| 1 25 26 package org.objectweb.jonas.web; 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.rmi.RemoteException ; 34 import java.util.ArrayList ; 35 import java.util.Enumeration ; 36 import java.util.HashSet ; 37 import java.util.Hashtable ; 38 import java.util.Iterator ; 39 import java.util.List ; 40 import java.util.Set ; 41 import java.util.StringTokenizer ; 42 import java.util.Vector ; 43 44 import javax.management.InstanceAlreadyExistsException ; 45 import javax.management.MBeanRegistrationException ; 46 import javax.management.MBeanServer ; 47 import javax.management.NotCompliantMBeanException ; 48 import javax.naming.Context ; 49 import javax.naming.LinkRef ; 50 import javax.naming.NamingException ; 51 import javax.naming.Reference ; 52 import javax.naming.StringRefAddr ; 53 54 import org.objectweb.jonas_lib.deployment.api.EjbLocalRefDesc; 55 import org.objectweb.jonas_lib.deployment.api.EjbRefDesc; 56 import org.objectweb.jonas_lib.deployment.api.EnvEntryDesc; 57 import org.objectweb.jonas_lib.deployment.api.MessageDestinationRefDesc; 58 import org.objectweb.jonas_lib.deployment.api.ResourceEnvRefDesc; 59 import org.objectweb.jonas_lib.deployment.api.ResourceRefDesc; 60 import org.objectweb.jonas_lib.loader.SimpleWebappClassLoader; 61 import org.objectweb.jonas_lib.loader.WebappClassLoader; 62 import org.objectweb.jonas_lib.naming.ContainerNaming; 63 import org.objectweb.jonas_lib.security.PermissionManagerException; 64 65 import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDesc; 66 import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDescException; 67 import org.objectweb.jonas_web.deployment.lib.wrapper.WebManagerWrapper; 68 69 import org.objectweb.jonas_ws.deployment.api.ServiceRefDesc; 70 71 import org.objectweb.jonas.common.JModule; 72 import org.objectweb.jonas.common.JProp; 73 import org.objectweb.jonas.common.Log; 74 import org.objectweb.jonas.ear.EarServiceImpl; 75 import org.objectweb.jonas.jmx.JmxService; 76 import org.objectweb.jonas.jmx.JonasObjectName; 77 import org.objectweb.jonas.naming.CompNamingContext; 78 import org.objectweb.jonas.naming.NamingManager; 79 import org.objectweb.jonas.server.LoaderManager; 80 import org.objectweb.jonas.service.AbsServiceImpl; 81 import org.objectweb.jonas.service.ServiceException; 82 import org.objectweb.jonas.service.ServiceManager; 83 import org.objectweb.jonas.web.lib.JarTools; 84 import org.objectweb.jonas.web.lib.PermissionManager; 85 import org.objectweb.jonas.ws.JServiceFactory; 86 import org.objectweb.jonas.ws.JServiceFactoryFinder; 87 import org.objectweb.jonas.ws.WebServicesService; 88 89 import org.objectweb.util.monolog.api.BasicLevel; 90 import org.objectweb.util.monolog.api.Logger; 91 92 100 public abstract class AbsJWebContainerServiceImpl extends AbsServiceImpl implements JWebContainerService, 101 AbsJWebContainerServiceImplMBean { 102 103 106 protected static final String JONAS_BASE = JProp.getJonasBase(); 107 108 111 protected static final String WEBAPPS_DIR = JONAS_BASE + File.separator + "webapps"; 112 113 116 protected static final String WORK_DIR = JProp.getWorkDir(); 117 118 121 protected static final String WORK_WEBAPPS_DIR = WORK_DIR + File.separator + "webapps"; 122 123 126 public static final String DESCRIPTORS = "jonas.service.web.descriptors"; 127 128 132 public static final String AUTOLOADDIR = "jonas.service.web.autoloaddir"; 133 134 137 public static final String PARSINGWITHVALIDATION = "jonas.service.web.parsingwithvalidation"; 138 139 142 private static final int WAR_EXTENSION_LENGTH = 4; 143 144 148 public static final String CLASS = "jonas.service.web.class"; 149 150 153 private static Logger logger = null; 154 155 158 private static String nameOfServer = null; 159 160 163 private ContainerNaming naming; 164 165 168 private Hashtable warLoaders = new Hashtable (); 169 170 173 private Hashtable warBindings = new Hashtable (); 174 175 178 private MBeanServer mbeanServer = null; 182 185 private Vector warNames = new Vector (); 186 187 190 private Vector warDeployed = new Vector (); 191 192 195 private List autoloadDirectories = new ArrayList (); 196 197 200 private String serverName = null; 201 202 205 private String serverVersion = null; 206 207 210 private WebServicesService wsService = null; 211 212 215 private ClassLoader appsClassLoader; 216 217 222 protected void doInit(Context ctx) throws ServiceException { 223 224 logger = Log.getLogger(Log.JONAS_WEB_PREFIX); 226 227 try { 229 LoaderManager lm = LoaderManager.getInstance(); 230 appsClassLoader = lm.getAppsLoader(); 231 } catch (Exception e) { 232 logger.log(BasicLevel.ERROR, "Cannot get the Applications ClassLoader from Web Container Service: " + e); 233 throw new ServiceException("Cannot get the Applications ClassLoader from Web Container Service", e); 234 } 235 236 ServiceManager sm = null; 237 try { 238 sm = ServiceManager.getInstance(); 239 } catch (Exception e) { 240 String err = "Cannot get ServiceManager instance."; 241 logger.log(BasicLevel.ERROR, err); 242 throw new ServiceException(err, e); 243 } 244 245 try { 247 mbeanServer = ((JmxService) sm.getJmxService()).getJmxServer(); 248 } catch (ServiceException e) { 249 mbeanServer = null; 251 } 252 253 try { 255 wsService = (WebServicesService) sm.getWebServicesService(); 256 } catch (ServiceException e) { 257 if (logger.isLoggable(BasicLevel.DEBUG)) { 258 logger.log(BasicLevel.DEBUG, "WebServices service not started"); 259 } 260 wsService = null; 262 } 263 264 String parsingMode = "false"; 266 try { 267 parsingMode = (String ) ctx.lookup(PARSINGWITHVALIDATION); 268 } catch (NamingException e) { 269 if (logger.isLoggable(BasicLevel.DEBUG)) { 270 logger.log(BasicLevel.DEBUG, "No value for parsingWithValidation"); 271 } 272 } 275 276 WebManagerWrapper.setParsingWithValidation("true".equalsIgnoreCase(parsingMode)); 277 if (logger.isLoggable(BasicLevel.DEBUG)) { 278 if ("false".equalsIgnoreCase(parsingMode)) { 279 logger.log(BasicLevel.DEBUG, "Web XML parsing without validation"); 280 } else { 281 logger.log(BasicLevel.DEBUG, "Web XML parsing with validation"); 282 } 283 } 284 285 String descsValue = null; 287 try { 288 descsValue = (String ) ctx.lookup(DESCRIPTORS); 289 } catch (NamingException e) { 290 if (logger.isLoggable(BasicLevel.DEBUG)) { 291 logger.log(BasicLevel.DEBUG, "No " + DESCRIPTORS); 292 } 293 } 294 if (descsValue != null) { 295 StringTokenizer st = new StringTokenizer (descsValue, ","); 296 while (st.hasMoreTokens()) { 297 String fileName = st.nextToken().trim(); 298 warNames.add(fileName); 299 } 300 } 301 String dirValue = null; 303 ArrayList autoDirs = new ArrayList (); 304 try { 305 dirValue = (String ) ctx.lookup(AUTOLOADDIR); 306 } catch (NamingException e) { 307 if (logger.isLoggable(BasicLevel.DEBUG)) { 308 logger.log(BasicLevel.DEBUG, "No " + AUTOLOADDIR); 309 } 310 } 311 if (dirValue != null) { 312 StringTokenizer st = new StringTokenizer (dirValue, ","); 313 while (st.hasMoreTokens()) { 314 String dirName = st.nextToken().trim(); 315 addWars(dirName); 316 autoDirs.add(dirName); 317 } 318 } 319 File oFile; 321 Iterator it = autoDirs.iterator(); 322 while (it.hasNext()) { 323 String dirName = (String ) it.next(); 324 try { 325 oFile = new File (WEBAPPS_DIR, dirName); 326 if (!oFile.exists()) { 327 oFile = new File (dirName); 328 } 329 if (oFile.exists()) { 330 autoloadDirectories.add(oFile.getCanonicalPath()); 331 } 332 } catch (Exception e) { 333 String err = "Error when trying to verify Webapps autoload directory : " + dirName; 334 logger.log(BasicLevel.ERROR, err + " " + e.getMessage()); 335 } 336 } 337 338 try { 340 naming = NamingManager.getInstance(); 341 } catch (NamingException e) { 342 throw new ServiceException("Error when getting the reference to the Naming manager"); 343 } 344 345 JProp jp = null; 346 try { 347 jp = JProp.getInstance(); 348 } catch (Exception e) { 349 String err = "Error when trying to get jonas name "; 350 logger.log(BasicLevel.ERROR, err + " " + e.getMessage()); 351 throw new ServiceException(err, e); 352 } 353 AbsJWebContainerServiceImpl.nameOfServer = jp.getValue("jonas.name", "jonas"); 354 355 } 356 357 361 protected void doStart() throws ServiceException { 362 for (Enumeration e = warNames.elements(); e.hasMoreElements();) { 364 String fileName = (String ) e.nextElement(); 365 366 URL warURL = checkWarFile(fileName); 367 368 Context contctx = null; 369 try { 370 contctx = new CompNamingContext(fileName); 371 contctx.rebind("warURL", warURL); 372 } catch (NamingException ne) { 375 String err = "Cannot start the WebContainerService"; 376 throw new ServiceException(err, ne); 377 } 378 try { 379 registerWar(contctx); 380 } catch (JWebContainerServiceException jwcse) { 381 String err = "Cannot deploy the file '" + warURL + "' : " + jwcse.getMessage(); 382 logger.log(BasicLevel.WARN, err); 383 } 384 } 385 386 try { 387 if (mbeanServer != null) { 390 mbeanServer.registerMBean(this, JonasObjectName.webContainerService()); 391 } 392 } catch (InstanceAlreadyExistsException iae) { 393 String err = "Cannot start the WebContainerService Already Exists"; 394 throw new ServiceException(err, iae); 395 } catch (MBeanRegistrationException mbre) { 396 throw new ServiceException("Cannot start the WebContainerService (MBean registration error)", mbre); 397 } catch (NotCompliantMBeanException ncmbe) { 398 throw new ServiceException("Cannot start the WebContainerService (MBean Not compliant error)", ncmbe); 399 } 400 } 401 402 406 protected void doStop() throws ServiceException { 407 408 for (int i = warDeployed.size() - 1; i >= 0; i--) { 411 War war = (War) warDeployed.elementAt(i); 412 URL warURL = war.getWarURL(); 413 String fileName = warURL.getFile(); 414 try { 415 if (!war.isInEarCase()) { 417 Context ctx = new CompNamingContext(fileName); 418 ctx.rebind("warURL", warURL); 419 ctx.rebind("isEarCase", new Boolean (false)); 420 unRegisterWar(ctx); 421 } 422 } catch (Exception e) { 423 String err = "Error when undeploying the war :" + fileName; 426 logger.log(BasicLevel.ERROR, err + e.getMessage()); 427 } 428 } 429 430 if (mbeanServer != null) { 431 try { 432 mbeanServer.unregisterMBean(JonasObjectName.webContainerService()); 434 } catch (Exception e) { 435 logger.log(BasicLevel.ERROR, "Cannot stop the WebContainerService: " + e); 436 } 437 } 438 if (logger.isLoggable(BasicLevel.DEBUG)) { 439 logger.log(BasicLevel.DEBUG, "WebContainerService stopped"); 440 } 441 } 442 443 451 protected abstract void doRegisterWar(Context ctx) throws JWebContainerServiceException; 452 453 459 protected abstract void doUnRegisterWar(Context ctx) throws JWebContainerServiceException; 460 461 469 protected URL getUnpackDir(URL warURL, String earAppName) throws JWebContainerServiceException { 470 471 String destDir = WORK_WEBAPPS_DIR + File.separator + nameOfServer + File.separator; 472 473 479 URL unpackedWarURL = null; 481 482 String fileName = warURL.getFile(); 483 484 if (new File (fileName).isFile()) { 486 if (earAppName != null) { 489 destDir += earAppName + File.separator; 490 } 491 492 String fTemp = new File (fileName).getName(); 493 destDir += fTemp.substring(0, fTemp.length() - WAR_EXTENSION_LENGTH); 494 495 JarTools.unpack(fileName, destDir); 497 } else { 498 destDir = fileName; 500 } 501 502 try { 503 unpackedWarURL = new File (destDir).toURL(); 504 } catch (MalformedURLException mue) { 505 throw new JWebContainerServiceException("Error", mue); 506 } 507 508 return unpackedWarURL; 509 510 } 511 512 523 public URLClassLoader getClassLoader(URL warURL, String earAppName, ClassLoader parentLoader) 524 throws JWebContainerServiceException { 525 526 URLClassLoader loaderForCls = null; 527 try { 528 WebLoaderHolder holder = (WebLoaderHolder) warLoaders.get(warURL); 529 if (holder != null) { 530 loaderForCls = holder.getJonasWebLoader(); 531 } 532 } catch (Exception e) { 533 throw new JWebContainerServiceException("Error when getting '" + warURL + "' in cache", e); 534 } 535 536 if (loaderForCls == null) { 537 539 URL unpackedWarURL = getUnpackDir(warURL, earAppName); 541 542 try { 543 if (parentLoader != null) { 544 loaderForCls = new WebappClassLoader(unpackedWarURL, parentLoader); 546 } else { 547 loaderForCls = new WebappClassLoader(unpackedWarURL, appsClassLoader); 549 } 550 } catch (IOException ioe) { 551 throw new JWebContainerServiceException( 552 "Cannot create WebAppClassLoader from '" + unpackedWarURL + "'", ioe); 553 } 554 555 try { 557 WebLoaderHolder holder = new WebLoaderHolder(loaderForCls, null); 558 warLoaders.put(warURL, holder); 559 } catch (Exception e) { 560 throw new JWebContainerServiceException("Error when adding '" + warURL + "' in cache", e); 561 } 562 } 563 564 return loaderForCls; 565 566 } 567 568 572 public ClassLoader getContextLinkedClassLoader(URL warURL) { 573 WebLoaderHolder holder = (WebLoaderHolder) warLoaders.get(warURL); 574 if (holder != null) { 575 return holder.getEnvWebLoader(); 576 } 577 return null; 578 } 579 580 588 private void registerWar(Context ctx) throws JWebContainerServiceException { 589 601 URL earURL = null; 604 String contextRoot = null; 605 String earAppName = null; 606 try { 607 earURL = (URL ) ctx.lookup("earURL"); 608 contextRoot = (String ) ctx.lookup("contextRoot"); 609 earAppName = EarServiceImpl.buildJ2eeApplicationName(earURL); 610 } catch (NamingException e) { 611 if (earURL != null || contextRoot != null) { 612 String err = "Error while getting parameter from context param :" + e.getMessage(); 613 logger.log(BasicLevel.ERROR, err); 614 throw new JWebContainerServiceException(err, e); 615 } } 617 618 URL warURL = null; 620 try { 621 warURL = (URL ) ctx.lookup("warURL"); 622 } catch (NamingException e) { 623 String err = "Error while getting parameter from context param :" + e.getMessage(); 624 logger.log(BasicLevel.ERROR, err); 625 throw new JWebContainerServiceException(err, e); 626 } 627 628 File warFile = new File (warURL.getFile()); 630 if (!warFile.exists()) { 631 String err = "registerWar: '" + warFile.getPath() + "' not found"; 632 logger.log(BasicLevel.ERROR, err); 633 throw new JWebContainerServiceException(err); 634 } 635 636 War war = getWar(warURL); 638 if (war != null) { 639 String err = "Cannot deploy war '" + warURL.getFile() + "' is already deployed." 641 + " You must undeploy the war before a new deployment."; 642 throw new JWebContainerServiceException(err); 643 } 644 645 URLClassLoader parentLoader = null; 646 URLClassLoader earClassLoader = null; 647 try { 648 parentLoader = (URLClassLoader ) ctx.lookup("parentClassLoader"); 649 earClassLoader = (URLClassLoader ) ctx.lookup("earClassLoader"); 650 } catch (NamingException ne) { 651 if (logger.isLoggable(BasicLevel.DEBUG)) { 652 logger.log(BasicLevel.DEBUG, "Not an ear case"); 653 } 654 } 656 657 URLClassLoader loaderForCls = getClassLoader(warURL, earAppName, parentLoader); 659 660 URL unpackedWarURL = getUnpackDir(warURL, earAppName); 662 663 if (wsService != null && earClassLoader == null) { 666 try { 667 CompNamingContext contctx = null; 668 try { 669 contctx = new CompNamingContext(unpackedWarURL.getFile()); 670 contctx.rebind("unpackDir", unpackedWarURL.toExternalForm()); 671 contctx.rebind("jarUrls", new URL [0]); 672 contctx.rebind("warUrls", new URL [] {warURL}); 673 if (parentLoader != null) { 674 contctx.rebind("ejbClassLoader", parentLoader); 675 } 676 } catch (NamingException e) { 677 String err = "Can not bind params for the WebServices service, " 678 + "Can't deploy Web Services Endpoint"; 679 throw new JWebContainerServiceException(err, e); 680 } 681 wsService.deployWebServices(contctx); 682 } catch (ServiceException se) { 683 String err = "Error during the deployment of the WebServices of the War file '" + warURL + "'"; 684 logger.log(BasicLevel.ERROR, err + " : " + se.getMessage()); 685 throw new JWebContainerServiceException(err, se); 686 } 687 } 688 689 WebContainerDeploymentDesc webDD = null; 691 try { 692 webDD = WebManagerWrapper.getDeploymentDesc(warURL, loaderForCls, earClassLoader); 693 } catch (WebContainerDeploymentDescException e) { 694 String err = "Cannot read the deployment descriptors '" + warURL.getFile() + "'"; 695 logger.log(BasicLevel.ERROR, err + ": " + e); 696 e.printStackTrace(System.err); 697 throw new JWebContainerServiceException(err, e); 698 } 699 700 URLClassLoader webClassLoader = null; 702 try { 703 if (logger.isLoggable(BasicLevel.DEBUG)) { 704 logger.log(BasicLevel.DEBUG, "Populating environment of the file " + warURL.getFile()); 705 } 706 Context ctxParam = new CompNamingContext(unpackedWarURL.getFile()); 707 ctxParam.rebind("DeploymentDesc", webDD); 708 ctxParam.rebind("warName", unpackedWarURL.getFile()); 709 if (parentLoader == null) { 710 webClassLoader = new SimpleWebappClassLoader(unpackedWarURL, appsClassLoader); 711 } else { 712 &nbs
|