00001
00027 package org.objectweb.jonas.web;
00028
00029 import java.io.File;
00030 import java.io.IOException;
00031 import java.net.MalformedURLException;
00032 import java.net.URL;
00033 import java.net.URLClassLoader;
00034 import java.rmi.RemoteException;
00035 import java.util.ArrayList;
00036 import java.util.Enumeration;
00037 import java.util.HashSet;
00038 import java.util.Hashtable;
00039 import java.util.Iterator;
00040 import java.util.List;
00041 import java.util.Set;
00042 import java.util.StringTokenizer;
00043 import java.util.Vector;
00044
00045 import javax.management.InstanceAlreadyExistsException;
00046 import javax.management.MBeanRegistrationException;
00047 import javax.management.MBeanServer;
00048 import javax.management.NotCompliantMBeanException;
00049 import javax.naming.Context;
00050 import javax.naming.LinkRef;
00051 import javax.naming.NamingException;
00052 import javax.naming.Reference;
00053 import javax.naming.StringRefAddr;
00054
00055 import org.objectweb.jonas.common.JModule;
00056 import org.objectweb.jonas.common.JProp;
00057 import org.objectweb.jonas.common.Log;
00058 import org.objectweb.jonas.server.LoaderManager;
00059 import org.objectweb.jonas.ear.EarServiceImpl;
00060 import org.objectweb.jonas.jmx.JmxService;
00061 import org.objectweb.jonas.jmx.JonasObjectName;
00062 import org.objectweb.jonas.naming.CompNamingContext;
00063 import org.objectweb.jonas.naming.NamingManager;
00064 import org.objectweb.jonas.service.AbsServiceImpl;
00065 import org.objectweb.jonas.service.ServiceException;
00066 import org.objectweb.jonas.service.ServiceManager;
00067 import org.objectweb.jonas.web.lib.JarTools;
00068 import org.objectweb.jonas.web.lib.PermissionManager;
00069 import org.objectweb.jonas.ws.AbsWebServicesServiceImpl;
00070 import org.objectweb.jonas.ws.JServiceFactory;
00071 import org.objectweb.jonas.ws.JServiceFactoryFinder;
00072 import org.objectweb.jonas.ws.WebServicesService;
00073 import org.objectweb.jonas_lib.deployment.api.EjbLocalRefDesc;
00074 import org.objectweb.jonas_lib.deployment.api.EjbRefDesc;
00075 import org.objectweb.jonas_lib.deployment.api.EnvEntryDesc;
00076 import org.objectweb.jonas_lib.deployment.api.MessageDestinationRefDesc;
00077 import org.objectweb.jonas_lib.deployment.api.ResourceEnvRefDesc;
00078 import org.objectweb.jonas_lib.deployment.api.ResourceRefDesc;
00079 import org.objectweb.jonas_lib.loader.SimpleWebappClassLoader;
00080 import org.objectweb.jonas_lib.loader.WebappClassLoader;
00081 import org.objectweb.jonas_lib.naming.ContainerNaming;
00082 import org.objectweb.jonas_lib.security.PermissionManagerException;
00083 import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDesc;
00084 import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDescException;
00085 import org.objectweb.jonas_web.deployment.lib.wrapper.WebManagerWrapper;
00086 import org.objectweb.jonas_ws.deployment.api.ServiceRefDesc;
00087 import org.objectweb.util.monolog.api.BasicLevel;
00088 import org.objectweb.util.monolog.api.Logger;
00089
00098 public abstract class AbsJWebContainerServiceImpl extends AbsServiceImpl implements JWebContainerService,
00099 AbsJWebContainerServiceImplMBean {
00100
00104 protected static final String JONAS_BASE = JProp.getJonasBase();
00105
00109 protected static final String WEBAPPS_DIR = JONAS_BASE + File.separator + "webapps";
00110
00114 protected static final String WORK_DIR = JProp.getWorkDir();
00115
00119 protected static final String WORK_WEBAPPS_DIR = WORK_DIR + File.separator + "webapps";
00120
00124 public static final String DESCRIPTORS = "jonas.service.web.descriptors";
00125
00130 public static final String AUTOLOADDIR = "jonas.service.web.autoloaddir";
00131
00135 public static final String PARSINGWITHVALIDATION = "jonas.service.web.parsingwithvalidation";
00136
00140 private static final int WAR_EXTENSION_LENGTH = 4;
00141
00146 public static final String CLASS = "jonas.service.web.class";
00147
00151 private static Logger logger = null;
00152
00156 private static String nameOfServer = null;
00157
00161 private ContainerNaming naming;
00162
00166 private Hashtable warLoaders = new Hashtable();
00167
00171 private Hashtable warBindings = new Hashtable();
00172
00176 private MBeanServer mbeanServer = null;
00177
00178
00179
00183 private Vector warNames = new Vector();
00184
00188 private Vector warDeployed = new Vector();
00189
00193 private ArrayList autoloadDirectories = new ArrayList();
00194
00198 private String serverName = null;
00199
00203 private String serverVersion = null;
00204
00208 private WebServicesService wsService = null;
00209
00213 private ClassLoader appsClassLoader;
00214
00220 protected void doInit(Context ctx) throws ServiceException {
00221
00222
00223 logger = Log.getLogger(Log.JONAS_WEB_PREFIX);
00224
00225
00226 try {
00227 LoaderManager lm = LoaderManager.getInstance();
00228 appsClassLoader = lm.getAppsLoader();
00229 } catch (Exception e) {
00230 logger.log(BasicLevel.ERROR, "Cannot get the Applications ClassLoader from Web Container Service: " + e);
00231 throw new ServiceException("Cannot get the Applications ClassLoader from Web Container Service", e);
00232 }
00233
00234 ServiceManager sm = null;
00235 try {
00236 sm = ServiceManager.getInstance();
00237 } catch (Exception e) {
00238 String err = "Cannot get ServiceManager instance.";
00239 logger.log(BasicLevel.ERROR, err);
00240 throw new ServiceException(err, e);
00241 }
00242
00243
00244 try {
00245 mbeanServer = ((JmxService) sm.getJmxService()).getJmxServer();
00246 } catch (ServiceException e) {
00247
00248 mbeanServer = null;
00249 }
00250
00251
00252 try {
00253 wsService = (WebServicesService) sm.getWebServicesService();
00254 } catch (ServiceException e) {
00255 logger.log(BasicLevel.DEBUG, "WebServices service not started");
00256
00257 wsService = null;
00258 }
00259
00260
00261 String parsingMode = "false";
00262 try {
00263 parsingMode = (String) ctx.lookup(PARSINGWITHVALIDATION);
00264 } catch (NamingException e) {
00265 logger.log(BasicLevel.DEBUG, "No value for parsingWithValidation");
00266
00267
00268 }
00269
00270 WebManagerWrapper.setParsingWithValidation("true".equalsIgnoreCase(parsingMode));
00271 if ("false".equalsIgnoreCase(parsingMode)) {
00272 logger.log(BasicLevel.DEBUG, "Web XML parsing without validation");
00273 } else {
00274
00275 logger.log(BasicLevel.DEBUG, "Web XML parsing with validation");
00276 }
00277
00278
00279 String descsValue = null;
00280 try {
00281 descsValue = (String) ctx.lookup(DESCRIPTORS);
00282 } catch (NamingException e) {
00283 logger.log(BasicLevel.DEBUG, "No " + DESCRIPTORS);
00284 }
00285 if (descsValue != null) {
00286 StringTokenizer st = new StringTokenizer(descsValue, ",");
00287 while (st.hasMoreTokens()) {
00288 String fileName = st.nextToken().trim();
00289 warNames.add(fileName);
00290 }
00291 }
00292
00293 String dirValue = null;
00294 ArrayList autoDirs = new ArrayList();
00295 try {
00296 dirValue = (String) ctx.lookup(AUTOLOADDIR);
00297 } catch (NamingException e) {
00298 logger.log(BasicLevel.DEBUG, "No " + AUTOLOADDIR);
00299 }
00300 if (dirValue != null) {
00301 StringTokenizer st = new StringTokenizer(dirValue, ",");
00302 while (st.hasMoreTokens()) {
00303 String dirName = st.nextToken().trim();
00304 addWars(dirName);
00305 autoDirs.add(dirName);
00306 }
00307 }
00308
00309 File oFile;
00310 Iterator it = autoDirs.iterator();
00311 while (it.hasNext()) {
00312 String dirName = (String) it.next();
00313 try {
00314 oFile = new File(WEBAPPS_DIR, dirName);
00315 if (!oFile.exists()) {
00316 oFile = new File(dirName);
00317 }
00318 if (oFile.exists()) {
00319 autoloadDirectories.add(oFile.getCanonicalPath());
00320 }
00321 } catch (Exception e) {
00322 String err = "Error when trying to verify Webapps autoload directory : " + dirName;
00323 logger.log(BasicLevel.ERROR, err + " " + e.getMessage());
00324 }
00325 }
00326
00327
00328 try {
00329 naming = NamingManager.getInstance();
00330 } catch (NamingException e) {
00331 throw new ServiceException("Error when getting the reference to the Naming manager");
00332 }
00333
00334 JProp jp = null;
00335 try {
00336 jp = JProp.getInstance();
00337 } catch (Exception e) {
00338 String err = "Error when trying to get jonas name ";
00339 logger.log(BasicLevel.ERROR, err + " " + e.getMessage());
00340 throw new ServiceException(err, e);
00341 }
00342 AbsJWebContainerServiceImpl.nameOfServer = jp.getValue("jonas.name", "jonas");
00343
00344 }
00345
00350 protected void doStart() throws ServiceException {
00351
00352 for (Enumeration e = warNames.elements(); e.hasMoreElements();) {
00353 String fileName = (String) e.nextElement();
00354
00355 URL warURL = checkWarFile(fileName);
00356
00357 Context contctx = null;
00358 try {
00359 contctx = new CompNamingContext(fileName);
00360 contctx.rebind("warURL", warURL);
00361
00362
00363 } catch (NamingException ne) {
00364 String err = "Cannot start the WebContainerService";
00365 throw new ServiceException(err, ne);
00366 }
00367 try {
00368 registerWar(contctx);
00369 } catch (JWebContainerServiceException jwcse) {
00370 String err = "Cannot deploy the file '" + warURL + "' : " + jwcse.getMessage();
00371 logger.log(BasicLevel.WARN, err);
00372 }
00373 }
00374
00375 try {
00376
00377
00378 if (mbeanServer != null) {
00379 mbeanServer.registerMBean(this, JonasObjectName.webContainerService());
00380 }
00381 } catch (InstanceAlreadyExistsException iae) {
00382 String err = "Cannot start the WebContainerService Already Exists";
00383 throw new ServiceException(err, iae);
00384 } catch (MBeanRegistrationException mbre) {
00385 throw new ServiceException("Cannot start the WebContainerService (MBean registration error)", mbre);
00386 } catch (NotCompliantMBeanException ncmbe) {
00387 throw new ServiceException("Cannot start the WebContainerService (MBean Not compliant error)", ncmbe);
00388 }
00389 }
00390
00395 protected void doStop() throws ServiceException {
00396
00397
00398
00399 Enumeration wars = warDeployed.elements();
00400 while (wars.hasMoreElements()) {
00401 War war = (War) wars.nextElement();
00402 URL warURL = war.getWarURL();
00403 String fileName = warURL.getFile();
00404 try {
00405
00406 if (!war.isInEarCase()) {
00407 Context ctx = new CompNamingContext(fileName);
00408 ctx.rebind("warURL", warURL);
00409 ctx.rebind("isEarCase", new Boolean(false));
00410 unRegisterWar(ctx);
00411 }
00412 } catch (Exception e) {
00413
00414
00415 String err = "Error when undeploying the war :" + fileName;
00416 logger.log(BasicLevel.ERROR, err + e.getMessage());
00417 }
00418 }
00419
00420 if (mbeanServer != null) {
00421 try {
00422
00423 mbeanServer.unregisterMBean(JonasObjectName.webContainerService());
00424 } catch (Exception e) {
00425 logger.log(BasicLevel.ERROR, "Cannot stop the WebContainerService: " + e);
00426 }
00427 }
00428 logger.log(BasicLevel.DEBUG, "WebContainerService stopped");
00429 }
00430
00439 protected abstract void doRegisterWar(Context ctx) throws JWebContainerServiceException;
00440
00447 protected abstract void doUnRegisterWar(Context ctx) throws JWebContainerServiceException;
00448
00457 protected URL getUnpackDir(URL warURL, String earAppName) throws JWebContainerServiceException {
00458
00459 String destDir = WORK_WEBAPPS_DIR + File.separator + nameOfServer + File.separator;
00460
00461
00462
00463
00464
00465
00466
00467
00468 URL unpackedWarURL = null;
00469
00470 String fileName = warURL.getFile();
00471
00472
00473 if (new File(fileName).isFile()) {
00474
00475
00476 if (earAppName != null) {
00477 destDir += earAppName + File.separator;
00478 }
00479
00480 String fTemp = new File(fileName).getName();
00481 destDir += fTemp.substring(0, fTemp.length() - WAR_EXTENSION_LENGTH);
00482
00483
00484 JarTools.unpack(fileName, destDir);
00485 } else {
00486
00487 destDir = fileName;
00488 }
00489
00490 try {
00491 unpackedWarURL = new File(destDir).toURL();
00492 } catch (MalformedURLException mue) {
00493 throw new JWebContainerServiceException("Error", mue);
00494 }
00495
00496 return unpackedWarURL;
00497
00498 }
00499
00511 public URLClassLoader getClassLoader(URL warURL, String earAppName, ClassLoader parentLoader)
00512 throws JWebContainerServiceException {
00513
00514 URLClassLoader loaderForCls = null;
00515 try {
00516 WebLoaderHolder holder = (WebLoaderHolder) warLoaders.get(warURL);
00517 if (holder != null) {
00518 loaderForCls = holder.getJonasWebLoader();
00519 }
00520 } catch (Exception e) {
00521 throw new JWebContainerServiceException("Error when getting '" + warURL + "' in cache", e);
00522 }
00523
00524 if (loaderForCls == null) {
00525
00526
00527
00528 URL unpackedWarURL = getUnpackDir(warURL, earAppName);
00529
00530 try {
00531 if (parentLoader != null) {
00532
00533 loaderForCls = new WebappClassLoader(unpackedWarURL, parentLoader);
00534 } else {
00535
00536 loaderForCls = new WebappClassLoader(unpackedWarURL, appsClassLoader);
00537 }
00538 } catch (IOException ioe) {
00539 throw new JWebContainerServiceException(
00540 "Cannot create WebAppClassLoader from '" + unpackedWarURL + "'", ioe);
00541 }
00542
00543
00544 try {
00545 WebLoaderHolder holder = new WebLoaderHolder(loaderForCls, null);
00546 warLoaders.put(warURL, holder);
00547 } catch (Exception e) {
00548 throw new JWebContainerServiceException("Error when adding '" + warURL + "' in cache", e);
00549 }
00550 }
00551
00552 return loaderForCls;
00553
00554 }
00555
00560 public ClassLoader getContextLinkedClassLoader(URL warURL) {
00561 WebLoaderHolder holder = (WebLoaderHolder) warLoaders.get(warURL);
00562 if (holder != null) {
00563 return holder.getEnvWebLoader();
00564 }
00565 return null;
00566 }
00567
00576 private void registerWar(Context ctx) throws JWebContainerServiceException {
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 URL earURL = null;
00592 String contextRoot = null;
00593 String earAppName = null;
00594 try {
00595 earURL = (URL) ctx.lookup("earURL");
00596 contextRoot = (String) ctx.lookup("contextRoot");
00597 earAppName = EarServiceImpl.buildJ2eeApplicationName(earURL);
00598 } catch (NamingException e) {
00599 if (earURL != null || contextRoot != null) {
00600 String err = "Error while getting parameter from context param :" + e.getMessage();
00601 logger.log(BasicLevel.ERROR, err);
00602 throw new JWebContainerServiceException(err, e);
00603 }
00604 }
00605
00606
00607 URL warURL = null;
00608 try {
00609 warURL = (URL) ctx.lookup("warURL");
00610 } catch (NamingException e) {
00611 String err = "Error while getting parameter from context param :" + e.getMessage();
00612 logger.log(BasicLevel.ERROR, err);
00613 throw new JWebContainerServiceException(err, e);
00614 }
00615
00616
00617 File warFile = new File(warURL.getFile());
00618 if (!warFile.exists()) {
00619 String err = "registerWar: '" + warFile.getPath() + "' not found";
00620 logger.log(BasicLevel.ERROR, err);
00621 throw new JWebContainerServiceException(err);
00622 }
00623
00624
00625 War war = getWar(warURL);
00626 if (war != null) {
00627
00628 String err = "Cannot deploy war '" + warURL.getFile() + "' is already deployed."
00629 + " You must undeploy the war before a new deployment.";
00630 throw new JWebContainerServiceException(err);
00631 }
00632
00633 URLClassLoader parentLoader = null;
00634 URLClassLoader earClassLoader = null;
00635 try {
00636 parentLoader = (URLClassLoader) ctx.lookup("parentClassLoader");
00637 earClassLoader = (URLClassLoader) ctx.lookup("earClassLoader");
00638 } catch (NamingException ne) {
00639 logger.log(BasicLevel.DEBUG, "Not an ear case");
00640
00641 }
00642
00643
00644 URLClassLoader loaderForCls = getClassLoader(warURL, earAppName, parentLoader);
00645
00646
00647 URL unpackedWarURL = getUnpackDir(warURL, earAppName);
00648
00649
00650
00651 if (wsService != null && earClassLoader == null) {
00652 try {
00653 CompNamingContext contctx = null;
00654 try {
00655 contctx = new CompNamingContext(unpackedWarURL.getFile());
00656 contctx.rebind("unpackDir", unpackedWarURL.toExternalForm());
00657 contctx.rebind("jarUrls", new URL[0]);
00658 contctx.rebind("warUrls", new URL[] {warURL});
00659 if (parentLoader != null) {
00660 contctx.rebind("ejbClassLoader", parentLoader);
00661 }
00662 } catch (NamingException e) {
00663 String err = "Can not bind params for the WebServices service, "
00664 + "Can't deploy Web Services Endpoint";
00665 throw new JWebContainerServiceException(err, e);
00666 }
00667 wsService.deployWebServices(contctx);
00668 } catch (ServiceException se) {
00669 String err = "Error during the deployment of the WebServices of the War file '" + warURL + "'";
00670 logger.log(BasicLevel.ERROR, err + " : " + se.getMessage());
00671 throw new JWebContainerServiceException(err, se);
00672 }
00673 }
00674
00675
00676 WebContainerDeploymentDesc webDD = null;
00677 try {
00678 webDD = WebManagerWrapper.getDeploymentDesc(warURL, loaderForCls, earClassLoader);
00679 } catch (WebContainerDeploymentDescException e) {
00680 String err = "Cannot read the deployment descriptors '" + warURL.getFile() + "'";
00681 logger.log(BasicLevel.ERROR, err + ": " + e);
00682 e.printStackTrace(System.err);
00683 throw new JWebContainerServiceException(err, e);
00684 }
00685
00686
00687 URLClassLoader webClassLoader = null;
00688 try {
00689 logger.log(BasicLevel.DEBUG, "Populating environment of the file " + warURL.getFile());
00690 Context ctxParam = new CompNamingContext(unpackedWarURL.getFile());
00691 ctxParam.rebind("DeploymentDesc", webDD);
00692 ctxParam.rebind("warName", unpackedWarURL.getFile());
00693 if (parentLoader == null) {
00694 webClassLoader = new SimpleWebappClassLoader(unpackedWarURL, appsClassLoader);
00695 } else {
00696 webClassLoader = new SimpleWebappClassLoader(unpackedWarURL, parentLoader);
00697 }
00698 ctxParam.rebind("parentCL", webClassLoader);
00699
00700 setWebEnvironment(ctxParam);
00701 } catch (Exception e) {
00702
00703 String err = "Error when populating ";
00704 logger.log(BasicLevel.ERROR, err + e.getMessage());
00705 throw new JWebContainerServiceException(err, e);
00706 }
00707
00708
00709 WebLoaderHolder holder = (WebLoaderHolder) warLoaders.get(warURL);
00710 holder.setEnvWebLoader(webClassLoader);
00711
00712
00713
00714
00715
00716
00717 if (earClassLoader == null && contextRoot == null) {
00718 String cRoot = webDD.getContextRoot();
00719 if (cRoot == null) {
00720 String file = new File(unpackedWarURL.getFile()).getName();
00721 if (file.toLowerCase().endsWith(".war")) {
00722 contextRoot = file.substring(0, file.length() - WAR_EXTENSION_LENGTH);
00723 } else {
00724
00725 contextRoot = file.substring(0, file.length());
00726 }
00727 } else {
00728 contextRoot = cRoot;
00729 }
00730 }
00731
00732
00733
00734 String hostName = webDD.getHost();
00735
00736
00737 List deployedWars = getWar(contextRoot);
00738 for (Iterator itDeployed = deployedWars.iterator(); itDeployed.hasNext();) {
00739 War deployedWar = (War) itDeployed.next();
00740 String hostDeployed = deployedWar.getHostName();
00741 if ((hostDeployed == null && hostName == null) || (hostDeployed != null && hostDeployed.equals(hostName))) {
00742
00743 String err = "Cannot deploy war '" + warURL.getFile() + "' is already deployed with the context '"
00744 + contextRoot + "'." + " You must undeploy the war before a new deployment.";
00745 throw new JWebContainerServiceException(err);
00746 }
00747 }
00748
00749
00750 boolean java2DelegationModel = webDD.getJava2DelegationModel();
00751
00752
00753 war = new War(warURL, earURL, hostName, contextRoot, java2DelegationModel, webDD.getXmlContent(), webDD
00754 .getJOnASXmlContent(), webDD.getServletsName());
00755
00756
00757 PermissionManager permissionManager = null;
00758 try {
00759 permissionManager = new PermissionManager(webDD, war.getContextId());
00760 permissionManager.translateServletDeploymentDescriptor();
00761
00762
00763 if (earClassLoader == null) {
00764 permissionManager.commit();
00765 }
00766 } catch (Exception e) {
00767 e.printStackTrace();
00768 String err = "Cannot build permission manager object for the webapp '" + unpackedWarURL + "' : ";
00769 logger.log(BasicLevel.ERROR, err + e.getMessage());
00770 throw new JWebContainerServiceException(err, e);
00771 }
00772
00773
00774 Context ctxParam = null;
00775 try {
00776 ctxParam = new CompNamingContext(unpackedWarURL.getFile());
00777 ctxParam.rebind("warURL", warURL);
00778 if (earURL != null) {
00779 ctxParam.rebind("earURL", earURL);
00780 }
00781 ctxParam.rebind("unpackedWarURL", unpackedWarURL);
00782 ctxParam.rebind("parentCL", webClassLoader);
00783 if (hostName != null) {
00784 ctxParam.rebind("hostName", hostName);
00785 }
00786 ctxParam.rebind("contextRoot", contextRoot);
00787 if (earAppName != null) {
00788 ctxParam.rebind("earAppName", earAppName);
00789 }
00790 ctxParam.rebind("jonasDD", webDD.getJOnASXmlContent());
00791 ctxParam.rebind("java2DelegationModel", new Boolean(java2DelegationModel));
00792 ctxParam.rebind("permissionManager", permissionManager);
00793 } catch (NamingException e) {
00794 String err = "Error when deploying the war '" + unpackedWarURL.getFile() + "'";
00795 logger.log(BasicLevel.ERROR, err + e.getMessage());
00796 throw new JWebContainerServiceException(err, e);
00797 }
00798
00799 war.setPermissionManager(permissionManager);
00800
00801
00802 doRegisterWar(ctxParam);
00803
00804
00805 warDeployed.addElement(war);
00806 warBindings.put(warURL, webClassLoader);
00807
00808 try {
00809
00810 if (mbeanServer != null) {
00811 mbeanServer.registerMBean(war, JonasObjectName.war(warURL.getFile()));
00812 }
00813 } catch (Exception ware) {
00814 logger.log(BasicLevel.ERROR, "Can not register the MBean for the war" + unpackedWarURL + " :"
00815 + ware.getMessage());
00816 }
00817
00818
00819
00820
00821 if (wsService != null && earClassLoader == null) {
00822 try {
00823 CompNamingContext contctx = null;
00824 try {
00825 contctx = new CompNamingContext(unpackedWarURL.getFile());
00826 contctx.rebind(AbsWebServicesServiceImpl.CLASSLOADER_CTX_PARAM, loaderForCls);
00827 } catch (NamingException e) {
00828 String err = "Can not bind params for the WebServices service, "
00829 + "can't complete deployment of Web Services Endpoints";
00830 throw new JWebContainerServiceException(err, e);
00831 }
00832 wsService.completeWSDeployment(contctx);
00833 } catch (ServiceException se) {
00834 String err = "Error during the deployment of the WebServices of the War file '" + warURL + "'";
00835 logger.log(BasicLevel.ERROR, err + " : " + se.getMessage());
00836 throw new JWebContainerServiceException(err, se);
00837 }
00838 }
00839
00840 StringBuffer txtInfo = new StringBuffer("War " + warURL.getFile() + " available at the context ");
00841 if (!contextRoot.startsWith("/")) {
00842 txtInfo.append("/");
00843 }
00844 txtInfo.append(contextRoot);
00845
00846 if (hostName != null) {
00847 txtInfo.append(" on the host ");
00848 txtInfo.append(hostName);
00849 }
00850 txtInfo.append(".");
00851 logger.log(BasicLevel.INFO, txtInfo.toString());
00852
00853
00854 if (wsService != null && earClassLoader == null) {
00855 wsService.removeCache(loaderForCls);
00856 }
00857 }
00858
00866 public void registerWarMBean(String fileName) throws RemoteException, JWebContainerServiceException {
00867
00868
00869 URL warURL = checkWarFile(fileName);
00870
00871
00872 Context ctx = null;
00873 try {
00874 ctx = new CompNamingContext(fileName);
00875 ctx.rebind("warURL", warURL);
00876 } catch (NamingException e) {
00877 String err = "Error when deploying the war '" + fileName + "'";
00878 logger.log(BasicLevel.ERROR, err + e.getMessage());
00879 throw new JWebContainerServiceException(err, e);
00880 }
00881
00882
00883 registerWar(ctx);
00884 }
00885
00893 private void setWebEnvironment(Context ctxParam) throws JWebContainerServiceException {
00894
00895 WebContainerDeploymentDesc dd = null;
00896 String warName = null;
00897 ClassLoader parentClassLoader = null;
00898
00899
00900
00901
00902
00903 try {
00904 dd = (WebContainerDeploymentDesc) ctxParam.lookup("DeploymentDesc");
00905 warName = (String) ctxParam.lookup("warName");
00906 } catch (NamingException e) {
00907 String err = "Error while getting parameter from context param ";
00908 logger.log(BasicLevel.ERROR, err + e.getMessage());
00909 throw new JWebContainerServiceException(err, e);
00910 }
00911
00912
00913 try {
00914 parentClassLoader = (ClassLoader) ctxParam.lookup("parentCL");
00915 } catch (NamingException e) {
00916 String err = "Error while getting parameter from context param ";
00917 logger.log(BasicLevel.ERROR, err + e.getMessage());
00918 throw new JWebContainerServiceException(err, e);
00919 }
00920
00921
00922 try {
00923
00924 Context javaCtx = naming.createEnvironmentContext(warName);
00925 naming.setComponentContext(javaCtx, parentClassLoader);
00926 Context envCtx = javaCtx.createSubcontext("comp/env");
00927
00928
00929 EnvEntryDesc[] envt = dd.getEnvEntryDesc();
00930 for (int i = 0; i < envt.length; i++) {
00931
00932 String name = envt[i].getName();
00933 Object obj = envt[i].getValue();
00934
00935
00936 logger.log(BasicLevel.DEBUG, warName + ": Binding object " + name + " -> " + obj);
00937 envCtx.rebind(name, obj);
00938 }
00939
00940
00941 ResourceRefDesc[] resref = dd.getResourceRefDesc();
00942 for (int i = 0; i < resref.length; i++) {
00943
00944 String name = resref[i].getName();
00945 String type = resref[i].getTypeName();
00946 String resname = resref[i].getJndiName();
00947
00948 logger.log(BasicLevel.DEBUG, warName + ": Linking resource " + name + " -> " + resname);
00949
00950 if (type.equalsIgnoreCase("java.net.URL")) {
00951
00952 Reference ref = new Reference("java.net.URL", "org.objectweb.jonas_lib.naming.factory.URLFactory",
00953 null);
00954 StringRefAddr refAddr = new StringRefAddr("url", resname);
00955 ref.add(refAddr);
00956 envCtx.rebind(name, ref);
00957 } else {
00958
00959
00960 LinkRef lref = new LinkRef(resname);
00961 envCtx.rebind(name, lref);
00962 }
00963 }
00964
00965
00966 ResourceEnvRefDesc[] resEnvref = dd.getResourceEnvRefDesc();
00967 for (int i = 0; i < resEnvref.length; i++) {
00968
00969 String name = resEnvref[i].getName();
00970 String resname = resEnvref[i].getJndiName();
00971 LinkRef lref = new LinkRef(resname);
00972
00973 logger.log(BasicLevel.DEBUG, warName + ": Linking resource environment " + name + " -> " + resname);
00974 envCtx.rebind(name, lref);
00975 }
00976
00977
00978 EjbRefDesc[] ejbref = dd.getEjbRefDesc();
00979 for (int i = 0; i < ejbref.length; i++) {
00980
00981 String name = ejbref[i].getEjbRefName();
00982 String ejbname = null;
00983 ejbname = ejbref[i].getJndiName();
00984
00985 LinkRef lref = new LinkRef(ejbname);
00986
00987 logger.log(BasicLevel.DEBUG, warName + ": Linking ejb " + name + " -> " + ejbname);
00988 envCtx.rebind(name, lref);
00989 }
00990
00991
00992
00993
00994
00995 EjbLocalRefDesc[] ejblocalref = dd.getEjbLocalRefDesc();
00996 for (int i = 0; i < ejblocalref.length; i++) {
00997 String name = ejblocalref[i].getEjbRefName();
00998 String ejbname = ejblocalref[i].getJndiLocalName();
00999 LinkRef lref = new LinkRef(ejbname);
01000 logger.log(BasicLevel.DEBUG, warName + ": Linking ejb " + name + " -> " + ejbname);
01001 envCtx.rebind(name, lref);
01002 }
01003
01004
01005 MessageDestinationRefDesc[] mdref = dd.getMessageDestinationRefDesc();
01006 for (int i = 0; i < mdref.length; i++) {
01007
01008 String name = mdref[i].getMessageDestinationRefName();
01009 String mdname = null;
01010 mdname = mdref[i].getJndiName();
01011
01012 LinkRef lref = new LinkRef(mdname);
01013
01014 logger.log(BasicLevel.DEBUG, warName + ": Linking message-destination " + name + " -> " + mdname);
01015 envCtx.rebind(name, lref);
01016 }
01017
01018
01019
01020
01021
01022
01023 JServiceFactory factory = null;
01024
01025 ServiceRefDesc[] serviceRefs = dd.getServiceRefDesc();
01026 for (int i = 0; i < serviceRefs.length; i++) {
01027
01028 if (factory == null) {
01029 factory = JServiceFactoryFinder.getJOnASServiceFactory();
01030 }
01031
01032
01033 String name = serviceRefs[i].getServiceRefName();
01034
01035 Reference ref = factory.getServiceReference(serviceRefs[i], parentClassLoader);
01036 envCtx.rebind(name, ref);
01037 logger.log(BasicLevel.DEBUG, "Adding service-ref 'java:comp/env/" + name + "'");
01038 }
01039
01040 } catch (NamingException e) {
01041 String err = "Error while populating environment of the war file " + warName;
01042 logger.log(BasicLevel.ERROR, err + " :" + e.getMessage());
01043 throw new JWebContainerServiceException(err, e);
01044 }
01045 }
01046
01054 private void unRegisterWar(Context ctx) throws JWebContainerServiceException {
01055
01056
01057
01058 URL warURL = null;
01059 boolean isEarCase = true;
01060 try {
01061 warURL = (URL) ctx.lookup("warURL");
01062 isEarCase = ((Boolean) ctx.lookup("isEarCase")).booleanValue();
01063 } catch (NamingException e) {
01064 String err = "Error while getting parameter from context param.";
01065 logger.log(BasicLevel.ERROR, err + e.getMessage());
01066 throw new JWebContainerServiceException(err, e);
01067 }
01068
01069
01070 String fileName = warURL.getFile();
01071
01072
01073 War war = null;
01074 war = getWar(warURL);
01075 if (war == null) {
01076 String err = "Cannot undeploy war: '" + fileName + "' is not deployed.";
01077 logger.log(BasicLevel.ERROR, err);
01078 throw new JWebContainerServiceException(err);
01079 }
01080
01081
01082
01083
01084 if (isEarCase != war.isInEarCase()) {
01085 String err = "Cannot undeploy war: '" + fileName
01086 + "' it is in an ear application. You must undeploy the ear associated.";
01087 logger.log(BasicLevel.ERROR, err);
01088 throw new JWebContainerServiceException(err);
01089 }
01090
01091
01092 try {
01093
01094 ctx.rebind("contextRoot", war.getContextRoot());
01095 ctx.rebind("webClassLoader", warBindings.get(warURL));
01096 } catch (NamingException e) {
01097 String err = "Error when undeploying the war '" + fileName + "'";
01098 logger.log(BasicLevel.ERROR, err + e.getMessage());
01099 throw new JWebContainerServiceException(err, e);
01100 }
01101
01102
01103 PermissionManager permissionManager = war.getPermissionManager();
01104 try {
01105 permissionManager.delete();
01106 permissionManager = null;
01107 } catch (PermissionManagerException pme) {
01108 logger.log(BasicLevel.ERROR, "Cannot remove permission manager for file '" + fileName + "'.", pme);
01109 }
01110
01111 doUnRegisterWar(ctx);
01112
01113
01114 URLClassLoader loader = (URLClassLoader) warBindings.remove(warURL);
01115 naming.unSetComponentContext(loader);
01116
01117
01118 warLoaders.remove(warURL);
01119
01120
01121
01122 warDeployed.removeElement(war);
01123
01124
01125 if (mbeanServer != null) {
01126 try {
01127
01128 mbeanServer.unregisterMBean(JonasObjectName.war(fileName));
01129 } catch (Exception e) {
01130 logger
01131 .log(BasicLevel.ERROR, "Cannot remove the MBean for the war " + fileName + " : "
01132 + e.getMessage());
01133 }
01134 }
01135
01136 logger.log(BasicLevel.INFO, "War " + fileName + " no longer available");
01137 }
01138
01146 public void unRegisterWarMBean(String fileName) throws RemoteException, JWebContainerServiceException {
01147
01148
01149
01150 URL warURL = checkWarDeployed(fileName);
01151
01152
01153 Context ctx = null;
01154 try {
01155 ctx = new CompNamingContext(fileName);
01156 ctx.rebind("warURL", warURL);
01157 ctx.rebind("isEarCase", new Boolean(false));
01158 } catch (NamingException e) {
01159 String err = "Error when undeploying the war file '" + fileName + "'";
01160 logger.log(BasicLevel.ERROR, err + e.getMessage());
01161 throw new JWebContainerServiceException(err, e);
01162 }
01163 unRegisterWar(ctx);
01164 }
01165
01181 public void deployWars(Context ctx) throws JWebContainerServiceException {
01182
01183
01184
01185
01186
01187
01188
01189 URL[] urls = null;
01190 URL earURL = null;
01191 ClassLoader parentClassLoader = null;
01192 ClassLoader earClassLoader = null;
01193 URL[] altDDs = null;
01194 String[] contextRoots = null;
01195 try {
01196 urls = (URL[]) ctx.lookup("urls");
01197 earURL = (URL) ctx.lookup("earURL");
01198 parentClassLoader = (ClassLoader) ctx.lookup("parentClassLoader");
01199 earClassLoader = (ClassLoader) ctx.lookup("earClassLoader");
01200 altDDs = (URL[]) ctx.lookup("altDDs");
01201 contextRoots = (String[]) ctx.lookup("contextRoots");
01202 } catch (NamingException e) {
01203 String err = "Error while getting parameter from context param ";
01204 logger.log(BasicLevel.ERROR, err + e.getMessage());
01205 throw new JWebContainerServiceException(err, e);
01206 }
01207
01208
01209
01210 for (int i = 0; i < urls.length; i++) {
01211
01212 String fileName = urls[i].getFile();
01213 logger.log(BasicLevel.DEBUG, "Deploy war '" + fileName + "' for the ear service");
01214
01215
01216
01217 Context contctx = null;
01218 try {
01219 contctx = new CompNamingContext(fileName);
01220 contctx.rebind("warURL", urls[i]);
01221 contctx.rebind("parentClassLoader", parentClassLoader);
01222 contctx.rebind("earClassLoader", earClassLoader);
01223 contctx.rebind("earURL", earURL);
01224 if (altDDs[i] != null) {
01225 contctx.rebind("altDD", altDDs[i]);
01226 }
01227 if (contextRoots[i] != null) {
01228 contctx.rebind("contextRoot", contextRoots[i]);
01229 }
01230 registerWar(contctx);
01231 } catch (Exception e) {
01232
01233
01234 logger.log(BasicLevel.ERROR, "Error when deploying '" + fileName + "'");
01235 logger.log(BasicLevel.ERROR, e.getMessage());
01236 logger.log(BasicLevel.ERROR, "Undeploy war of the ear application");
01237
01238 for (int j = 0; j < i; j++) {
01239 String warFileName = urls[j].getFile();
01240 try {
01241
01242 CompNamingContext context = new CompNamingContext(warFileName);
01243 context.rebind("warURL", urls[j]);
01244 context.rebind("isEarCase", new Boolean(true));
01245 unRegisterWar(context);
01246 } catch (Exception ex) {
01247
01248
01249 logger.log(BasicLevel.ERROR, "Error when undeploying '" + warFileName + "'");
01250 logger.log(BasicLevel.ERROR, ex.getMessage());
01251 logger.log(BasicLevel.ERROR, "Cannot undeploy war of the ear application");
01252 }
01253
01254 }
01255 throw new JWebContainerServiceException("Error during the deployment", e);
01256 }
01257 }
01258 }
01259
01266 public void unDeployWars(URL[] urls) {
01267 for (int i = 0; i < urls.length; i++) {
01268 String warFileName = urls[i].getFile();
01269 try {
01270
01271 CompNamingContext context = new CompNamingContext(warFileName);
01272 context.rebind("warURL", urls[i]);
01273 context.rebind("isEarCase", new Boolean(true));
01274 unRegisterWar(context);
01275 } catch (Exception ex) {
01276
01277
01278 logger.log(BasicLevel.ERROR, "Error when undeploying '" + warFileName + "'");
01279 logger.log(BasicLevel.ERROR, ex.getMessage());
01280 logger.log(BasicLevel.ERROR, "Cannot undeploy war of the ear application");
01281 }
01282 }
01283 }
01284
01290 public War getWar(URL url) {
01291 Enumeration wars = warDeployed.elements();
01292 while (wars.hasMoreElements()) {
01293 War war = (War) wars.nextElement();
01294 if (war.getWarURL().equals(url)) {
01295 return war;
01296 }
01297 }
01298 return null;
01299 }
01300
01307 private List getWar(String pContext) {
01308 List checkDeployed = new ArrayList();
01309 Enumeration wars = warDeployed.elements();
01310 while (wars.hasMoreElements()) {
01311 War war = (War) wars.nextElement();
01312 if (war.getContextRoot().equals(pContext)) {
01313 checkDeployed.add(war);
01314 }
01315 }
01316 return checkDeployed;
01317 }
01318
01325 public void removeCache(ClassLoader earClassLoader) {
01326 WebManagerWrapper.removeCache(earClassLoader);
01327 }
01328
01339 private URL checkWarFile(String fileName) throws JWebContainerServiceException {
01340
01341 File f = null;
01342 try {
01343 f = new File(fileName).getCanonicalFile();
01344 if (!f.exists()) {
01345 boolean found = false;
01346 String warFileName = null;
01347
01348 warFileName = WEBAPPS_DIR + File.separator + fileName;
01349 f = new File(warFileName).getCanonicalFile();
01350 found = f.exists();
01351 if (found) {
01352 fileName = f.getPath();
01353 } else {
01354 String err = "File '" + f.getPath() + "' not found";
01355 logger.log(BasicLevel.ERROR, err);
01356 throw new JWebContainerServiceException(err);
01357 }
01358 }
01359 } catch (IOException e) {
01360 String err = "Invalid war file name '" + fileName;
01361 logger.log(BasicLevel.ERROR, err);
01362 throw new JWebContainerServiceException(err, e);
01363 }
01364
01365 URL warURL = null;
01366 try {
01367 warURL = f.toURL();
01368 } catch (MalformedURLException e) {
01369 String err = "Invalid war file name '" + fileName + "'.";
01370 logger.log(BasicLevel.ERROR, err + e.getMessage());
01371 throw new JWebContainerServiceException(err, e);
01372 }
01373 return warURL;
01374 }
01375
01384 private URL checkWarDeployed(String fileName) throws JWebContainerServiceException {
01385
01386 URL url = null;
01387 try {
01388 Enumeration wars = warDeployed.elements();
01389 while (wars.hasMoreElements()) {
01390 War war = (War) wars.nextElement();
01391 url = (new File(fileName).getCanonicalFile()).toURL();
01392 if (war.getWarURL().equals(url)) {
01393 return url;
01394 }
01395 }
01396 String warFileName = WEBAPPS_DIR + File.separator + fileName;
01397 wars = warDeployed.elements();
01398 while (wars.hasMoreElements()) {
01399 War war = (War) wars.nextElement();
01400 url = (new File(warFileName).getCanonicalFile()).toURL();
01401 if (war.getWarURL().equals(url)) {
01402 return url;
01403 }
01404 }
01405
01406 String err = "Cannot undeploy war: '" + fileName + "' is not deployed.";
01407 logger.log(BasicLevel.ERROR, err);
01408 throw new JWebContainerServiceException(err);
01409
01410 } catch (MalformedURLException e) {
01411 String err = "Invalid war file name '" + fileName + "'.";
01412 logger.log(BasicLevel.ERROR, err + e.getMessage());
01413 throw new JWebContainerServiceException(err, e);
01414 } catch (IOException e) {
01415 String err = "Invalid war file name '" + fileName;
01416 logger.log(BasicLevel.ERROR, err);
01417 throw new JWebContainerServiceException(err, e);
01418 }
01419 }
01420
01424 public Integer getCurrentNumberOfWars() {
01425 return new Integer(warDeployed.size());
01426 }
01427
01436 public List getInstalledWars() throws Exception {
01437
01438 ArrayList al = JModule.getInstalledContainersInDir(WEBAPPS_DIR, JModule.WAR_EXTENSION, JModule.WAR_CHILD_DIR,
01439 JModule.WAR_CONFIRM_FILE);
01440
01441 for (Iterator it = autoloadDirectories.iterator(); it.hasNext();) {
01442 al.addAll(JModule.getInstalledContainersInDir((String) it.next(), JModule.WAR_EXTENSION,
01443 JModule.WAR_CHILD_DIR, JModule.WAR_CONFIRM_FILE));
01444 }
01445 return al;
01446 }
01447
01453 public Set getWarNames() {
01454 HashSet names = new HashSet();
01455 for (Enumeration wars = warDeployed.elements(); wars.hasMoreElements();) {
01456 War war = (War) wars.nextElement();
01457 URL warURL = war.getWarURL();
01458 names.add(warURL.getFile());
01459 }
01460 return names;
01461 }
01462
01470 private void addWars(String dirPath) {
01471 boolean found = false;
01472
01473
01474
01475 File dir = new File(dirPath);
01476 found = dir.isDirectory();
01477
01478 if (!found) {
01479
01480 dir = new File(WEBAPPS_DIR + File.separator + dirPath);
01481 found = dir.isDirectory();
01482 }
01483
01484 if (found) {
01485 addWarsFrom(dir);
01486 } else {
01487 String err = "Warning: Cannot load dir: '" + dirPath + "' ";
01488 err += "is not a directory or directory doesn't exist";
01489 logger.log(BasicLevel.WARN, err);
01490 }
01491 }
01492
01498 private void addWarsFrom(File dir) throws JWebContainerServiceException {
01499 try {
01500 if (dir.isDirectory()) {
01501 File[] files = dir.listFiles();
01502 for (int i = 0; i < files.length; i++) {
01503 if (files[i].isFile()) {
01504 if (files[i].getPath().toLowerCase().endsWith(".war")) {
01505
01506 warNames.add(files[i].getCanonicalPath());
01507 }
01508 } else {
01509
01510 warNames.add(files[i].getCanonicalPath());
01511 }
01512 }
01513 }
01514 } catch (IOException e) {
01515 String err = "Invalid file name '" + dir.getPath();
01516 logger.log(BasicLevel.ERROR, err);
01517 throw new JWebContainerServiceException(err, e);
01518 }
01519 }
01520
01526 public boolean isWarLoaded(String fileName) {
01527
01528 URL url = null;
01529 boolean isLoaded = false;
01530 try {
01531
01532 try {
01533 url = new File(fileName).getCanonicalFile().toURL();
01534
01535 if (getWar(url) != null) {
01536 isLoaded = true;
01537 } else {
01538
01539 url = null;
01540 }
01541 } catch (Exception e) {
01542 url = null;
01543 }
01544
01545 if (url == null) {
01546 url = new File(WEBAPPS_DIR + File.separator + fileName).getCanonicalFile().toURL();
01547
01548 if (getWar(url) != null) {
01549 isLoaded = true;
01550 }
01551 }
01552 } catch (Exception e) {
01553 String err = "Can not found if the war is deployed or not";
01554 logger.log(BasicLevel.ERROR, err);
01555 return false;
01556 }
01557
01558 return isLoaded;
01559 }
01560
01565 public List getDeployedWars() {
01566 ArrayList al = new ArrayList();
01567 for (Enumeration wars = warDeployed.elements(); wars.hasMoreElements();) {
01568 War war = (War) wars.nextElement();
01569 URL warURL = war.getWarURL();
01570 al.add(warURL.getFile());
01571 }
01572 return al;
01573 }
01574
01580 public List getDeployableWars() throws Exception {
01581 List al = getInstalledWars();
01582 al.removeAll(getDeployedWars());
01583 return al;
01584 }
01585
01590 public List getAutoloadDirectories() {
01591 ArrayList al = new ArrayList();
01592 for (Iterator it = autoloadDirectories.iterator(); it.hasNext();) {
01593 try {
01594 al.add(new File((String) it.next()).toURL().getPath());
01595 } catch (Exception e) {
01596 logger.log(BasicLevel.DEBUG, "Can't get autoload directories " + e.getMessage());
01597
01598 }
01599 }
01600 return al;
01601 }
01602
01607 public String getWebappsDirectory() {
01608 String sRet = null;
01609 try {
01610 sRet = (new File(WEBAPPS_DIR)).toURL().getPath();
01611 } catch (Exception e) {
01612 logger.log(BasicLevel.DEBUG, "Can't get webapps directory " + e.getMessage());
01613
01614 }
01615 return sRet;
01616 }
01617
01622 public String getServerName() {
01623 if (serverName == null) {
01624 updateServerInfos();
01625 }
01626 return serverName;
01627 }
01628
01633 public String getServerVersion() {
01634 if (serverVersion == null) {
01635 updateServerInfos();
01636 }
01637 return serverVersion;
01638 }
01639
01643 protected abstract void updateServerInfos();
01644
01651 public abstract String getDefaultHost() throws JWebContainerServiceException;
01652
01660 public abstract String getDefaultHttpPort() throws JWebContainerServiceException;
01661
01669 public abstract String getDefaultHttpsPort() throws JWebContainerServiceException;
01670
01674 protected static Logger getLogger() {
01675 return logger;
01676 }
01677
01681 protected ContainerNaming getNaming() {
01682 return naming;
01683 }
01684
01688 protected MBeanServer getMbeanServer() {
01689 return mbeanServer;
01690 }
01691
01695 protected void setServerName(String serverName) {
01696 this.serverName = serverName;
01697 }
01698
01702 protected void setServerVersion(String serverVersion) {
01703 this.serverVersion = serverVersion;
01704 }
01705
01711 public class WebLoaderHolder {
01712
01716 private URLClassLoader jonasWebLoader;
01717
01721 private ClassLoader envWebLoader;
01722
01728 public WebLoaderHolder(URLClassLoader jonas, ClassLoader env) {
01729 jonasWebLoader = jonas;
01730 envWebLoader = env;
01731 }
01732
01736 public URLClassLoader getJonasWebLoader() {
01737 return jonasWebLoader;
01738 }
01739
01743 public ClassLoader getEnvWebLoader() {
01744 return envWebLoader;
01745 }
01746
01750 public void setEnvWebLoader(ClassLoader envWebLoader) {
01751 this.envWebLoader = envWebLoader;
01752 }
01753
01757 public void setJonasWebLoader(URLClassLoader jonasWebLoader) {
01758 this.jonasWebLoader = jonasWebLoader;
01759 }
01760 }
01761
01762 }