0001: /**
0002: * EasyBeans
0003: * Copyright (C) 2007 Bull S.A.S.
0004: * Contact: easybeans@ow2.org
0005: *
0006: * This library is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU Lesser General Public
0008: * License as published by the Free Software Foundation; either
0009: * version 2.1 of the License, or any later version.
0010: *
0011: * This library is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * Lesser General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU Lesser General Public
0017: * License along with this library; if not, write to the Free Software
0018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
0019: * USA
0020: *
0021: * --------------------------------------------------------------------------
0022: * $Id: JOnASDeployer.java 1970 2007-10-16 11:49:25Z benoitf $
0023: * --------------------------------------------------------------------------
0024: */package org.ow2.easybeans.deployer;
0025:
0026: import java.lang.reflect.Constructor;
0027: import java.lang.reflect.InvocationTargetException;
0028: import java.lang.reflect.Method;
0029: import java.net.URL;
0030: import java.net.URLClassLoader;
0031: import java.security.Policy;
0032: import java.util.ArrayList;
0033: import java.util.Arrays;
0034: import java.util.Iterator;
0035: import java.util.LinkedList;
0036: import java.util.List;
0037:
0038: import javax.naming.Context;
0039: import javax.naming.NamingException;
0040: import javax.security.jacc.PolicyConfiguration;
0041: import javax.security.jacc.PolicyConfigurationFactory;
0042: import javax.security.jacc.PolicyContextException;
0043:
0044: import org.ow2.easybeans.api.EZBContainer;
0045: import org.ow2.easybeans.loader.EasyBeansClassLoader;
0046: import org.ow2.easybeans.naming.context.ContextImpl;
0047: import org.ow2.easybeans.persistence.PersistenceUnitManager;
0048: import org.ow2.easybeans.persistence.xml.PersistenceXmlFileAnalyzer;
0049: import org.ow2.easybeans.persistence.xml.PersistenceXmlFileAnalyzerException;
0050: import org.ow2.util.ee.deploy.api.archive.ArchiveException;
0051: import org.ow2.util.ee.deploy.api.deployable.CARDeployable;
0052: import org.ow2.util.ee.deploy.api.deployable.EARDeployable;
0053: import org.ow2.util.ee.deploy.api.deployable.EJB21Deployable;
0054: import org.ow2.util.ee.deploy.api.deployable.EJB3Deployable;
0055: import org.ow2.util.ee.deploy.api.deployable.EJBDeployable;
0056: import org.ow2.util.ee.deploy.api.deployable.IDeployable;
0057: import org.ow2.util.ee.deploy.api.deployable.LibDeployable;
0058: import org.ow2.util.ee.deploy.api.deployable.RARDeployable;
0059: import org.ow2.util.ee.deploy.api.deployable.WARDeployable;
0060: import org.ow2.util.ee.deploy.api.deployer.DeployerException;
0061: import org.ow2.util.ee.deploy.api.deployer.IDeployer;
0062: import org.ow2.util.log.Log;
0063: import org.ow2.util.log.LogFactory;
0064:
0065: /**
0066: * Implementation of the Deployer for EasyBeans in JOnAS. <br />
0067: * It will deploy EJB3 and EAR. EJB21 of the EAR will go in JOnAS, EJB3 in
0068: * EasyBeans, War in JOnAS, Rar in JOnAS.
0069: * @author Florent Benoit
0070: */
0071: public class JOnASDeployer extends AbsDeployer implements IDeployer {
0072:
0073: /**
0074: * Logger.
0075: */
0076: private static Log logger = LogFactory.getLog(JOnASDeployer.class);
0077:
0078: /**
0079: * JOnAS JClassLoader class.
0080: */
0081: private static final String JCLASSLOADER_CLASS = "org.objectweb.jonas.server.JClassLoader";
0082:
0083: /**
0084: * JOnAS service manager class.
0085: */
0086: private static final String SERVICE_MANAGER_CLASS = "org.objectweb.jonas.service.ServiceManager";
0087:
0088: /**
0089: * JOnAS EJB Manager Wrapper class.
0090: */
0091: private static final String EJBMANAGERWRAPPER_CLASS = "org.objectweb.jonas_ejb.deployment.lib.wrapper.EjbManagerWrapper";
0092:
0093: /**
0094: * JOnAS WEB Manager Wrapper class.
0095: */
0096: private static final String WEBMANAGERWRAPPER_CLASS = "org.objectweb.jonas_web.deployment.lib.wrapper.WebManagerWrapper";
0097:
0098: /**
0099: * JOnAS Client Manager Wrapper class.
0100: */
0101: private static final String CLIENTMANAGERWRAPPER_CLASS = "org.objectweb.jonas_client.deployment.lib.wrapper.ClientManagerWrapper";
0102:
0103: /**
0104: * JOnAS EJB manager setAvailable method.
0105: */
0106: private static final String EJBMANAGERWRAPPER_SETAVAILABLE_METHODNAME = "setAvailableEjbJarsAndAltDDs";
0107:
0108: /**
0109: * JOnAS WEB manager setAltDD method.
0110: */
0111: private static final String WEBMANAGERWRAPPER_SETALTDD_METHODNAME = "setAltDD";
0112:
0113: /**
0114: * JOnAS Client manager setAltDD method.
0115: */
0116: private static final String CLIENTMANAGERWRAPPER_SETALTDD_METHODNAME = "setAltDD";
0117:
0118: /**
0119: * JOnAS service manager getInstance() method name.
0120: */
0121: private static final String SERVICE_MANAGER_GETINSTANCE_METHODNAME = "getInstance";
0122:
0123: /**
0124: * JOnAS service manager getEjbService() method name.
0125: */
0126: private static final String SERVICE_MANAGER_GETEJBSERVICE_METHODNAME = "getEjbService";
0127:
0128: /**
0129: * JOnAS service manager getWebContainerService() method name.
0130: */
0131: private static final String SERVICE_MANAGER_GETWEBCONTAINERSERVICE_METHODNAME = "getWebContainerService";
0132:
0133: /**
0134: * JOnAS service manager getRarService() method name.
0135: */
0136: private static final String SERVICE_MANAGER_GETRARSERVICE_METHODNAME = "getRarService";
0137:
0138: /**
0139: * checkGenIC method on the EJB 2.1 service.
0140: */
0141: private static final String CHECK_GENIC_METHODNAME = "checkGenIC";
0142:
0143: /**
0144: * deploy method on the EJB 2.1 service.
0145: */
0146: private static final String EJBSERVICE_DEPLOY_METHODNAME = "deployJars";
0147:
0148: /**
0149: * deploy method on the EJB 2.1 service.
0150: */
0151: private static final String EJBSERVICE_UNDEPLOY_METHODNAME = "unDeployJars";
0152:
0153: /**
0154: * deploy method on the RAR service.
0155: */
0156: private static final String RARSERVICE_DEPLOY_METHODNAME = "deployRars";
0157:
0158: /**
0159: * undeploy method on the RAR service.
0160: */
0161: private static final String RARSERVICE_UNDEPLOY_METHODNAME = "unDeployRars";
0162:
0163: /**
0164: * deploy method on the Web container service.
0165: */
0166: private static final String WARSERVICE_DEPLOY_METHODNAME = "deployWars";
0167:
0168: /**
0169: * undeploy method on the Web container service.
0170: */
0171: private static final String WARSERVICE_UNDEPLOY_METHODNAME = "unDeployWars";
0172:
0173: /**
0174: * Reference to the JOnAS service manager.
0175: */
0176: private Object serviceManager = null;
0177:
0178: /**
0179: * Reference to the JOnAS EJB 2.1 Service.
0180: */
0181: private Object ejb21Service = null;
0182:
0183: /**
0184: * Reference to the JOnAS Web Service.
0185: */
0186: private Object warService = null;
0187:
0188: /**
0189: * Reference to the deploy method of war service.
0190: */
0191: private Method deployMethodwarService = null;
0192:
0193: /**
0194: * Reference to the undeploy method of war service.
0195: */
0196: private Method undeployMethodwarService = null;
0197:
0198: /**
0199: * Reference to the deploy method of EJB 2.1 service.
0200: */
0201: private Method deployMethodejb21Service = null;
0202:
0203: /**
0204: * Reference to the undeploy method of EJB 2.1 service.
0205: */
0206: private Method undeployMethodejb21Service = null;
0207:
0208: /**
0209: * Reference to the checkGenIC method of EJB 2.1 service.
0210: */
0211: private Method checkGenICMethod = null;
0212:
0213: /**
0214: * Reference to the JOnAS Resource Service.
0215: */
0216: private Object rarService = null;
0217:
0218: /**
0219: * Reference to the deploy method of rar service.
0220: */
0221: private Method deployMethodRarService = null;
0222:
0223: /**
0224: * Reference to the undeploy method of rar service.
0225: */
0226: private Method undeployMethodRarService = null;
0227:
0228: /**
0229: * Classloader used by JOnAS.
0230: */
0231: private Constructor jClassLoaderConstructor = null;
0232:
0233: /**
0234: * setAltDD method on EJB manager.
0235: */
0236: private Method ejbSetAltDD = null;
0237:
0238: /**
0239: * setAltDD method on Web manager.
0240: */
0241: private Method webSetAltDD = null;
0242:
0243: /**
0244: * setAltDD method on Client manager.
0245: */
0246: private Method clientSetAltDD = null;
0247:
0248: /**
0249: * Build a new instance of this deployer.
0250: * @throws DeployerException if the instance is not built.
0251: */
0252: public JOnASDeployer() throws DeployerException {
0253: super ();
0254:
0255: // First, get the service manager
0256: Class serviceManagerClazz = loadClass(SERVICE_MANAGER_CLASS);
0257:
0258: // Get the unique instance of the service manager
0259: Method getInstanceMethod = getMethod(serviceManagerClazz,
0260: SERVICE_MANAGER_GETINSTANCE_METHODNAME);
0261: serviceManager = invoke(getInstanceMethod, null);
0262:
0263: // Get ejb service
0264: Method getEJBServiceMethod = getMethod(serviceManagerClazz,
0265: SERVICE_MANAGER_GETEJBSERVICE_METHODNAME);
0266: ejb21Service = invoke(getEJBServiceMethod, serviceManager);
0267:
0268: // War service
0269: Method getWarServiceMethod = getMethod(serviceManagerClazz,
0270: SERVICE_MANAGER_GETWEBCONTAINERSERVICE_METHODNAME);
0271: warService = invoke(getWarServiceMethod, serviceManager);
0272:
0273: // Rar service
0274: Method getRarServiceMethod = getMethod(serviceManagerClazz,
0275: SERVICE_MANAGER_GETRARSERVICE_METHODNAME);
0276: rarService = invoke(getRarServiceMethod, serviceManager);
0277:
0278: // (un)deployRars method
0279: deployMethodRarService = getMethod(rarService.getClass(),
0280: RARSERVICE_DEPLOY_METHODNAME, Context.class);
0281: undeployMethodRarService = getMethod(rarService.getClass(),
0282: RARSERVICE_UNDEPLOY_METHODNAME, URL[].class, URL.class);
0283:
0284: // (un)deployWars method
0285: deployMethodwarService = getMethod(warService.getClass(),
0286: WARSERVICE_DEPLOY_METHODNAME, Context.class);
0287: undeployMethodwarService = getMethod(warService.getClass(),
0288: WARSERVICE_UNDEPLOY_METHODNAME, URL[].class);
0289:
0290: // (un)Deploy Jars method
0291: deployMethodejb21Service = getMethod(ejb21Service.getClass(),
0292: EJBSERVICE_DEPLOY_METHODNAME, Context.class);
0293: undeployMethodejb21Service = getMethod(ejb21Service.getClass(),
0294: EJBSERVICE_UNDEPLOY_METHODNAME, URL[].class);
0295:
0296: // GenIC
0297: try {
0298: checkGenICMethod = getMethod(ejb21Service.getClass(),
0299: CHECK_GENIC_METHODNAME, String.class, URL[].class);
0300: } catch (DeployerException e) {
0301: logger
0302: .warn("A method was not present in this JOnAS version, auto-GenIC will be disabled");
0303: }
0304:
0305: // get the constructor of the JClassLoader class.
0306: Class jclassLoaderClass = loadClass(JCLASSLOADER_CLASS);
0307:
0308: // Then get the constructor of JClassLoader
0309: try {
0310: jClassLoaderConstructor = jclassLoaderClass.getConstructor(
0311: String.class, URL[].class, ClassLoader.class);
0312: } catch (SecurityException e) {
0313: throw new DeployerException(
0314: "Cannot get the constructor on the '"
0315: + JCLASSLOADER_CLASS + "' class", e);
0316: } catch (NoSuchMethodException e) {
0317: throw new DeployerException(
0318: "Cannot get the constructor on the '"
0319: + JCLASSLOADER_CLASS + "' class", e);
0320: }
0321:
0322: // SetAltDD methods
0323: // First, load the classes
0324: Class ejbManagerClass = loadClass(EJBMANAGERWRAPPER_CLASS);
0325: Class webManagerClass = loadClass(WEBMANAGERWRAPPER_CLASS);
0326: Class clientManagerClass = loadClass(CLIENTMANAGERWRAPPER_CLASS);
0327: // Then get the methods
0328: ejbSetAltDD = getMethod(ejbManagerClass,
0329: EJBMANAGERWRAPPER_SETAVAILABLE_METHODNAME,
0330: URLClassLoader.class, URL[].class, URL[].class);
0331: webSetAltDD = getMethod(webManagerClass,
0332: WEBMANAGERWRAPPER_SETALTDD_METHODNAME,
0333: URLClassLoader.class, URL[].class, URL[].class);
0334: clientSetAltDD = getMethod(clientManagerClass,
0335: CLIENTMANAGERWRAPPER_SETALTDD_METHODNAME,
0336: URLClassLoader.class, URL[].class, URL[].class);
0337:
0338: }
0339:
0340: /**
0341: * Deploy a deployable. It can be an EJB jar, EAR, WAR, etc.
0342: * @param deployable a given deployable
0343: * @throws DeployerException if the deployment is not done.
0344: */
0345: public void deploy(final IDeployable deployable)
0346: throws DeployerException {
0347:
0348: checkSupportedDeployable(deployable);
0349: if (deployable instanceof EJBDeployable) {
0350: deployEJB((EJBDeployable) deployable);
0351: } else if (deployable instanceof EARDeployable) {
0352: // needs to unpack it before deploying it
0353: EARDeployable earDeployable = unpackEARDeployable((EARDeployable) deployable);
0354: deployEAR(earDeployable);
0355: }
0356: }
0357:
0358: /**
0359: * Undeploy the given deployable. It can be an EJB jar, EAR, WAR, etc.
0360: * @param deployable a given deployable to undeploy
0361: * @throws DeployerException if the undeploy operation fails.
0362: */
0363: public void undeploy(final IDeployable deployable)
0364: throws DeployerException {
0365: if (deployable instanceof EARDeployable) {
0366: undeployEAR((EARDeployable) deployable);
0367: } else {
0368: throw new UnsupportedOperationException(
0369: "Undeploy only .ear files");
0370: }
0371: }
0372:
0373: /**
0374: * Undeploy an EAR (called by the undeploy method).
0375: * @param tmpEARDeployable a given EAR deployable
0376: * @throws DeployerException if the undeployment is not done.
0377: */
0378: protected void undeployEAR(final EARDeployable tmpEARDeployable)
0379: throws DeployerException {
0380: logger.info("Undeploying {0}", tmpEARDeployable);
0381:
0382: // From which deployable get the containers deployed
0383: EARDeployable earDeployable = tmpEARDeployable;
0384:
0385: // Check if this archive has been unpacked ?
0386: EARDeployable unpackedDeployable = earDeployable
0387: .getUnpackedDeployable();
0388: if (unpackedDeployable != null) {
0389: earDeployable = unpackedDeployable;
0390: }
0391:
0392: // get EAR URL
0393: URL earURL;
0394: try {
0395: earURL = earDeployable.getArchive().getURL();
0396: } catch (ArchiveException e) {
0397: throw new DeployerException(
0398: "Cannot get the URL on the EAR deployable '"
0399: + earDeployable + "'.", e);
0400: }
0401:
0402: // Undeploy wars (by sending URL of these wars)
0403: List<WARDeployable> warDeployables = earDeployable
0404: .getWARDeployables();
0405: if (warDeployables != null && warService != null) {
0406: List<URL> urls = new ArrayList<URL>();
0407: for (WARDeployable warDeployable : warDeployables) {
0408: try {
0409: urls.add(warDeployable.getArchive().getURL());
0410: } catch (ArchiveException e) {
0411: logger
0412: .error(
0413: "Cannot get the URL from the Deployable ''{0}''",
0414: warDeployable, e);
0415: }
0416: }
0417:
0418: URL[] warURLs = urls.toArray(new URL[urls.size()]);
0419: invoke(undeployMethodwarService, warService,
0420: new Object[] { warURLs });
0421: }
0422:
0423: // Undeploy EJB 2.1 jars (by sending URL of these jars)
0424: List<EJB21Deployable> ejb21Deployables = earDeployable
0425: .getEJB21Deployables();
0426: if (ejb21Deployables != null && ejb21Service != null) {
0427: List<URL> urls = new ArrayList<URL>();
0428: for (EJB21Deployable ejbDeployable : ejb21Deployables) {
0429: try {
0430: urls.add(ejbDeployable.getArchive().getURL());
0431: } catch (ArchiveException e) {
0432: logger
0433: .error(
0434: "Cannot get the URL from the Deployable ''{0}''",
0435: ejbDeployable, e);
0436: }
0437: }
0438:
0439: // Call undeploy by using the array of URLs
0440: URL[] ejbJarURLs = urls.toArray(new URL[urls.size()]);
0441: invoke(undeployMethodejb21Service, ejb21Service,
0442: new Object[] { ejbJarURLs });
0443:
0444: }
0445:
0446: // Undeploy EJB3s
0447: undeployEJB3FromEAR(earDeployable);
0448:
0449: // Undeploy Resource Adapters (by sending URL of these jars)
0450: List<RARDeployable> rarDeployables = earDeployable
0451: .getRARDeployables();
0452: if (rarDeployables != null && rarService != null) {
0453: List<URL> urls = new ArrayList<URL>();
0454: for (RARDeployable rarDeployable : rarDeployables) {
0455: try {
0456: urls.add(rarDeployable.getArchive().getURL());
0457: } catch (ArchiveException e) {
0458: logger
0459: .error(
0460: "Cannot get the URL from the Deployable ''{0}''",
0461: rarDeployable, e);
0462: }
0463: }
0464:
0465: // Call undeploy by using the array of URLs
0466: URL[] rarURLs = urls.toArray(new URL[urls.size()]);
0467: invoke(undeployMethodRarService, rarService, rarURLs,
0468: earURL);
0469:
0470: }
0471:
0472: logger.info("''{0}'' EAR Deployable is now undeployed",
0473: tmpEARDeployable);
0474: }
0475:
0476: /**
0477: * Deploy an EAR (called by the deploy method).
0478: * @param earDeployable a given EAR deployable
0479: * @throws DeployerException if the deployment is not done.
0480: */
0481: protected void deployEAR(final EARDeployable earDeployable)
0482: throws DeployerException {
0483: logger.info("Deploying {0}", earDeployable);
0484:
0485: // Get URL of this EAR
0486: URL earURL = null;
0487: try {
0488: earURL = earDeployable.getArchive().getURL();
0489: } catch (ArchiveException e) {
0490: throw new DeployerException(
0491: "Cannot get the URL for the deployable '"
0492: + earDeployable + "'.", e);
0493: }
0494:
0495: // Create a Root classloader for this EAR
0496: // Empty classloader
0497: URLClassLoader earClassLoader = (URLClassLoader) newInstance(
0498: jClassLoaderConstructor, earURL.toExternalForm(),
0499: new URL[0], Thread.currentThread()
0500: .getContextClassLoader());
0501:
0502: // Get the URLs of EJB, WEB and Clients
0503: List<URL> urlsEJB = new ArrayList<URL>();
0504: for (EJBDeployable ejb : earDeployable.getEJBDeployables()) {
0505: try {
0506: urlsEJB.add(ejb.getArchive().getURL());
0507: } catch (ArchiveException e) {
0508: throw new DeployerException(
0509: "Cannot get the URL for the archive '"
0510: + ejb.getArchive() + "'", e);
0511: }
0512: }
0513: List<URL> urlsWAR = new ArrayList<URL>();
0514: for (WARDeployable war : earDeployable.getWARDeployables()) {
0515: try {
0516: urlsWAR.add(war.getArchive().getURL());
0517: } catch (ArchiveException e) {
0518: throw new DeployerException(
0519: "Cannot get the URL for the archive '"
0520: + war.getArchive() + "'", e);
0521: }
0522: }
0523: List<URL> urlsClient = new ArrayList<URL>();
0524: for (CARDeployable car : earDeployable.getCARDeployables()) {
0525: try {
0526: urlsClient.add(car.getArchive().getURL());
0527: } catch (ArchiveException e) {
0528: throw new DeployerException(
0529: "Cannot get the URL for the archive '"
0530: + car.getArchive() + "'", e);
0531: }
0532: }
0533:
0534: // Set alt-dd
0535: invoke(ejbSetAltDD, null, earClassLoader, urlsEJB
0536: .toArray(new URL[urlsEJB.size()]), new URL[urlsEJB
0537: .size()]);
0538: invoke(webSetAltDD, null, earClassLoader, urlsWAR
0539: .toArray(new URL[urlsWAR.size()]), new URL[urlsWAR
0540: .size()]);
0541: invoke(clientSetAltDD, null, earClassLoader, urlsClient
0542: .toArray(new URL[urlsClient.size()]),
0543: new URL[urlsClient.size()]);
0544:
0545: // Deploy the RAR files of the EAR (if any)
0546: deployRARs(earDeployable, earURL, earClassLoader);
0547:
0548: // deploy EJB3s
0549: // Get EJBs of this EAR
0550: List<EJB3Deployable> ejb3s = earDeployable.getEJB3Deployables();
0551: List<EJBDeployable<?>> ejbs = earDeployable.getEJBDeployables();
0552:
0553: // Get libraries of this EAR
0554: List<LibDeployable> libs = earDeployable.getLibDeployables();
0555:
0556: // Create array of URLs with EJBs + Libraries
0557: List<URL> urls = new ArrayList<URL>();
0558: for (EJBDeployable<?> ejb : ejbs) {
0559: try {
0560: urls.add(ejb.getArchive().getURL());
0561: } catch (ArchiveException e) {
0562: throw new DeployerException(
0563: "Cannot get the URL for the Archive '"
0564: + ejb.getArchive() + "'.", e);
0565: }
0566: }
0567: for (LibDeployable lib : libs) {
0568: try {
0569: urls.add(lib.getArchive().getURL());
0570: } catch (ArchiveException e) {
0571: throw new DeployerException(
0572: "Cannot get the URL for the Archive '"
0573: + lib.getArchive() + "'.", e);
0574:
0575: }
0576: }
0577:
0578: // Create classloader with these URLs
0579: URL[] arrayURLs = urls.toArray(new URL[urls.size()]);
0580:
0581: // Child of the EAR classloader with RARs
0582: ClassLoader ejbClassLoader = new EasyBeansClassLoader(
0583: arrayURLs, earClassLoader);
0584:
0585: // Get Persistence unit manager
0586: PersistenceUnitManager persistenceUnitManager = getPersistenceUnitManager(
0587: earDeployable, ejbClassLoader);
0588:
0589: // Reset context ID of EJBs
0590: addEjbContextIdToList(earDeployable, new ArrayList<String>(),
0591: true);
0592:
0593: // Create containers for each EJB3 deployable
0594: List<EZBContainer> containers = new ArrayList<EZBContainer>();
0595: for (EJBDeployable ejb : ejb3s) {
0596: containers.add(getEmbedded().createContainer(
0597: ejb.getArchive()));
0598: }
0599:
0600: // Configure containers
0601: for (EZBContainer container : containers) {
0602: // Set the classloader that needs to be used
0603: container.setClassLoader(ejbClassLoader);
0604: // Add persistence context found
0605: container.setPersistenceUnitManager(persistenceUnitManager);
0606: }
0607:
0608: // Start containers
0609: for (EZBContainer container : containers) {
0610: try {
0611: container.start();
0612: } catch (Exception e) {
0613: logger.error("Cannot start container {0}", container
0614: .getName(), e);
0615: // stop it
0616: try {
0617: container.stop();
0618: getEmbedded().removeContainer(container);
0619: } catch (Exception se) {
0620: logger.error("Cannot stop failing container {0}",
0621: container.getName(), se);
0622: }
0623: // rethrow it
0624: throw new DeployerException("Container '"
0625: + container.getName() + "' has failed", e);
0626: }
0627: }
0628:
0629: // Deploy EJB 2.1
0630: deployEJB21s(earDeployable, earURL, earClassLoader,
0631: ejbClassLoader);
0632:
0633: // Link policy context of EJBs and Webs components
0634: linkPolicyObjects(earDeployable);
0635:
0636: // Commit EJB Policy objects
0637: commitEJBPolicyObjects(earDeployable);
0638:
0639: // Deploy Web App
0640: deployWARs(earDeployable, earURL, earClassLoader,
0641: ejbClassLoader);
0642:
0643: // Commit Web policy objects
0644: commitWebBPolicyObjects(earDeployable);
0645:
0646: logger.info("''{0}'' EAR Deployable is now deployed",
0647: earDeployable);
0648: }
0649:
0650: /**
0651: * Deploy the WAR files present in the given EAR.
0652: * @param earDeployable the EAR containing the WARs
0653: * @param earURL the EAR URL
0654: * @param earClassLoader the EAR classloader
0655: * @param parentClassLoader the parent classloader (EJB) to use
0656: * @throws DeployerException if the wars are not deployed.
0657: */
0658: protected void deployWARs(final EARDeployable earDeployable,
0659: final URL earURL, final ClassLoader earClassLoader,
0660: final ClassLoader parentClassLoader)
0661: throws DeployerException {
0662: // First, try to see if there are .war in this EAR
0663: List<WARDeployable> wars = earDeployable.getWARDeployables();
0664:
0665: if (wars.size() > 0) {
0666: if (warService == null) {
0667: logger
0668: .warn(
0669: "There are WAR files in the EAR ''{0}'' but the 'web' service is not available",
0670: earDeployable);
0671: } else {
0672:
0673: // Build context for sending parameters
0674: Context ctx = new ContextImpl(earURL.toExternalForm());
0675: try {
0676: ctx.rebind("earURL", earURL);
0677: } catch (NamingException e) {
0678: throw new DeployerException(
0679: "Cannot add the EAR URL parameter '"
0680: + earURL + "'", e);
0681: }
0682: // Get URLS of the wars and context-root
0683: List<URL> urls = new LinkedList<URL>();
0684: List<String> ctxRoots = new LinkedList<String>();
0685: for (WARDeployable warDeployable : wars) {
0686:
0687: // URL
0688: URL url = null;
0689: try {
0690: url = warDeployable.getArchive().getURL();
0691: } catch (ArchiveException e) {
0692: throw new DeployerException(
0693: "Cannot get the URL for the archive '"
0694: + warDeployable.getArchive()
0695: + "'", e);
0696: }
0697: urls.add(url);
0698:
0699: // Context-root
0700: ctxRoots.add(warDeployable.getContextRoot());
0701:
0702: }
0703: try {
0704: ctx.rebind("urls", urls
0705: .toArray(new URL[urls.size()]));
0706: } catch (NamingException e) {
0707: throw new DeployerException(
0708: "Cannot add the urls parameter '" + urls
0709: + "'", e);
0710: }
0711:
0712: // Bind the parent classloader of the web application
0713: try {
0714: ctx.rebind("parentClassLoader", parentClassLoader);
0715: } catch (NamingException e) {
0716: throw new DeployerException(
0717: "Cannot add the parentClassLoader parameter '"
0718: + parentClassLoader + "'", e);
0719: }
0720:
0721: // Bind the earClassLoader of the web application
0722: try {
0723: ctx.rebind("earClassLoader", earClassLoader);
0724: } catch (NamingException e) {
0725: throw new DeployerException(
0726: "Cannot add the earClassLoader parameter '"
0727: + earClassLoader + "'", e);
0728: }
0729:
0730: // No alt-dd yet, give an empty array
0731: try {
0732: ctx.rebind("altDDs", new URL[urls.size()]);
0733: } catch (NamingException e) {
0734: throw new DeployerException(
0735: "Cannot add the altDDs parameter.'", e);
0736: }
0737:
0738: // Build context roots
0739: try {
0740: ctx.rebind("contextRoots", ctxRoots
0741: .toArray(new String[ctxRoots.size()]));
0742: } catch (NamingException e) {
0743: throw new DeployerException(
0744: "Cannot add the contextRoots parameter '"
0745: + urls + "'", e);
0746: }
0747:
0748: try {
0749: deployMethodwarService.invoke(warService, ctx);
0750: } catch (IllegalArgumentException e) {
0751: throw new DeployerException(
0752: "Cannot deploy the WARs.'", e);
0753: } catch (IllegalAccessException e) {
0754: throw new DeployerException(
0755: "Cannot deploy the WARs.'", e);
0756: } catch (InvocationTargetException e) {
0757: throw new DeployerException(
0758: "Cannot deploy the WARs.'", e
0759: .getTargetException());
0760: }
0761: }
0762: }
0763:
0764: }
0765:
0766: /**
0767: * Deploy the RARs of the given EAR.
0768: * @param earDeployable the EAR that contains the war files
0769: * @param earURL the URL of the EAR
0770: * @param earClassLoader the classloader of the EAR
0771: * @throws DeployerException if the RARs file can't be deployed
0772: */
0773: protected void deployRARs(final EARDeployable earDeployable,
0774: final URL earURL, final ClassLoader earClassLoader)
0775: throws DeployerException {
0776: // First, try to see if there are .rar in this EAR
0777: List<RARDeployable> rars = earDeployable.getRARDeployables();
0778: if (rars.size() > 0) {
0779: if (rarService == null) {
0780: logger
0781: .warn(
0782: "There are RAR files in the EAR ''{0}'' but the resource service is not available",
0783: earDeployable);
0784: } else {
0785: Context ctx = new ContextImpl(earURL.toExternalForm());
0786: try {
0787: ctx.rebind("earUrl", earURL);
0788: } catch (NamingException e) {
0789: throw new DeployerException(
0790: "Cannot add the EAR URL parameter '"
0791: + earURL + "'", e);
0792: }
0793: List<URL> urls = new ArrayList<URL>();
0794: for (RARDeployable rarDeployable : rars) {
0795: try {
0796: urls.add(rarDeployable.getArchive().getURL());
0797: } catch (ArchiveException e) {
0798: throw new DeployerException(
0799: "Cannot get the URL for the archive '"
0800: + rarDeployable.getArchive()
0801: + "'", e);
0802: }
0803: }
0804: try {
0805: ctx.rebind("urls", urls
0806: .toArray(new URL[urls.size()]));
0807: } catch (NamingException e) {
0808: throw new DeployerException(
0809: "Cannot add the urls parameter '" + urls
0810: + "'", e);
0811: }
0812: try {
0813: ctx.rebind("earClassLoader", earClassLoader);
0814: } catch (NamingException e) {
0815: throw new DeployerException(
0816: "Cannot add the earClassLoader parameter '"
0817: + earClassLoader + "'", e);
0818: }
0819: try {
0820: ctx.rebind("altDDs", new URL[urls.size()]);
0821: } catch (NamingException e) {
0822: throw new DeployerException(
0823: "Cannot add the altDDs parameter.'", e);
0824: }
0825:
0826: try {
0827: deployMethodRarService.invoke(rarService, ctx);
0828: } catch (IllegalArgumentException e) {
0829: throw new DeployerException(
0830: "Cannot deploy the RARs.'", e);
0831: } catch (IllegalAccessException e) {
0832: throw new DeployerException(
0833: "Cannot deploy the RARs.'", e);
0834: } catch (InvocationTargetException e) {
0835: throw new DeployerException(
0836: "Cannot deploy the RARs.'", e
0837: .getTargetException());
0838: }
0839: }
0840: }
0841:
0842: }
0843:
0844: /**
0845: * Deploy the EJB 2.1 of the given EAR.
0846: * @param earDeployable the EAR that contains the EJB files
0847: * @param earURL the URL of the EAR
0848: * @param earClassLoader the classloader of the EAR
0849: * @param ejbClassLoader the given EJB ClassLoader
0850: * @throws DeployerException if the EJB 2.1 filse can't be deployed
0851: */
0852: protected void deployEJB21s(final EARDeployable earDeployable,
0853: final URL earURL, final URLClassLoader earClassLoader,
0854: final ClassLoader ejbClassLoader) throws DeployerException {
0855: // First, try to see if there are EJB 2.1 in this EAR
0856: List<EJB21Deployable> ejbs = earDeployable
0857: .getEJB21Deployables();
0858: if (ejbs.size() > 0) {
0859: if (ejb21Service == null) {
0860: logger
0861: .warn(
0862: "There are EJB 2.1 files in the EAR ''{0}'' but the EJB 2.1 service is not available",
0863: earDeployable);
0864: } else {
0865:
0866: // Build list of EJB URLs
0867: List<URL> urls = new ArrayList<URL>();
0868: for (EJB21Deployable ejb21Deployable : ejbs) {
0869: try {
0870: urls.add(ejb21Deployable.getArchive().getURL());
0871: } catch (ArchiveException e) {
0872: throw new DeployerException(
0873: "Cannot get the URL for the archive '"
0874: + ejb21Deployable.getArchive()
0875: + "'", e);
0876: }
0877: }
0878:
0879: // Get classpath of the EJBs
0880: URL[] compilationURLs = null;
0881:
0882: // content of the ear loader (application wide resources)
0883: URL[] myApplicationJars = earClassLoader.getURLs();
0884:
0885: // content of the apps loader (system wide resources)
0886: URL[] appsJars = ((URLClassLoader) earClassLoader
0887: .getParent()).getURLs();
0888:
0889: // merge the 3 Set of URLs
0890: compilationURLs = new URL[myApplicationJars.length
0891: + appsJars.length + urls.size()];
0892: System.arraycopy(urls.toArray(new URL[urls.size()]), 0,
0893: compilationURLs, 0, urls.size());
0894: System.arraycopy(appsJars, 0, compilationURLs, urls
0895: .size(), appsJars.length);
0896: System.arraycopy(myApplicationJars, 0, compilationURLs,
0897: urls.size() + appsJars.length,
0898: myApplicationJars.length);
0899:
0900: // Call automatic GenIC on the URLs of the EJB 2.1
0901: if (checkGenICMethod != null) {
0902: for (EJB21Deployable ejb : ejbs) {
0903: URL ejbURL = null;
0904: try {
0905: ejbURL = ejb.getArchive().getURL();
0906: } catch (ArchiveException e) {
0907: throw new DeployerException(
0908: "Cannot get the URL on the deployable '"
0909: + ejb + "'", e);
0910: }
0911: logger
0912: .debug(
0913: "Calling GenIC on the EJB ''{0}'' with compilation URL ''{1}''.",
0914: ejbURL,
0915: Arrays.asList(compilationURLs));
0916: invoke(checkGenICMethod, ejb21Service, ejbURL
0917: .getFile(), compilationURLs);
0918: }
0919: }
0920:
0921: // Deploy EJB 2.1 on JOnAS service
0922: Context ctx = new ContextImpl(earURL.toExternalForm());
0923: try {
0924: ctx.rebind("earUrl", earURL);
0925: ctx.rebind("earRootUrl", earURL);
0926: } catch (NamingException e) {
0927: throw new DeployerException(
0928: "Cannot add the EAR URL parameter '"
0929: + earURL + "'", e);
0930: }
0931:
0932: try {
0933: ctx.rebind("jarURLs", urls.toArray(new URL[urls
0934: .size()]));
0935: } catch (NamingException e) {
0936: throw new DeployerException(
0937: "Cannot add the urls parameter '" + urls
0938: + "'", e);
0939: }
0940: try {
0941: ctx.rebind("earClassLoader", earClassLoader);
0942: } catch (NamingException e) {
0943: throw new DeployerException(
0944: "Cannot add the earClassLoader parameter '"
0945: + earClassLoader + "'", e);
0946: }
0947:
0948: // Bind the EJB classloader
0949: try {
0950: ctx.rebind("ejbClassLoader", ejbClassLoader);
0951: } catch (NamingException e) {
0952: throw new DeployerException(
0953: "Cannot add the ejbClassLoader parameter '"
0954: + ejbClassLoader + "'", e);
0955: }
0956:
0957: // Role names
0958: try {
0959: ctx.rebind("roleNames", new String[0]);
0960: } catch (NamingException e) {
0961: throw new DeployerException(
0962: "Cannot add the altDDs parameter.'", e);
0963: }
0964:
0965: try {
0966: deployMethodejb21Service.invoke(ejb21Service, ctx);
0967: } catch (IllegalArgumentException e) {
0968: throw new DeployerException(
0969: "Cannot deploy the EJB 2.1'", e);
0970: } catch (IllegalAccessException e) {
0971: throw new DeployerException(
0972: "Cannot deploy the EJB 2.1'", e);
0973: } catch (InvocationTargetException e) {
0974: throw new DeployerException(
0975: "Cannot deploy the EJB 2.1'", e
0976: .getTargetException());
0977: }
0978: }
0979: }
0980:
0981: }
0982:
0983: /**
0984: * Check that the given deployable is supported by this deployer. If it is
0985: * not supported, throw an error.
0986: * @param deployable the deployable that needs to be deployed
0987: * @throws DeployerException if this deployable is not supported.
0988: */
0989: private void checkSupportedDeployable(final IDeployable deployable)
0990: throws DeployerException {
0991: if (!(deployable instanceof EARDeployable || deployable instanceof EJBDeployable)) {
0992: throw new DeployerException("The deployable '" + deployable
0993: + "' is not supported by this deployer");
0994: }
0995: }
0996:
0997: /**
0998: * Link policy configuration objects of EJB and Web Component.
0999: * @param earDeployable the EAR that contains the EJB files
1000: * @throws DeployerException if the policy objects can't be linked
1001: */
1002: private void linkPolicyObjects(final EARDeployable earDeployable)
1003: throws DeployerException {
1004:
1005: // Add context ID of EJB and Web components
1006: List<String> ctxIDs = new LinkedList<String>();
1007: // Get contextID of EJB
1008: addEjbContextIdToList(earDeployable, ctxIDs, false);
1009:
1010: // Now for WebApp
1011: addWebBContextIdToList(earDeployable, ctxIDs, true);
1012:
1013: try {
1014: // Now link the policy configuration objects
1015: for (Iterator itCtxId = ctxIDs.iterator(); itCtxId
1016: .hasNext();) {
1017: String toBeLinkedCtxId = (String) itCtxId.next();
1018: PolicyConfiguration toBeLinkedPC = getPolicyConfigurationFactory()
1019: .getPolicyConfiguration(toBeLinkedCtxId, false);
1020: for (Iterator linkCId = ctxIDs.iterator(); linkCId
1021: .hasNext();) {
1022: String linkedCtxId = (String) linkCId.next();
1023: if (!toBeLinkedCtxId.equals(linkedCtxId)) {
1024: PolicyConfiguration linkedPC = getPolicyConfigurationFactory()
1025: .getPolicyConfiguration(linkedCtxId,
1026: false);
1027: toBeLinkedPC.linkConfiguration(linkedPC);
1028: }
1029: }
1030: }
1031: } catch (PolicyContextException pce) {
1032: throw new DeployerException(
1033: "Cannot retrieve a policy configuration", pce);
1034: }
1035:
1036: }
1037:
1038: /**
1039: * Add context-id for given jar urls to a given List.
1040: * @param earDeployable the EAR deployable to analyze
1041: * @param contextIDs the list of context-id.
1042: * @param resetPolicyConfiguration reset or not the associated policy
1043: * configuration.
1044: * @throws DeployerException if the EAR can't be analyzed
1045: */
1046: private void addEjbContextIdToList(
1047: final EARDeployable earDeployable,
1048: final List<String> contextIDs,
1049: final boolean resetPolicyConfiguration)
1050: throws DeployerException {
1051: // Extract URLs of EJB from the EAR
1052: List<EJBDeployable<?>> ejbDeployables = earDeployable
1053: .getEJBDeployables();
1054: List<URL> urls = new ArrayList<URL>();
1055: if (ejbDeployables != null) {
1056: for (EJBDeployable ejbDeployable : ejbDeployables) {
1057: try {
1058: urls.add(ejbDeployable.getArchive().getURL());
1059: } catch (ArchiveException e) {
1060: throw new DeployerException(
1061: "Cannot get URL on the deployable '"
1062: + ejbDeployable + "'.", e);
1063: }
1064: }
1065: }
1066:
1067: URL[] jarUrls = urls.toArray(new URL[urls.size()]);
1068:
1069: // Get contextID of EJB
1070: for (int u = 0; u < jarUrls.length; u++) {
1071: String ctxId = jarUrls[u].getPath();
1072: // reset the policy configuration associated to this context ID.
1073: if (resetPolicyConfiguration) {
1074: try {
1075: getPolicyConfigurationFactory()
1076: .getPolicyConfiguration(ctxId, true);
1077: } catch (PolicyContextException pce) {
1078: throw new DeployerException(
1079: "Cannot retrieve a policy configuration",
1080: pce);
1081: }
1082: }
1083: contextIDs.add(ctxId);
1084: }
1085: }
1086:
1087: /**
1088: * Add context-id for given web urls to a given List. Also, reset the
1089: * context-id associated to it. *
1090: * @param earDeployable the EAR deployable to analyze
1091: * @param contextIDs the list of context-id.
1092: * @param resetPolicyConfiguration reset or not the associated policy
1093: * configuration.
1094: * @throws DeployerException if policy context cannot be get.
1095: */
1096: private void addWebBContextIdToList(
1097: final EARDeployable earDeployable,
1098: final List<String> contextIDs,
1099: final boolean resetPolicyConfiguration)
1100: throws DeployerException {
1101:
1102: // Extract URLs of Web from the EAR
1103: List<WARDeployable> warDeployables = earDeployable
1104: .getWARDeployables();
1105: if (warDeployables != null) {
1106: for (WARDeployable warDeployable : warDeployables) {
1107: URL warURL = null;
1108: try {
1109: warURL = warDeployable.getArchive().getURL();
1110: } catch (ArchiveException e) {
1111: throw new DeployerException(
1112: "Cannot get URL on the deployable '"
1113: + warDeployable + "'.", e);
1114: }
1115:
1116: // build context ID of war
1117: String ctxId = warURL.getFile()
1118: + warDeployable.getContextRoot();
1119: // reset the policy configuration associated to this context ID.
1120: if (resetPolicyConfiguration) {
1121: try {
1122: getPolicyConfigurationFactory()
1123: .getPolicyConfiguration(ctxId, true);
1124: } catch (PolicyContextException pce) {
1125: throw new DeployerException(
1126: "Cannot retrieve a policy configuration",
1127: pce);
1128: }
1129: }
1130: contextIDs.add(ctxId);
1131: }
1132: }
1133: }
1134:
1135: /**
1136: * Commit policy configuration objects of EJB Component.
1137: * @param earDeployable the EAR to analyze
1138: * @throws DeployerException if the policy objects can't be committed
1139: */
1140: private void commitEJBPolicyObjects(
1141: final EARDeployable earDeployable) throws DeployerException {
1142: List<String> ctxIDs = new LinkedList<String>();
1143: addEjbContextIdToList(earDeployable, ctxIDs, false);
1144: commitPolicyObjects(ctxIDs);
1145: }
1146:
1147: /**
1148: * Commit policy configuration objects of Web Component.
1149: * @param earDeployable the EAR to analyze
1150: * @throws DeployerException if the policy objects can't be committed
1151: */
1152: private void commitWebBPolicyObjects(
1153: final EARDeployable earDeployable) throws DeployerException {
1154: List<String> ctxIDs = new LinkedList<String>();
1155: addWebBContextIdToList(earDeployable, ctxIDs, false);
1156: commitPolicyObjects(ctxIDs);
1157: }
1158:
1159: /**
1160: * @return policy configuration factory
1161: * @throws DeployerException if the policy configuration factory cannot
1162: * be obtain
1163: */
1164: private PolicyConfigurationFactory getPolicyConfigurationFactory()
1165: throws DeployerException {
1166: PolicyConfigurationFactory pcFactory = null;
1167: try {
1168: pcFactory = PolicyConfigurationFactory
1169: .getPolicyConfigurationFactory();
1170: } catch (Exception cnfe) {
1171: throw new DeployerException(
1172: "Cannot retrieve current policy configuration factory",
1173: cnfe);
1174: }
1175: return pcFactory;
1176: }
1177:
1178: /**
1179: * Commit policy context IDs of the given list.
1180: * @param ctxIDs list of context ID to commit.
1181: * @throws DeployerException if the policy objects cannot be committed.
1182: */
1183: private void commitPolicyObjects(final List ctxIDs)
1184: throws DeployerException {
1185: String ctxId = null;
1186: try {
1187: // commit the policy configuration objects
1188: for (Iterator itCtxId = ctxIDs.iterator(); itCtxId
1189: .hasNext();) {
1190: ctxId = (String) itCtxId.next();
1191: PolicyConfiguration pc = getPolicyConfigurationFactory()
1192: .getPolicyConfiguration(ctxId, false);
1193: pc.commit();
1194: }
1195: } catch (PolicyContextException pce) {
1196: throw new DeployerException(
1197: "Cannot commit policy configuration with Id '"
1198: + ctxId + "'", pce);
1199: }
1200:
1201: // refresh policy
1202: Policy.getPolicy().refresh();
1203: }
1204:
1205: }
|