| 1 25 26 package org.objectweb.jonas.container; 27 28 import java.io.File ; 29 import java.io.IOException ; 30 import java.net.MalformedURLException ; 31 import java.net.URL ; 32 import java.net.URLClassLoader ; 33 import java.util.ArrayList ; 34 import java.util.Enumeration ; 35 import java.util.HashMap ; 36 import java.util.HashSet ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 import java.util.Map ; 40 import java.util.Properties ; 41 import java.util.Set ; 42 import java.util.StringTokenizer ; 43 import java.util.Vector ; 44 import java.util.jar.Attributes ; 45 import java.util.jar.JarFile ; 46 import java.util.jar.Manifest ; 47 48 import javax.management.MBeanException ; 49 import javax.management.MBeanServer ; 50 import javax.management.ObjectName ; 51 import javax.management.OperationsException ; 52 import javax.management.modelmbean.ModelMBean ; 53 import javax.naming.Context ; 54 import javax.naming.InitialContext ; 55 import javax.naming.NamingException ; 56 57 import org.apache.commons.modeler.ManagedBean; 58 import org.apache.commons.modeler.Registry; 59 60 import org.objectweb.transaction.jta.TransactionManager; 61 62 import org.objectweb.carol.util.configuration.ConfigurationRepository; 63 import org.objectweb.carol.util.configuration.ProtocolConfiguration; 64 65 import org.objectweb.jonas_ejb.container.BeanFactory; 66 import org.objectweb.jonas_ejb.container.Container; 67 import org.objectweb.jonas_ejb.container.JContainer; 68 import org.objectweb.jonas_ejb.container.JEntityFactory; 69 import org.objectweb.jonas_ejb.container.JMdbEndpointFactory; 70 import org.objectweb.jonas_ejb.container.JMdbFactory; 71 import org.objectweb.jonas_ejb.container.JSessionFactory; 72 import org.objectweb.jonas_ejb.container.JStatelessFactory; 73 import org.objectweb.jonas_ejb.container.PermissionManager; 74 import org.objectweb.jonas_ejb.deployment.api.BeanDesc; 75 import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc; 76 import org.objectweb.jonas_ejb.deployment.api.EntityBmpDesc; 77 import org.objectweb.jonas_ejb.deployment.api.EntityCmpDesc; 78 import org.objectweb.jonas_ejb.deployment.api.SessionStatefulDesc; 79 import org.objectweb.jonas_ejb.deployment.api.SessionStatelessDesc; 80 import org.objectweb.jonas_ejb.deployment.lib.wrapper.EjbManagerWrapper; 81 82 import org.objectweb.jonas_lib.JWorkManager; 83 import org.objectweb.jonas_lib.deployment.api.DeploymentDescException; 84 import org.objectweb.jonas_lib.deployment.work.CleanerException; 85 import org.objectweb.jonas_lib.deployment.work.DeployerLog; 86 import org.objectweb.jonas_lib.deployment.work.DeployerLogException; 87 import org.objectweb.jonas_lib.deployment.work.FileManager; 88 import org.objectweb.jonas_lib.deployment.work.JarCleanTask; 89 import org.objectweb.jonas_lib.deployment.work.WorkCleaner; 90 import org.objectweb.jonas_lib.files.FileUtils; 91 import org.objectweb.jonas_lib.loader.EjbJarClassLoader; 92 import org.objectweb.jonas_lib.version.Version; 93 94 import org.objectweb.jonas_jms.api.JmsManager; 95 96 import org.objectweb.jonas.common.JModule; 97 import org.objectweb.jonas.common.JProp; 98 import org.objectweb.jonas.common.Log; 99 import org.objectweb.jonas.ear.EarServiceImpl; 100 import org.objectweb.jonas.jms.JmsService; 101 import org.objectweb.jonas.jmx.J2eeObjectName; 102 import org.objectweb.jonas.jmx.JmxService; 103 import org.objectweb.jonas.jmx.JonasObjectName; 104 import org.objectweb.jonas.jtm.TransactionService; 105 import org.objectweb.jonas.management.JonasMBeanTools; 106 import org.objectweb.jonas.naming.CompNamingContext; 107 import org.objectweb.jonas.naming.NamingManager; 108 import org.objectweb.jonas.security.SecurityService; 109 import org.objectweb.jonas.server.LoaderManager; 110 import org.objectweb.jonas.server.WorkManagerMBean; 111 import org.objectweb.jonas.service.AbsServiceImpl; 112 import org.objectweb.jonas.service.ServiceException; 113 import org.objectweb.jonas.service.ServiceManager; 114 115 import org.objectweb.util.monolog.api.BasicLevel; 116 import org.objectweb.util.monolog.api.Logger; 117 118 131 public class EJBServiceImpl extends AbsServiceImpl implements EJBService, EJBServiceImplMBean { 132 133 134 private static Logger servlog = null; 135 136 137 private static Logger loaderlog = null; 138 139 143 private TransactionManager tm = null; 144 145 146 private JmsManager jms = null; 147 148 149 private MBeanServer mbeanServer = null; 150 151 152 private SecurityService securityService = null; 153 154 157 private static WorkCleaner workCleaner = null; 158 159 private Registry oRegistry = null; 160 161 164 private Vector ejbNames = new Vector (); 165 166 167 private Vector containers = new Vector (); 168 169 170 public static final String MINWORKTHREADS = "jonas.service.ejb.minworkthreads"; 171 private static final int DEFAULT_MINWORKTHREADS = 3; 172 public static final String MAXWORKTHREADS = "jonas.service.ejb.maxworkthreads "; 173 private static final int DEFAULT_MAXWORKTHREADS = 80; 174 public static final String THREADWAITTIMEOUT = "jonas.service.ejb.threadwaittimeout"; 175 private static final int DEFAULT_THREADWAITTIMEOUT = 60; 176 private JWorkManager workManager; 177 178 181 protected static final String JONAS_BASE = JProp.getJonasBase(); 182 183 186 protected static final String EJBJARS_DIR = JONAS_BASE + File.separator + "ejbjars"; 187 188 191 private ArrayList autoloadDirectories = new ArrayList (); 192 193 194 public static final String JONAS_EJB = "jonas.service.ejb"; 195 196 197 public static final String AUTOLOADDIR = JONAS_EJB + ".autoloaddir"; 198 199 200 public static final String PARSINGWITHVALIDATION = JONAS_EJB + ".parsingwithvalidation"; 201 202 203 public static final String DESCRIPTORS = JONAS_EJB + ".descriptors"; 204 205 206 public static final String CLASS = JONAS_EJB + ".class"; 207 208 209 public static final String BMP = "Bean-Managed"; 210 211 212 public static final String CMP = "Container-Managed"; 213 214 215 private ClassLoader appsClassLoader = null; 216 217 220 private static final String WORK_DIR = JProp.getWorkDir(); 221 222 225 private static final String WORK_EJBJARS_DIR = WORK_DIR + File.separator + "ejbjars"; 226 227 230 private static String ejbjarsDir = null; 231 232 236 private DeployerLog jarDeployerLog = null; 237 238 242 246 public void doInit(Context ctx) throws ServiceException { 247 servlog = Log.getLogger(Log.JONAS_SERVER_PREFIX); 248 loaderlog = Log.getLogger(Log.JONAS_LOADER_PREFIX); 249 250 if (servlog.isLoggable(BasicLevel.DEBUG)) { 251 servlog.log(BasicLevel.DEBUG, ""); 252 } 253 254 try { 256 LoaderManager lm = LoaderManager.getInstance(); 257 appsClassLoader = lm.getAppsLoader(); 258 } catch (Exception e) { 259 servlog.log(BasicLevel.ERROR, "Cannot get the Applications ClassLoader from EJB Container Service"); 260 throw new ServiceException("Cannot get the Applications ClassLoader from EJB Container Service", e); 261 } 262 263 ServiceManager serviceManager = null; 264 try { 265 serviceManager = ServiceManager.getInstance(); 266 } catch (Exception e) { 267 servlog.log(BasicLevel.ERROR, "Cannot initialize the EJB Container Service"); 268 throw new ServiceException("Cannot initialize the EJB Container Service", e); 269 } 270 try { 272 TransactionService jtmService = (TransactionService) serviceManager.getTransactionService(); 274 tm = jtmService.getTransactionManager(); 275 } catch (ServiceException e) { 276 servlog.log(BasicLevel.ERROR, "Cannot initialize the EJB Container Service"); 277 throw new ServiceException("Cannot initialize the EJB Container Service", e); 278 } 279 280 try { 281 securityService = (SecurityService) serviceManager.getSecurityService(); 283 } catch (ServiceException se) { 284 securityService = null; 286 } 287 288 try { 289 JmsService jmsService = (JmsService) serviceManager.getJmsService(); 291 jms = jmsService.getJmsManager(); 292 } catch (ServiceException e) { 293 jms = null; 295 } 296 297 try { 298 JmxService jmxService = (JmxService) serviceManager.getJmxService(); 300 mbeanServer = jmxService.getJmxServer(); 301 } catch (ServiceException e) { 302 mbeanServer = null; 304 } 305 oRegistry = JonasMBeanTools.getRegistry(); 306 307 String parsingMode; 309 try { 310 parsingMode = (String ) ctx.lookup(PARSINGWITHVALIDATION); 311 } catch (NamingException e) { 312 parsingMode = "false"; 315 } 316 if ("false".equalsIgnoreCase(parsingMode)) { 317 EjbManagerWrapper.setParsingWithValidation(false); 318 if (servlog.isLoggable(BasicLevel.DEBUG)) { 319 servlog.log(BasicLevel.DEBUG, "XML parsing without validation"); 320 } 321 } else { 322 if (servlog.isLoggable(BasicLevel.DEBUG)) { 323 servlog.log(BasicLevel.DEBUG, "XML parsing with validation"); 324 } 325 } 326 327 String descsValue; 329 try { 330 descsValue = (String ) ctx.lookup(DESCRIPTORS); 331 } catch (NamingException e) { 332 descsValue = null; 335 } 336 if (descsValue != null) { 337 StringTokenizer st = new StringTokenizer (descsValue, ","); 338 while (st.hasMoreTokens()) { 339 String fileName = st.nextToken().trim(); 340 ejbNames.add(fileName); 341 } 342 } 343 344 String dirValue; 346 ArrayList autoDirs = new ArrayList (); 347 try { 348 dirValue = (String ) ctx.lookup(AUTOLOADDIR); 349 } catch (NamingException e) { 350 dirValue = null; 353 } 354 if (dirValue != null) { 355 StringTokenizer st = new StringTokenizer (dirValue, ","); 356 while (st.hasMoreTokens()) { 357 String dirName = st.nextToken().trim(); 358 addEjbjars(dirName); 359 autoDirs.add(dirName); 360 } 361 } 362 File oFile; 364 for (int i = 0; i < autoDirs.size(); i++) { 365 try { 366 oFile = new File (EJBJARS_DIR, autoDirs.get(i).toString()); 367 if (oFile.exists()) { 368 autoloadDirectories.add(oFile.getCanonicalPath()); 369 } else { 370 oFile = new File (autoDirs.get(i).toString()); 371 } 372 } catch (Exception e) { 373 String err = "Error when trying to verify Ejbjar autoload directory : " + autoDirs.get(i); 374 servlog.log(BasicLevel.ERROR, err, e); 375 } 376 } 377 378 int minworkthreads = DEFAULT_MINWORKTHREADS; 380 try { 381 String plz = (String ) ctx.lookup(MINWORKTHREADS); 382 minworkthreads = (new Integer (plz)).intValue(); 383 } catch (NamingException e) { 384 } 386 int maxworkthreads = DEFAULT_MAXWORKTHREADS; 387 try { 388 String mxplz = (String ) ctx.lookup(MAXWORKTHREADS); 389 maxworkthreads = (new Integer (mxplz)).intValue(); 390 } catch (NamingException e) { 391 } 393 int threadwaittimeout = DEFAULT_THREADWAITTIMEOUT; 394 try { 395 String tto = (String ) ctx.lookup(THREADWAITTIMEOUT); 396 threadwaittimeout = (new Integer (tto)).intValue(); 397 } catch (NamingException e) { 398 } 400 workManager = new JWorkManager(minworkthreads, maxworkthreads, tm, threadwaittimeout); 401 402 ObjectName mbn; 404 try { 405 mbn = JonasObjectName.workManager(); 406 ManagedBean oManaged = oRegistry.findManagedBean("WorkManager"); 407 ModelMBean oMBean = oManaged.createMBean(new WorkManagerMBean(workManager)); 408 mbeanServer.registerMBean(oMBean, mbn); 409 } catch (Exception e) { 410 servlog.log(BasicLevel.ERROR, "Cannot create MBean", e); 411 } 412 413 if (servlog.isLoggable(BasicLevel.DEBUG)) { 414 servlog.log(BasicLevel.DEBUG, "EJB Container Service initialized"); 415 } 416 } 417 418 public JWorkManager getWorkManager() { 419 return workManager; 420 } 421 422 425 public void doStart() throws ServiceException { 426 427 ejbjarsDir = WORK_EJBJARS_DIR + File.separator + getJonasServerName(); 428 429 URL ejbjarsUrl = null; 430 try { 431 ejbjarsUrl = new File (ejbjarsDir).toURL(); 432 } catch (MalformedURLException mue) { 433 throw new ServiceException("Error when trying to get the URL of the jonasroot/apps directory", mue); 434 } 435 436 File fLog = new File (ejbjarsUrl.getFile() + File.separator + getJonasServerName() + ".log"); 437 if (!fLog.exists()) { 438 try { 439 fLog.getParentFile().mkdirs(); 441 fLog.createNewFile(); 442 } catch (IOException e) { 443 throw new ServiceException("cannot create the log file" + fLog, e); 444 } 445 } 446 447 try { 449 jarDeployerLog = new DeployerLog(fLog); 450 } catch (DeployerLogException e) { 451 throw new ServiceException("Can not get an EarDeployerLog", e); 452 } 453 454 JarCleanTask jarCleanTask = new JarCleanTask(jarDeployerLog); 456 457 workCleaner = WorkCleaner.getInstance(); 459 460 try { 462 workCleaner.registerTask(jarCleanTask); 463 } catch (CleanerException ce) { 464 throw new ServiceException("Cannot register the JAR clean task", ce); 465 466 } 467 468 workCleaner.executeTasks(); 470 471 String fileName = null; 474 Context contctx = null; 475 for (int i = 0; i < ejbNames.size(); i++) { 476 fileName = (String ) ejbNames.elementAt(i); 477 try { 478 contctx = new CompNamingContext(fileName); 479 contctx.rebind("filename", fileName); 480 } catch (NamingException ne) { 481 servlog.log(BasicLevel.WARN, "Cannot create container for " + fileName 482 + " because of a NamingException : " + ne.toString()); 483 } 484 485 try { 486 createContainer(contctx); 487 } catch (Exception e) { 488 servlog.log(BasicLevel.WARN, "Cannot create container for " + fileName, e); 489 try { 491 contctx.close(); 492 } catch (NamingException nne) { 493 if (servlog.isLoggable(BasicLevel.DEBUG)) { 494 servlog.log(BasicLevel.DEBUG, "Cannot close deploy context for " + fileName, nne); 495 } 496 } 497 } 498 } 499 500 if (mbeanServer != null) { 502 try { 503 mbeanServer.registerMBean(this, JonasObjectName.ejbService()); 504 } catch (MBeanException mbe) { 505 servlog.log(BasicLevel.WARN, "Cannot register the EJB Container Service in the MBean Server."); 507 servlog.log(BasicLevel.WARN, "Regstration failure cause : " + mbe.getTargetException().toString()); 508 } catch (OperationsException me) { 509 servlog.log(BasicLevel.WARN, "Cannot register the EJB Container Service in the MBean Server.", me); 512 } 513 } 514 } 515 516 520 public void doStop() { 521 522 Enumeration lc = containers.elements(); 523 while (lc.hasMoreElements()) { 524 Container cont = (Container) lc.nextElement(); 525 removeContainer(cont); 526 } 527 if (mbeanServer != null) { 528 try { 529 mbeanServer.unregisterMBean(JonasObjectName.ejbService()); 531 } catch (Exception e) { 532 servlog.log(BasicLevel.ERROR, "Cannot stop the EJB Container Service", e); 533 } 534 } 535 536 if (servlog.isLoggable(BasicLevel.DEBUG)) { 537 servlog.log(BasicLevel.DEBUG, "EJB Container Service stopped"); 538 } 539 } 540 541 545 552 public String createContainer(Context ctx) throws Exception { 553 if (servlog.isLoggable(BasicLevel.DEBUG)) { 554 servlog.log(BasicLevel.DEBUG, ""); 555 } 556 557 String fileName = (String ) ctx.lookup("filename"); 559 File f = new File (fileName).getCanonicalFile(); 560 561 boolean isEjbJar = fileName.toLowerCase().endsWith(".jar"); 562 563 try { 567 if (!f.exists() && isEjbJar) { 568 String ejbjarFileName = EJBJARS_DIR + File.separator + fileName; 569 f = new File (ejbjarFileName).getCanonicalFile(); 570 if (!f.exists()) { 571 servlog.log(BasicLevel.ERROR, "createContainer: " + fileName + " not found"); 572 throw new NamingException (fileName + " not found"); 573 } 574 } 575 } catch (IOException e) { 576 String err = "Invalid ejbjar file name '" + fileName; 577 servlog.log(BasicLevel.ERROR, err); 578 throw new Exception (err, e); 579 } 580 boolean isEjbJarFile = isEjbJar && f.isFile(); 581 boolean isEjbJarXml = fileName.toLowerCase().endsWith(".xml") && f.isFile(); 582 583 try { 586 fileName = f.toURL().getPath(); 587 } catch (MalformedURLException e) { 588 servlog.log(BasicLevel.ERROR, "Invalid ejb-jar file name '" + fileName + "'", e); 589 } 590 591 if (f.isFile()) { 592 if (!isEjbJar && !isEjbJarXml) { 593 throw new ServiceException("The ejbjar to deploy is not a jar file nor an xml file"); 594 } 595 } 596 597 if (getContainer(fileName) != null) { 599 servlog.log(BasicLevel.ERROR, "createContainer: " + fileName + " already exists"); 600 throw new Exception ("Container already exists"); 601 } 602 603 boolean isInEar = true; 607 try { 608 ctx.lookup("earClassLoader"); 609 } catch (NamingException ne) { 610 isInEar = false; 611 } 612 613 if (!isInEar) { 616 checkGenIC(fileName); 617 } 618 619 620 String wkFileName = null; 621 622 if (!isInEar && isEjbJarFile) { 623 wkFileName = ejbjarsDir + File.separator + FileManager.fileToTimeStampDir(f.toURL(), ".jar"); 625 626 if (servlog.isLoggable(BasicLevel.DEBUG)) { 627 servlog.log(BasicLevel.DEBUG, "filename=" + fileName); 628 servlog.log(BasicLevel.DEBUG, "wkFilename=" + wkFileName); 629 } 630 631 FileUtils.copyFile(fileName, wkFileName); 633 634 try { 636 jarDeployerLog.addEntry(f, new File (wkFileName)); 637 } catch (DeployerLogException e) { 638 String err = "Error while adding the " + fileName + " entry in the log file"; 639 servlog.log(BasicLevel.ERROR, err + " : " + e.getMessage()); 640 throw new Exception (err, e); 641 } 642 643 if (servlog.isLoggable(BasicLevel.DEBUG)) { 644 servlog.log(BasicLevel.DEBUG, "Create wk file :" + wkFileName); 645 } 646 647 } else { 648 wkFileName = fileName; 650 if (servlog.isLoggable(BasicLevel.DEBUG)) { 651 servlog.log(BasicLevel.DEBUG, "No needs wk file :" + wkFileName); 652 } 653 } 654 655 URL [] url = null; 657 try { 658 url = new URL [1]; 659 url[0] = (new File (wkFileName)).toURL(); 660 } catch (MalformedURLException e) { 661 servlog.log(BasicLevel.ERROR, "Invalid ejb-jar file name '" + wkFileName + "'", e); 662 } 663 664 URLClassLoader ejbClassLoader = null; 666 URLClassLoader earClassLoader = null; 667 try { 668 earClassLoader = (URLClassLoader ) ctx.lookup("earClassLoader"); 669 ejbClassLoader = (URLClassLoader ) ctx.lookup("ejbClassLoader"); 670 if (loaderlog.isLoggable(BasicLevel.DEBUG)) { 671 loaderlog.log(BasicLevel.DEBUG, "earClassLoader=" + earClassLoader); 672 } 673 } catch (NamingException ne) { 674 if (isEjbJar) { 676 ejbClassLoader = new EjbJarClassLoader(url, appsClassLoader); 677 } else { 678 ejbClassLoader = (URLClassLoader ) appsClassLoader; 679 } 680 if (loaderlog.isLoggable(BasicLevel.DEBUG)) { 681 loaderlog.log(BasicLevel.DEBUG, "parent Loader=" + appsClassLoader); 682 } 683 } 684 if (loaderlog.isLoggable(BasicLevel.DEBUG)) { 685 loaderlog.log(BasicLevel.DEBUG, "ejbClassLoader=" + ejbClassLoader); 686 } 687 688 DeploymentDesc dd = null; 690 try { 691 dd = EjbManagerWrapper.getDeploymentDesc(url[0], ejbClassLoader, earClassLoader); 693 } catch (DeploymentDescException e) { 694 String err = "Cannot read the deployment descriptors '" + fileName + "'"; 695 servlog.log(BasicLevel.ERROR, err); 696 throw new ServiceException(err, e); 697 } 698 699 String cname = buildEJBModuleName(fileName); 701 if (cname == null) { 702 cname = "EJB container "; 704 if (dd.getDisplayName() != null) { 705 cname += dd.getDisplayName(); 706 } 707 } 708 709 JContainer cont = new JContainer(cname, fileName, wkFileName, ejbClassLoader); 711 cont.setContainerNaming(NamingManager.getInstance()); 712 cont.setTransactionManager(tm); 713 cont.setPrincipalFactory(new PrincipalFactoryImpl()); 714 cont.setJmsManager(jms); 715 716 String earFileName; 719 try { 720 earFileName = (String ) ctx.lookup("earFileName"); 721  
|