0001: /**
0002: * JOnAS: Java(TM) Open Application Server
0003: * Copyright (C) 1999-2005 Bull S.A.
0004: * Contact: jonas-team@objectweb.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: EarServiceImpl.java 9700 2006-10-09 12:45:59Z benoitf $
0023: * --------------------------------------------------------------------------
0024: */package org.objectweb.jonas.ear;
0025:
0026: import java.io.File;
0027: import java.io.IOException;
0028: import java.net.MalformedURLException;
0029: import java.net.URL;
0030: import java.net.URLClassLoader;
0031: import java.security.Policy;
0032: import java.util.ArrayList;
0033: import java.util.Date;
0034: import java.util.Enumeration;
0035: import java.util.HashSet;
0036: import java.util.Hashtable;
0037: import java.util.Iterator;
0038: import java.util.LinkedList;
0039: import java.util.List;
0040: import java.util.Map;
0041: import java.util.Set;
0042: import java.util.StringTokenizer;
0043: import java.util.Vector;
0044:
0045: import javax.management.InstanceAlreadyExistsException;
0046: import javax.management.MBeanRegistrationException;
0047: import javax.management.MBeanServer;
0048: import javax.management.NotCompliantMBeanException;
0049: import javax.management.ObjectName;
0050: import javax.management.modelmbean.ModelMBean;
0051: import javax.naming.Context;
0052: import javax.naming.NamingException;
0053: import javax.security.jacc.PolicyConfiguration;
0054: import javax.security.jacc.PolicyConfigurationFactory;
0055: import javax.security.jacc.PolicyContextException;
0056:
0057: import org.apache.commons.modeler.ManagedBean;
0058: import org.apache.commons.modeler.Registry;
0059:
0060: import org.objectweb.jonas_client.deployment.api.ClientContainerDeploymentDesc;
0061: import org.objectweb.jonas_client.deployment.api.ClientContainerDeploymentDescException;
0062: import org.objectweb.jonas_client.deployment.lib.wrapper.ClientManagerWrapper;
0063:
0064: import org.objectweb.jonas_ear.deployment.api.EarDeploymentDesc;
0065: import org.objectweb.jonas_ear.deployment.api.EarDeploymentDescException;
0066: import org.objectweb.jonas_ear.deployment.lib.wrapper.EarManagerWrapper;
0067: import org.objectweb.jonas_ear.deployment.xml.Web;
0068:
0069: import org.objectweb.jonas_ejb.deployment.lib.wrapper.EjbManagerWrapper;
0070:
0071: import org.objectweb.jonas_lib.deployment.work.CleanerException;
0072: import org.objectweb.jonas_lib.deployment.work.DeployerLog;
0073: import org.objectweb.jonas_lib.deployment.work.DeployerLogException;
0074: import org.objectweb.jonas_lib.deployment.work.EarCleanTask;
0075: import org.objectweb.jonas_lib.deployment.work.EarFileManager;
0076: import org.objectweb.jonas_lib.deployment.work.FileManagerException;
0077: import org.objectweb.jonas_lib.deployment.work.WorkCleaner;
0078: import org.objectweb.jonas_lib.files.CheckerException;
0079: import org.objectweb.jonas_lib.files.WsGenChecker;
0080: import org.objectweb.jonas_lib.loader.ClientClassLoader;
0081: import org.objectweb.jonas_lib.loader.EjbJarClassLoader;
0082:
0083: import org.objectweb.jonas_web.deployment.lib.wrapper.WebManagerWrapper;
0084:
0085: import org.objectweb.jonas.client.AppClientModule;
0086: import org.objectweb.jonas.common.JModule;
0087: import org.objectweb.jonas.common.JProp;
0088: import org.objectweb.jonas.common.Log;
0089: import org.objectweb.jonas.container.EJBService;
0090: import org.objectweb.jonas.container.EJBServiceImpl;
0091: import org.objectweb.jonas.ear.lib.EarClassPathManager;
0092: import org.objectweb.jonas.ear.lib.EarClassPathManagerException;
0093: import org.objectweb.jonas.ear.lib.JarList;
0094: import org.objectweb.jonas.ear.lib.JarListException;
0095: import org.objectweb.jonas.jmx.J2eeObjectName;
0096: import org.objectweb.jonas.jmx.JmxService;
0097: import org.objectweb.jonas.jmx.JonasObjectName;
0098: import org.objectweb.jonas.management.JonasMBeanTools;
0099: import org.objectweb.jonas.naming.CompNamingContext;
0100: import org.objectweb.jonas.resource.ResourceService;
0101: import org.objectweb.jonas.resource.ResourceServiceException;
0102: import org.objectweb.jonas.security.jacc.JPolicyUserRoleMapping;
0103: import org.objectweb.jonas.server.JClassLoader;
0104: import org.objectweb.jonas.server.LoaderManager;
0105: import org.objectweb.jonas.service.AbsServiceImpl;
0106: import org.objectweb.jonas.service.ServiceException;
0107: import org.objectweb.jonas.service.ServiceManager;
0108: import org.objectweb.jonas.web.JWebContainerService;
0109: import org.objectweb.jonas.web.JWebContainerServiceException;
0110: import org.objectweb.jonas.ws.AbsWebServicesServiceImpl;
0111: import org.objectweb.jonas.ws.WSServiceException;
0112: import org.objectweb.jonas.ws.WebServicesService;
0113:
0114: import org.objectweb.util.monolog.api.BasicLevel;
0115: import org.objectweb.util.monolog.api.Logger;
0116:
0117: /**
0118: * JOnAS EAR Service Implementation class. This class provides an implementation
0119: * of the ear service.
0120: * @author Florent Benoit
0121: * @author Ludovic Bert Contributor(s): Adriana Danes: highlight configuration
0122: * properties Eric Hardesty: added ability to include rar files in an
0123: * ear Michel-Ange Anton : new JSR77 MBean
0124: */
0125: public class EarServiceImpl extends AbsServiceImpl implements
0126: EarService, EarServiceImplMBean {
0127:
0128: /**
0129: * The name of the JONAS_BASE directory.
0130: */
0131: protected static final String JONAS_BASE = JProp.getJonasBase();
0132:
0133: /**
0134: * The name of the apps directory.
0135: */
0136: protected static final String APPS_DIR = JONAS_BASE
0137: + File.separator + "apps";
0138:
0139: /**
0140: * The name of the working directory.
0141: */
0142: protected static final String WORK_DIR = JProp.getWorkDir();
0143:
0144: /**
0145: * The name of the working apps directory.
0146: */
0147: protected static final String WORK_APPS_DIR = WORK_DIR
0148: + File.separator + "apps";
0149:
0150: /**
0151: * Property for ear to deploy at runtime
0152: */
0153: protected static final String DESCRIPTORS = "jonas.service.ear.descriptors";
0154:
0155: /**
0156: * Directories property for autoload
0157: */
0158: protected static final String AUTOLOADDIR = "jonas.service.ear.autoloaddir";
0159:
0160: /**
0161: * Property for parsing with validation or not
0162: */
0163: protected static final String PARSINGWITHVALIDATION = "jonas.service.ear.parsingwithvalidation";
0164:
0165: /**
0166: * Property for the class of the EAR service
0167: */
0168: protected static final String CLASS = "jonas.service.ear.class";
0169:
0170: /**
0171: * Logger for this service.
0172: */
0173: private static Logger logger = null;
0174:
0175: /**
0176: * Reference to the cleaner
0177: */
0178: private static WorkCleaner workCleaner = null;
0179:
0180: /**
0181: * Reference to a MBean server.
0182: */
0183: private MBeanServer mbeanServer = null;
0184:
0185: /**
0186: * List of the ear names to load when starting the EarService
0187: */
0188: private Vector earNames = new Vector();
0189:
0190: /**
0191: * Reference to the Ejb service.
0192: */
0193: private EJBService ejbService = null;
0194:
0195: /**
0196: * Reference to the WebContainer service.
0197: */
0198: private JWebContainerService webContainerService = null;
0199:
0200: /**
0201: * Reference to the WebServices service.
0202: */
0203: private WebServicesService wsService = null;
0204:
0205: /**
0206: * Reference to the Resource service.
0207: */
0208: private ResourceService resourceService = null;
0209:
0210: /**
0211: * List of loaded ear
0212: */
0213: private Hashtable ears = null;
0214:
0215: /**
0216: * List of autoloaded directories.
0217: */
0218: private ArrayList autoloadDirectories = new ArrayList();
0219:
0220: /**
0221: * Reference on the DeployerLog which is the class that manage the
0222: * accesses to the log file (to remove the ear).
0223: */
0224: private DeployerLog earDeployerLog = null;
0225:
0226: /**
0227: * Application Classloader
0228: */
0229: private ClassLoader appsClassLoader;
0230:
0231: /**
0232: * Init the EAR service.
0233: * @param ctx the configuration of the Ear service.
0234: * @throws ServiceException if the initialization failed.
0235: */
0236: protected void doInit(Context ctx) throws ServiceException {
0237:
0238: //we init the logger
0239: logger = Log.getLogger(Log.JONAS_EAR_PREFIX);
0240:
0241: // get apps ClassLoader
0242: try {
0243: LoaderManager lm = LoaderManager.getInstance();
0244: appsClassLoader = lm.getAppsLoader();
0245: } catch (Exception e) {
0246: logger.log(BasicLevel.ERROR,
0247: "Cannot get the Applications ClassLoader from EAR Container Service: "
0248: + e);
0249: throw new ServiceException(
0250: "Cannot get the Applications ClassLoader from EAR Container Service",
0251: e);
0252: }
0253:
0254: ServiceManager sm = null;
0255:
0256: try {
0257: sm = ServiceManager.getInstance();
0258: } catch (Exception e) {
0259: String err = "Cannot get ServiceManager instance";
0260: logger.log(BasicLevel.ERROR, err);
0261: throw new ServiceException(err, e);
0262: }
0263:
0264: // Get the JMX Server via JMX Service
0265: try {
0266: mbeanServer = ((JmxService) sm.getJmxService())
0267: .getJmxServer();
0268: } catch (ServiceException e) {
0269: // the JMX service may not be started
0270: mbeanServer = null;
0271: }
0272:
0273: // Get the EJB service
0274: try {
0275: ejbService = (EJBService) sm.getEjbService();
0276: } catch (ServiceException e) {
0277: //not started
0278: ejbService = null;
0279: }
0280:
0281: // Get the Web Container service
0282: try {
0283: webContainerService = (JWebContainerService) sm
0284: .getWebContainerService();
0285: } catch (ServiceException e) {
0286: //not started
0287: webContainerService = null;
0288: }
0289:
0290: // Get the WebServices service
0291: try {
0292: wsService = (WebServicesService) sm.getWebServicesService();
0293: } catch (ServiceException e) {
0294: //not started
0295: wsService = null;
0296: }
0297:
0298: // Get the Resource service
0299: try {
0300: resourceService = (ResourceService) sm.getResourceService();
0301: } catch (ServiceException e) {
0302: //not started
0303: resourceService = null;
0304: }
0305:
0306: // Set the XML parsing mode to no validation
0307: String parsingMode = "false";
0308: try {
0309: parsingMode = (String) ctx.lookup(PARSINGWITHVALIDATION);
0310: } catch (NamingException e) {
0311: /*
0312: * No problem if there is no value for 'parsingwithvalidation'
0313: * (false by default)
0314: */
0315: if (logger.isLoggable(BasicLevel.DEBUG)) {
0316: logger
0317: .log(BasicLevel.DEBUG,
0318: "No XML parsing validation property, use default");
0319: }
0320: }
0321: EarManagerWrapper.setParsingWithValidation("true"
0322: .equalsIgnoreCase(parsingMode));
0323: if ("false".equalsIgnoreCase(parsingMode)) {
0324: if (logger.isLoggable(BasicLevel.DEBUG)) {
0325: logger.log(BasicLevel.DEBUG,
0326: "Ear XML parsing without validation");
0327: }
0328: } else {
0329: if (logger.isLoggable(BasicLevel.DEBUG)) {
0330: logger.log(BasicLevel.DEBUG,
0331: "Ear XML parsing with validation");
0332: }
0333: }
0334:
0335: // Init the ear names to be loaded when starting
0336: String descsValue = null;
0337: try {
0338: descsValue = (String) ctx.lookup(DESCRIPTORS);
0339: } catch (NamingException e) {
0340: if (logger.isLoggable(BasicLevel.DEBUG)) {
0341: logger.log(BasicLevel.DEBUG, "No property DESCRIPTORS");
0342: }
0343: // No problem if there is no value for 'descriptors'
0344: //(no ear to load)
0345: }
0346: if (descsValue != null) {
0347: StringTokenizer st = new StringTokenizer(descsValue, ",");
0348: while (st.hasMoreTokens()) {
0349: String fileName = st.nextToken().trim();
0350: earNames.add(fileName);
0351: }
0352: }
0353:
0354: // Add the ears of the jonas.service.ear.autoloaddir property
0355: String dirValue = null;
0356: ArrayList autoDirs = new ArrayList();
0357: try {
0358: dirValue = (String) ctx.lookup(AUTOLOADDIR);
0359: } catch (NamingException e) {
0360: if (logger.isLoggable(BasicLevel.DEBUG)) {
0361: logger.log(BasicLevel.DEBUG, "No AUTOLOADDIR property");
0362: }
0363: // No problem if there is no value for 'autoloaddir'
0364: //(no ear to load)
0365: }
0366: if (dirValue != null) {
0367: StringTokenizer st = new StringTokenizer(dirValue, ",");
0368: while (st.hasMoreTokens()) {
0369: String dirName = st.nextToken().trim();
0370: addEars(dirName);
0371: autoDirs.add(dirName);
0372: }
0373: }
0374: // Build autoload directories
0375: File oFile;
0376: Iterator it = autoDirs.iterator();
0377: while (it.hasNext()) {
0378: String dirName = (String) it.next();
0379: try {
0380: oFile = new File(APPS_DIR, dirName);
0381: if (!oFile.exists()) {
0382: oFile = new File(dirName);
0383: }
0384: if (oFile.exists()) {
0385: autoloadDirectories.add(oFile.getCanonicalPath());
0386: }
0387: } catch (Exception e) {
0388: String err = "Error when trying to verify Application EAR autoload directory : "
0389: + dirName;
0390: logger.log(BasicLevel.ERROR, err, e);
0391: }
0392: }
0393:
0394: //create hashtable of the ears ( Url of an ear ---> Ear structure)
0395: ears = new Hashtable();
0396:
0397: // Init the rar deployment desc manager.
0398: //rarDDManager = RarDeploymentDescManager.getInstance();
0399: }
0400:
0401: /**
0402: * Stop the EAR service.
0403: * @throws ServiceException if the stop failed.
0404: */
0405: protected void doStop() throws ServiceException {
0406:
0407: //undeploy the loaded ears files
0408: URL earFileName = null;
0409: //For each ear file, we delegate the operation to the
0410: //unDeployEar method
0411: for (Enumeration earEntries = ears.keys(); earEntries
0412: .hasMoreElements();) {
0413: earFileName = (URL) earEntries.nextElement();
0414: //Try to undeploy the ear
0415: try {
0416: Context ctx = new CompNamingContext(earFileName
0417: .getFile());
0418: ctx.rebind("filename", earFileName);
0419: unDeployEar(ctx);
0420: } catch (Exception e) {
0421: //We don't stop the process of undeploying the ears.
0422: //We only display an error in the logger.
0423: String err = "Error when undeploying the ear :"
0424: + earFileName;
0425: logger.log(BasicLevel.ERROR, err, e);
0426: }
0427: }
0428:
0429: if (mbeanServer != null) {
0430: try {
0431: // unregister EarService MBean : EarServiceImplMBean
0432: mbeanServer.unregisterMBean(JonasObjectName
0433: .earService());
0434: } catch (Exception e) {
0435: logger.log(BasicLevel.ERROR,
0436: "Cannot stop the EarService", e);
0437: }
0438: }
0439:
0440: //The service is stopped
0441: if (logger.isLoggable(BasicLevel.DEBUG)) {
0442: logger.log(BasicLevel.DEBUG, "EarService stopped");
0443: }
0444:
0445: }
0446:
0447: /**
0448: * Deploy an EAR file with sending JAR file to the EJB container and WAR
0449: * file to the WEB container and RAR file to the resource service.
0450: * @param ctx the context which contains the configuration in order to
0451: * deploy an EAR.
0452: * @return The ObjectName of the J2EE Application MBean associated to the
0453: * deployed EAR the Application Container
0454: * @throws EarServiceException if the deployment of the EAR failed.
0455: */
0456: public String deployEar(Context ctx) throws EarServiceException {
0457:
0458: //We have one of the ejb or web services launched
0459: if ((webContainerService == null) && (ejbService == null)) {
0460: throw new EarServiceException(
0461: "The ear service requires that at least the service ejb or web is launched for deploying an ear file.");
0462: }
0463:
0464: //We get the fileName
0465: // Get the file name and check if file exists
0466: String fileName;
0467: try {
0468: fileName = (String) ctx.lookup("filename");
0469: } catch (NamingException e) {
0470: throw new EarServiceException(
0471: "Error during performing lookup a fileName", e);
0472: }
0473:
0474: File f = null;
0475: try {
0476: //We search the file
0477: f = new File(fileName).getCanonicalFile();
0478:
0479: if (!f.exists()) {
0480: boolean found = false;
0481: String earFileName = null;
0482: if (fileName.toLowerCase().endsWith(".ear")) {
0483: // In case of the name is a ear file name, check also in
0484: // the JONAS_BASE/apps directory
0485: earFileName = APPS_DIR + File.separator + fileName;
0486: f = new File(earFileName).getCanonicalFile();
0487: found = f.exists();
0488: }
0489: if (found) {
0490: fileName = earFileName;
0491: } else {
0492: String err = "deployEar: The file "
0493: + fileName
0494: + " was not found neither in the current directory nor in the "
0495: + APPS_DIR + " directory";
0496: logger.log(BasicLevel.ERROR, err);
0497: throw new EarServiceException(err);
0498: }
0499: }
0500: } catch (IOException e) {
0501: String err = "Error when trying to get the canonical file from "
0502: + fileName;
0503: logger.log(BasicLevel.ERROR, err + " " + e.getMessage());
0504: throw new EarServiceException(err, e);
0505: }
0506:
0507: // Apply WsGen if needed
0508: // Before creating URLs, ...
0509: // -------------------------------
0510: try {
0511: ObjectName j2eeServer = J2eeObjectName.J2EEServer(this
0512: .getDomainName(), this .getJonasServerName());
0513: WsGenChecker wsgc = new WsGenChecker(this .mbeanServer,
0514: fileName, j2eeServer);
0515: wsgc.checkWsGen();
0516: } catch (CheckerException e) {
0517: throw new EarServiceException(
0518: "Cannot apply WsGen on the ear : " + fileName, e);
0519: } catch (Exception ue) {
0520: throw new EarServiceException(
0521: "Cannot apply WsGen on the ear (unexpected exception) : "
0522: + fileName, ue);
0523: }
0524:
0525: //--------------------------------
0526:
0527: //Make the url for the specified fileName and the earRootUrl
0528: URL[] earUrl = new URL[1];
0529: URL earRootUrl = null;
0530:
0531: try {
0532: earUrl[0] = f.toURL();
0533: earRootUrl = (new File(WORK_APPS_DIR + File.separator
0534: + getJonasServerName())).toURL();
0535: } catch (MalformedURLException e) {
0536: String err = "Invalid ear file name '" + fileName;
0537: logger.log(BasicLevel.ERROR, err + "': " + e.getMessage());
0538: throw new EarServiceException(err, e);
0539: }
0540:
0541: //Check if the ear is already deployed or not
0542: if (ears.get(earUrl[0]) != null) {
0543: String err = "The ear file : " + f.getName()
0544: + " is already deployed ('" + earUrl[0].getFile()
0545: + "'). You must undeploy the application "
0546: + "before a new deployment.";
0547: logger.log(BasicLevel.ERROR, err);
0548: throw new EarServiceException(err);
0549: }
0550:
0551: //Create classLoader
0552: //parent classloader is the current classloader
0553: URLClassLoader loaderCls = new URLClassLoader(earUrl,
0554: appsClassLoader);
0555:
0556: EarDeploymentDesc earDD = null;
0557: if (logger.isLoggable(BasicLevel.DEBUG)) {
0558: logger.log(BasicLevel.DEBUG,
0559: "Getting the deployment descriptor of the file"
0560: + f.getName());
0561: }
0562: try {
0563: earDD = EarManagerWrapper.getDeploymentDesc(earUrl[0]
0564: .getFile(), loaderCls);
0565: } catch (EarDeploymentDescException e) {
0566: String err = "Error in the Deployment descriptor '"
0567: + fileName + "': " + e;
0568: logger.log(BasicLevel.ERROR, err);
0569: throw new EarServiceException(err, e);
0570: }
0571:
0572: //We get the tags from the Deployment descriptor
0573: Web[] webTags = earDD.getWebTags();
0574: String[] ejbTags = earDD.getEjbTags();
0575: String[] connectorTags = earDD.getConnectorTags();
0576: String[] clientTags = earDD.getClientTags();
0577: String[] altDDClients = earDD.getAltDDClients();
0578: String[] altDDEjbs = earDD.getAltDDEjbs();
0579: String[] altDDWebs = earDD.getAltDDWebs();
0580: String[] altDDConnectors = earDD.getAltDDConnectors();
0581: String[] securityRoles = earDD.getSecurityRolesNames();
0582:
0583: //Check if all modules are inside the EAR file
0584: //no relatives mode like ../../file1.jar
0585:
0586: File fEar = new File(earUrl[0].getFile());
0587: File tmpFile = null;
0588:
0589: try {
0590: File fCanonicEar = fEar.getCanonicalFile();
0591: for (int i = 0; i < ejbTags.length; i++) {
0592: tmpFile = new File(fEar, ejbTags[i]);
0593: tmpFile = tmpFile.getCanonicalFile();
0594: if (!tmpFile.getPath()
0595: .startsWith(fCanonicEar.getPath())) {
0596: String err = "Error : The ejb-jar file "
0597: + ejbTags[i]
0598: + " is not inside the ear file " + fEar;
0599: logger.log(BasicLevel.ERROR, err);
0600: throw new EarServiceException(err);
0601: }
0602: }
0603:
0604: for (int i = 0; i < webTags.length; i++) {
0605: tmpFile = new File(fEar, webTags[i].getWebUri());
0606: tmpFile = tmpFile.getCanonicalFile();
0607: if (!tmpFile.getPath()
0608: .startsWith(fCanonicEar.getPath())) {
0609: String err = "Error : The war file "
0610: + webTags[i].getWebUri()
0611: + " is not inside the ear file " + fEar;
0612: logger.log(BasicLevel.ERROR, err);
0613: throw new EarServiceException(err);
0614: }
0615: }
0616:
0617: for (int i = 0; i < connectorTags.length; i++) {
0618: tmpFile = new File(fEar, connectorTags[i]);
0619: tmpFile = tmpFile.getCanonicalFile();
0620: if (!tmpFile.getPath()
0621: .startsWith(fCanonicEar.getPath())) {
0622: String err = "Error : The rar file "
0623: + connectorTags[i]
0624: + " is not inside the ear file " + fEar;
0625: logger.log(BasicLevel.ERROR, err);
0626: throw new EarServiceException(err);
0627: }
0628: }
0629:
0630: for (int i = 0; i < clientTags.length; i++) {
0631: tmpFile = new File(fEar, clientTags[i]);
0632: tmpFile = tmpFile.getCanonicalFile();
0633:
0634: if (!tmpFile.getPath()
0635: .startsWith(fCanonicEar.getPath())) {
0636: String err = "Error : The client jar file "
0637: + clientTags[i]
0638: + " is not inside the ear file " + fEar;
0639: throw new EarServiceException(err);
0640: }
0641: }
0642: } catch (IOException ioe) {
0643: String err = "Error while trying to get the canonical file of "
0644: + tmpFile;
0645: logger
0646: .log(BasicLevel.ERROR, err + " : "
0647: + ioe.getMessage());
0648: throw new EarServiceException(err, ioe);
0649: }
0650:
0651: //Changing array into JarList
0652: JarList ejbsList = new JarList(ejbTags);
0653: JarList warsList = new JarList(webTags);
0654: JarList connectorsList = new JarList(connectorTags);
0655: JarList clientsList = new JarList(clientTags);
0656:
0657: //Unpack the ear file and get the unpacked dir
0658: URL dirUnpackURL = null;
0659: try {
0660: dirUnpackURL = EarFileManager.unpackEar(earUrl[0],
0661: earRootUrl);
0662: } catch (FileManagerException e) {
0663: String err = "Error while unpacking the file '" + earUrl[0]
0664: + "'";
0665: logger.log(BasicLevel.ERROR, err + " : " + e.getMessage());
0666: throw new EarServiceException(err, e);
0667: }
0668:
0669: //the file is unpacked. Log it only if the ear is a file and not a
0670: // directory
0671: if (new File(earUrl[0].getFile()).isFile()) {
0672: try {
0673: earDeployerLog.addEntry(new File(earUrl[0].getFile()),
0674: new File(dirUnpackURL.getFile()));
0675: } catch (DeployerLogException e) {
0676: String err = "Error while adding the " + earUrl[0]
0677: + " entry in the log file";
0678: logger.log(BasicLevel.ERROR, err + " : "
0679: + e.getMessage());
0680: throw new EarServiceException(err, e);
0681: }
0682: }
0683:
0684: //We have successfully unpacked the ear file, now we analyze manifest
0685: // Class-path:
0686: EarClassPathManager earCPManager = null;
0687: try {
0688: earCPManager = new EarClassPathManager(ejbsList, warsList,
0689: dirUnpackURL);
0690: } catch (EarClassPathManagerException e) {
0691: String err = "Error while creating the Ear class path manager of the ear : '"
0692: + earUrl[0] + "'";
0693: logger.log(BasicLevel.ERROR, err + " : " + e.getMessage());
0694: throw new EarServiceException(err, e);
0695: }
0696:
0697: URL[] classpathURLs = null;
0698: //Get the urls of the ear class path manager
0699: try {
0700: classpathURLs = earCPManager.getResolvedClassPath();
0701: } catch (EarClassPathManagerException e) {
0702: String err = "Error while trying to resolve the classpath of the ejbjars and wars of the ear : '"
0703: + earUrl[0] + "'";
0704: logger.log(BasicLevel.ERROR, err + " : " + e.getMessage());
0705: throw new EarServiceException(err, e);
0706: }
0707:
0708: /*
0709: * We have the urls to load at our level We can now create our
0710: * classLoader
0711: */
0712: if (logger.isLoggable(BasicLevel.DEBUG)) {
0713: logger
0714: .log(BasicLevel.DEBUG,
0715: "Creating the EAR classLoader");
0716: }
0717: JClassLoader earClassLoader = new JClassLoader(earUrl[0]
0718: .toExternalForm(), new URL[0], appsClassLoader);
0719:
0720: //Extract the urls of the jarList
0721: URL[] jarUrls = null;
0722: URL[] warUrls = null;
0723: URL[] connectorUrls = null;
0724: URL[] clientUrls = null;
0725: try {
0726: jarUrls = ejbsList.getURLs(dirUnpackURL.toExternalForm());
0727: warUrls = warsList.getURLs(dirUnpackURL.toExternalForm());
0728: connectorUrls = connectorsList.getURLs(dirUnpackURL
0729: .toExternalForm());
0730: clientUrls = clientsList.getURLs(dirUnpackURL
0731: .toExternalForm());
0732: } catch (JarListException e) {
0733: String err = "Error while geting the Urls from jarlist of the ear : '"
0734: + earUrl[0] + "'";
0735: logger.log(BasicLevel.ERROR, err + " : " + e.getMessage());
0736: throw new EarServiceException(err, e);
0737: }
0738:
0739: //Extract context roots for wars
0740: //They are in webTags. Dump into warsContextRoots
0741: String[] warsContextRoots = new String[webTags.length];
0742: String ctxRoot = null;
0743: for (int i = 0; i < webTags.length; i++) {
0744: ctxRoot = webTags[i].getContextRoot();
0745: if (ctxRoot != null) {
0746: warsContextRoots[i] = ctxRoot;
0747: }
0748: }
0749:
0750: //Fill Alt-DD for Ejbs and Wars and Rars
0751: String altdd = null;
0752: File fAltDD = null;
0753:
0754: //Transorm the array altDDWebs into an array with the absolute URL to
0755: // the file
0756: URL[] warsAltDDs = new URL[altDDWebs.length];
0757: for (int i = 0; i < altDDWebs.length; i++) {
0758: if (altDDWebs[i] != null) {
0759: altdd = altDDWebs[i];
0760: if (altdd != null) {
0761: try {
0762: fAltDD = new File(new URL(dirUnpackURL
0763: .toExternalForm()
0764: + File.separator + altdd).getFile());
0765: warsAltDDs[i] = fAltDD.getCanonicalFile()
0766: .toURL();
0767: } catch (MalformedURLException e) {
0768: String err = "Can't build URL for alt-dd '"
0769: + altdd;
0770: logger.log(BasicLevel.ERROR, err + "': "
0771: + e.getMessage());
0772: throw new EarServiceException(err, e);
0773: } catch (IOException ioe) {
0774: String err = "Can't get canonicalFile() for the file '"
0775: + fAltDD;
0776: logger.log(BasicLevel.ERROR, err + "': "
0777: + ioe.getMessage());
0778: throw new EarServiceException(err, ioe);
0779: }
0780: }
0781: }
0782: }
0783:
0784: URL[] ejbsAltDDs = new URL[altDDEjbs.length];
0785: for (int i = 0; i < altDDEjbs.length; i++) {
0786: if (altDDEjbs[i] != null) {
0787: altdd = altDDEjbs[i];
0788: if (altdd != null) {
0789: try {
0790: fAltDD = new File(new URL(dirUnpackURL
0791: .toExternalForm()
0792: + File.separator + altdd).getFile());
0793: ejbsAltDDs[i] = fAltDD.getCanonicalFile()
0794: .toURL();
0795: } catch (MalformedURLException e) {
0796: String err = "Can't build URL for alt-dd '"
0797: + altdd;
0798: logger.log(BasicLevel.ERROR, err + "': "
0799: + e.getMessage());
0800: throw new EarServiceException(err, e);
0801: } catch (IOException ioe) {
0802: String err = "Can't get canonicalFile() for the file '"
0803: + fAltDD;
0804: logger.log(BasicLevel.ERROR, err + "': "
0805: + ioe.getMessage());
0806: throw new EarServiceException(err, ioe);
0807: }
0808: }
0809: }
0810: }
0811:
0812: URL[] connectorsAltDDs = new URL[altDDConnectors.length];
0813: for (int i = 0; i < altDDConnectors.length; i++) {
0814: if (altDDConnectors[i] != null) {
0815: altdd = altDDConnectors[i];
0816: if (altdd != null) {
0817: try {
0818: fAltDD = new File(new URL(dirUnpackURL
0819: .toExternalForm()
0820: + File.separator + altdd).getFile());
0821: connectorsAltDDs[i] = fAltDD.getCanonicalFile()
0822: .toURL();
0823: } catch (MalformedURLException e) {
0824: String err = "Can't build URL for alt-dd '"
0825: + altdd;
0826: logger.log(BasicLevel.ERROR, err + "': "
0827: + e.getMessage());
0828: throw new EarServiceException(err, e);
0829: } catch (IOException ioe) {
0830: String err = "Can't get canonicalFile() for the file '"
0831: + fAltDD;
0832: logger.log(BasicLevel.ERROR, err + "': "
0833: + ioe.getMessage());
0834: throw new EarServiceException(err, ioe);
0835: }
0836: }
0837: }
0838: }
0839:
0840: URL[] clientAltDDs = new URL[altDDClients.length];
0841: for (int i = 0; i < altDDClients.length; i++) {
0842: if (altDDClients[i] != null) {
0843: altdd = altDDClients[i];
0844: if (altdd != null) {
0845: try {
0846: fAltDD = new File(new URL(dirUnpackURL
0847: .toExternalForm()
0848: + File.separator + altdd).getFile());
0849: clientAltDDs[i] = fAltDD.getCanonicalFile()
0850: .toURL();
0851: } catch (MalformedURLException e) {
0852: String err = "Can't build URL for alt-dd '"
0853: + altdd;
0854: logger.log(BasicLevel.ERROR, err + "': "
0855: + e.getMessage());
0856: throw new EarServiceException(err, e);
0857: } catch (IOException ioe) {
0858: String err = "Can't get canonicalFile() for the file '"
0859: + fAltDD;
0860: logger.log(BasicLevel.ERROR, err + "': "
0861: + ioe.getMessage());
0862: throw new EarServiceException(err, ioe);
0863: }
0864: }
0865: }
0866: }
0867: //Extract roles name from the securityRole array
0868: String[] roleNames = new String[securityRoles.length];
0869: String affRoleNames = "";
0870: for (int i = 0; i < securityRoles.length; i++) {
0871: roleNames[i] = securityRoles[i];
0872: affRoleNames += roleNames[i] + ";";
0873: }
0874:
0875: if (logger.isLoggable(BasicLevel.DEBUG)) {
0876: logger
0877: .log(BasicLevel.DEBUG, "role names = "
0878: + affRoleNames);
0879: }
0880:
0881: /**
0882: * Now this is the deployment step with sending
0883: * + rars to the rar service
0884: * + jars to the ejb service
0885: * + wars to the web container service
0886: * + jars and wars to web services service
0887: */
0888:
0889: /**
0890: * Ejb ClassLoader is needed for WebServices deployment so We create it
0891: * in advance ...
0892: */
0893: // Set the list of the ejb-jar, war and clients that can do an ejb-link in this
0894: // ear application. This array can be empty.
0895: // The alternate urls are given
0896: EjbManagerWrapper.setAvailableEjbJarsAndAltDDs(earClassLoader,
0897: jarUrls, ejbsAltDDs);
0898: WebManagerWrapper.setAltDD(earClassLoader, warUrls, warsAltDDs);
0899: ClientManagerWrapper.setAltDD(earClassLoader, clientUrls,
0900: clientAltDDs);
0901:
0902: // Construct the ejb classloader for all the ejb-jars of the same
0903: // ear application. Because there is one ejb classloader for all
0904: // the ejb-jars of the same ear application.
0905: URL[] urls = new URL[jarUrls.length + classpathURLs.length];
0906: System.arraycopy(jarUrls, 0, urls, 0, jarUrls.length);
0907: System.arraycopy(classpathURLs, 0, urls, jarUrls.length,
0908: classpathURLs.length);
0909:
0910: // Set the list of the rars that can be referenced in this
0911: // ear application. This array can be empty.
0912: // The alternate urls are given
0913:
0914: //rarDDManager.setAvailableRarsAndAltDDs(earClassLoader, connectorUrls,
0915: // connectorsAltDDs);
0916:
0917: //Only if the connectorUrls is not empty
0918: //And if the service is started
0919: if (resourceService != null && (connectorUrls.length > 0)) {
0920: try {
0921: CompNamingContext contctx = null;
0922: try {
0923: contctx = new CompNamingContext(dirUnpackURL
0924: .getFile());
0925: contctx.rebind("earUrl", earUrl[0]);
0926: contctx.rebind("urls", connectorUrls);
0927: contctx.rebind("earClassLoader", earClassLoader);
0928: contctx.rebind("altDDs", connectorsAltDDs);
0929: } catch (NamingException e) {
0930: String err = "Can not bind params for the resource service, Can't deploy rars ";
0931: throw new ResourceServiceException(err, e);
0932: }
0933: resourceService.deployRars(contctx);
0934: } catch (ServiceException e) {
0935: String err = "Error during the deployment of the rars files of the Ear file "
0936: + fileName;
0937: logger.log(BasicLevel.ERROR, err + "': "
0938: + e.getMessage());
0939: //remove DDesc
0940: //resourceService.removeCache(earClassLoader);
0941: throw new EarServiceException(err, e);
0942: }
0943: }
0944:
0945: // Check GenIC has to be done after RAR deployment because
0946: // RAR resources (classes, ...) are added to the Application ClassLoader
0947: // only at deploy time.
0948:
0949: /**
0950: * Check that GenIC was applied on ejb-jar prior to sending them to EJB service.
0951: * As classloader is defined in this service, classes after will not be taken
0952: * into account. So GenIC should be called before creating Classloader.
0953: */
0954: if (jarUrls.length > 0 && ejbService != null) {
0955:
0956: URL[] compilationURLs = null;
0957: // if we have some resources, we have to use them in GenIC compilation
0958: if (resourceService != null) {
0959: // get the resources from the ear classloader and apps classloader
0960:
0961: // content of the ear loader (application wide resources)
0962: URL[] myApplicationJars = earClassLoader.getURLs();
0963: // content of the apps loader (system wide resources)
0964: URL[] appsJars = ((URLClassLoader) earClassLoader
0965: .getParent()).getURLs();
0966:
0967: // merge the 3 Set of URLs
0968: compilationURLs = new URL[myApplicationJars.length
0969: + appsJars.length + urls.length];
0970:
0971: System.arraycopy(urls, 0, compilationURLs, 0,
0972: urls.length);
0973: System.arraycopy(appsJars, 0, compilationURLs,
0974: urls.length, appsJars.length);
0975: System.arraycopy(myApplicationJars, 0, compilationURLs,
0976: urls.length + appsJars.length,
0977: myApplicationJars.length);
0978:
0979: }
0980:
0981: // Check GenIC :
0982: for (int i = 0; i < jarUrls.length; i++) {
0983: ejbService.checkGenIC(jarUrls[i].getFile(),
0984: compilationURLs);
0985: }
0986: }
0987:
0988: URLClassLoader ejbClassLoader;
0989: try {
0990: ejbClassLoader = new EjbJarClassLoader(urls, earClassLoader);
0991: } catch (IOException ioe) {
0992: String err = "Cannot Create EJB ClassLoader for EAR '"
0993: + fileName + "'";
0994: logger
0995: .log(BasicLevel.ERROR, err + " : "
0996: + ioe.getMessage());
0997: throw new EarServiceException(err, ioe);
0998: }
0999:
1000: // Only if the WebServicesService is started
1001: if (wsService != null) {
1002: try {
1003: Hashtable ctxRoots = new Hashtable();
1004: for (int w = 0; w < webTags.length; w++) {
1005: ctxRoots.put(warUrls[w], webTags[w]
1006: .getContextRoot());
1007: }
1008: CompNamingContext contctx = null;
1009: try {
1010: contctx = new CompNamingContext(dirUnpackURL
1011: .getFile());
1012: contctx.rebind("unpackDir", dirUnpackURL
1013: .toExternalForm());
1014: contctx.rebind("jarUrls", jarUrls);
1015: contctx.rebind("warUrls", warUrls);
1016: contctx.rebind("earURL", earUrl[0]);
1017: contctx.rebind("ejbClassLoader", ejbClassLoader);
1018: contctx.rebind("earClassLoader", earClassLoader);
1019: contctx.rebind("warCtxRootMapping", ctxRoots);
1020: } catch (NamingException e) {
1021: String err = "Cannot bind params for the WebServices service, Can't deploy Web Services Endpoints ";
1022: throw new WSServiceException(err, e);
1023: }
1024: wsService.deployWebServices(contctx);
1025: } catch (ServiceException se) {
1026: String err = "Error during the deployment of the WebServices of the Ear file "
1027: + fileName;
1028: logger.log(BasicLevel.ERROR, err + " : "
1029: + se.getMessage());
1030: wsService.removeCache(earClassLoader);
1031: try {
1032: if (logger.isLoggable(BasicLevel.DEBUG)) {
1033: logger.log(BasicLevel.DEBUG,
1034: "Undeploying Rars of the ear "
1035: + fileName);
1036: }
1037: if (resourceService != null
1038: && connectorUrls.length > 0) {
1039: // remove Resource
1040: resourceService.unDeployRars(connectorUrls,
1041: earUrl[0]);
1042: }
1043: } catch (ServiceException se2) {
1044: err = "Error during the undeployment of the rars files of the Ear file "
1045: + fileName;
1046: logger.log(BasicLevel.ERROR, err + "': "
1047: + se2.getMessage());
1048: }
1049:
1050: throw new EarServiceException(err, se);
1051: }
1052: }
1053:
1054: // ejbClassLoader created above
1055:
1056: //Only if the jarUrls is not empty
1057: //And if the service is started
1058: if (ejbService != null && (jarUrls.length > 0)) {
1059: try {
1060: CompNamingContext contctx = null;
1061: try {
1062: contctx = new CompNamingContext(dirUnpackURL
1063: .getFile());
1064: contctx.rebind("earRootUrl", dirUnpackURL);
1065: contctx.rebind("earUrl", earUrl[0]);
1066: contctx.rebind("jarURLs", jarUrls);
1067: contctx.rebind("earClassLoader", earClassLoader);
1068: contctx.rebind("ejbClassLoader", ejbClassLoader);
1069: contctx.rebind("roleNames", roleNames);
1070: } catch (NamingException e) {
1071: String err = "Can not bind params for the ejb service, Can't deploy jars ";
1072: throw new EarServiceException(err, e);
1073: }
1074: ejbService.deployJars(contctx);
1075: } catch (ServiceException e) {
1076: String err = "Error during the deployment of the jars files of the Ear file "
1077: + fileName;
1078: logger.log(BasicLevel.ERROR, err + "': "
1079: + e.getMessage());
1080: //remove DDesc
1081: ejbService.removeCache(earClassLoader);
1082: // Remove the deployed rars
1083: if (resourceService != null && connectorUrls.length > 0) {
1084: // remove Resource
1085: resourceService.unDeployRars(connectorUrls,
1086: earUrl[0]);
1087: }
1088: throw new EarServiceException(err, e);
1089: }
1090: }
1091:
1092: /*
1093: * We have deploy the ejb-jar files if the service is active And we have
1094: * the ejbClassLoader
1095: */
1096:
1097: // Link policy context of EJBs and Webs components
1098: linkPolicyObjects(earDD.getUserToRoleMapping(), jarUrls,
1099: warUrls, warsContextRoots);
1100: // commit ejb policy context (make them available for checking security)
1101: commitEJBPolicyObjects(jarUrls);
1102:
1103: /*
1104: * We're going to deploy wars Parent ClassLoader for web container is
1105: * ejbclassloader if ejbService is active, and a classloader with the
1106: * visibility of jar file if ejbservice is not active.
1107: */
1108:
1109: ClassLoader parentWarClassLoader = ejbClassLoader;
1110:
1111: //Only if the warUrls is not empty
1112: //And if the service is started
1113: if (webContainerService != null && (warUrls.length > 0)) {
1114: try {
1115: CompNamingContext contctx = null;
1116: try {
1117: contctx = new CompNamingContext(dirUnpackURL
1118: .getFile());
1119: contctx.rebind("earURL", earUrl[0]);
1120: contctx.rebind("urls", warUrls);
1121: contctx.rebind("parentClassLoader",
1122: parentWarClassLoader);
1123: contctx.rebind("earClassLoader", earClassLoader);
1124: contctx.rebind("altDDs", warsAltDDs);
1125: contctx.rebind("contextRoots", warsContextRoots);
1126: } catch (NamingException e) {
1127: String err = "Can not bind params for the web container service, Can't deploy wars ";
1128: throw new EarServiceException(err, e);
1129: }
1130: webContainerService.deployWars(contctx);
1131:
1132: } catch (JWebContainerServiceException e) {
1133: String err = "Error during the deployment of the wars file of the Ear file "
1134: + fileName;
1135: logger.log(BasicLevel.ERROR, err + "': "
1136: + e.getMessage());
1137: //remove DDesc
1138: webContainerService.removeCache(earClassLoader);
1139: err = "Undeploy the jars loaded from this ear";
1140: if (logger.isLoggable(BasicLevel.DEBUG)) {
1141: logger.log(BasicLevel.DEBUG, err);
1142: }
1143: try {
1144: if (ejbService != null && (jarUrls.length > 0)) {
1145: //remove DDesc
1146: ejbService.removeCache(earClassLoader);
1147: //remove the ejbs
1148: ejbService.unDeployJars(jarUrls);
1149: }
1150: // Remove the deployed rars
1151: if (resourceService != null
1152: && connectorUrls.length > 0) {
1153: // remove Resource
1154: resourceService.unDeployRars(connectorUrls,
1155: earUrl[0]);
1156: }
1157: } catch (ServiceException se) {
1158: err = "Error during the undeployment of the jars file of the Ear file "
1159: + fileName;
1160: logger.log(BasicLevel.ERROR, err + "': "
1161: + se.getMessage());
1162: throw new EarServiceException(err, e);
1163: }
1164:
1165: throw new EarServiceException(err, e);
1166: }
1167: }
1168:
1169: // Commit JACC policy configuration objects of WebApp components.
1170: commitWebBPolicyObjects(warUrls, warsContextRoots);
1171:
1172: if (logger.isLoggable(BasicLevel.DEBUG)) {
1173: logger.log(BasicLevel.DEBUG,
1174: "We store the rars/wars/jars associated to the url :"
1175: + earUrl[0]);
1176: }
1177:
1178: // Complete the Deployment of the WebServices
1179: // Only if the WebServicesService is started
1180: if (wsService != null) {
1181: try {
1182: CompNamingContext contctx = null;
1183: try {
1184: contctx = new CompNamingContext(earRootUrl
1185: .getFile());
1186: contctx
1187: .rebind(
1188: AbsWebServicesServiceImpl.CLASSLOADER_CTX_PARAM,
1189: earClassLoader);
1190: ObjectName name = J2eeObjectName.J2EEApplication(
1191: getDomainName(), getJonasServerName(),
1192: buildJ2eeApplicationName(earUrl[0]));
1193: contctx
1194: .rebind(
1195: WebServicesService.PARENT_OBJECTNAME_CTX_PARAM,
1196: name);
1197: contctx.rebind(
1198: WebServicesService.ISINEAR_CTX_PARAM,
1199: Boolean.TRUE);
1200:
1201: } catch (NamingException e) {
1202: String err = "Can not bind params for the WebServices service, "
1203: + "can't complete deployment of Web Services Endpoints";
1204: throw new JWebContainerServiceException(err, e);
1205: }
1206: wsService.completeWSDeployment(contctx);
1207: } catch (ServiceException se) {
1208: String err = "Error during the deployment of the WebServices of the Ear file '"
1209: + earRootUrl + "'";
1210: logger.log(BasicLevel.ERROR, err + " : "
1211: + se.getMessage());
1212: try {
1213: if (logger.isLoggable(BasicLevel.DEBUG)) {
1214: logger
1215: .log(BasicLevel.DEBUG,
1216: "Undeploy the WebApps loaded from this ear");
1217: }
1218: if (webContainerService != null
1219: && (warUrls.length > 0)) {
1220: //remove DDesc
1221: webContainerService.removeCache(earClassLoader);
1222: //remove the webapps
1223: webContainerService.unDeployWars(warUrls);
1224: }
1225: if (logger.isLoggable(BasicLevel.DEBUG)) {
1226: logger
1227: .log(BasicLevel.DEBUG,
1228: "Undeploy the EjbJars loaded from this ear");
1229: }
1230: if (ejbService != null && (jarUrls.length > 0)) {
1231: //remove DDesc
1232: ejbService.removeCache(earClassLoader);
1233: //remove the ejbs
1234: ejbService.unDeployJars(jarUrls);
1235: }
1236: // Remove the deployed rars
1237: if (logger.isLoggable(BasicLevel.DEBUG)) {
1238: logger
1239: .log(BasicLevel.DEBUG,
1240: "Undeploy the Resources loaded from this ear");
1241: }
1242: if (resourceService != null
1243: && connectorUrls.length > 0) {
1244: // remove Resource
1245: resourceService.unDeployRars(connectorUrls,
1246: earUrl[0]);
1247: }
1248: } catch (ServiceException se2) {
1249: err = "Error during the undeployment of the webapps/ejbjars/rars file of the Ear file "
1250: + fileName;
1251: logger.log(BasicLevel.ERROR, err + "': "
1252: + se2.getMessage());
1253: }
1254: throw new JWebContainerServiceException(err, se);
1255: }
1256: }
1257:
1258: // Management support
1259: // ------------------
1260:
1261: // Build the 'name' used to construct the J2EEApplication ObjectName
1262: String sJ2EEApplicationName = buildJ2eeApplicationName(earUrl[0]);
1263:
1264: // Create AppClientModule MBeans first
1265: AppClientModule[] appClientModules = null;
1266: ObjectName[] onAppClientModules = null;
1267: if (clientUrls.length > 0) {
1268: appClientModules = new AppClientModule[clientUrls.length];
1269: onAppClientModules = new ObjectName[clientUrls.length];
1270: }
1271:
1272: String moduleName = null;
1273: String moduleFileName = null;
1274: String moduleDD = null;
1275: String jonasModuleDD = null;
1276: ClientContainerDeploymentDesc clientContainerDD = null;
1277: for (int i = 0; i < clientUrls.length; i++) {
1278: ClassLoader moduleCL = null;
1279: try {
1280: moduleCL = new ClientClassLoader(clientUrls[i],
1281: ejbClassLoader);
1282: } catch (IOException ioe) {
1283: // fail case :
1284: // we use the ejbjar classloader, but the descriptor loading will fail
1285: moduleCL = ejbClassLoader;
1286: // TODO Find a better Exception handling ?
1287: }
1288: moduleName = EJBServiceImpl
1289: .buildEJBModuleName(clientUrls[i]);
1290: moduleFileName = clientUrls[i].getPath();
1291: try {
1292: clientContainerDD = ClientManagerWrapper
1293: .getDeploymentDesc(clientUrls[i], moduleCL,
1294: earClassLoader);
1295: moduleDD = clientContainerDD.getXmlContent();
1296: jonasModuleDD = clientContainerDD.getJOnASXmlContent();
1297: } catch (ClientContainerDeploymentDescException e) {
1298: // make debug trace
1299: String err = "Cannot read the deployment descriptors ': "
1300: + clientUrls[i] + "'" + e.toString();
1301: logger.log(BasicLevel.ERROR, err, e);
1302: }
1303: onAppClientModules[i] = J2eeObjectName.getAppClientModule(
1304: getDomainName(), getJonasServerName(),
1305: sJ2EEApplicationName, moduleName);
1306: appClientModules[i] = new AppClientModule(
1307: onAppClientModules[i].toString(), moduleFileName,
1308: moduleDD, jonasModuleDD);
1309: }
1310: URL clientUrl = null;
1311: try {
1312: if (mbeanServer != null) {
1313: Registry oRegistry = JonasMBeanTools.getRegistry();
1314: ManagedBean oManaged = null;
1315: ModelMBean oMBean = null;
1316: // Register AppClientModule MBeans
1317: if (appClientModules != null) {
1318: oManaged = oRegistry
1319: .findManagedBean("AppClientModule");
1320: for (int i = 0; i < appClientModules.length; i++) {
1321: clientUrl = clientUrls[i];
1322: oMBean = oManaged
1323: .createMBean(appClientModules[i]);
1324: mbeanServer.registerMBean(oMBean,
1325: onAppClientModules[i]);
1326: }
1327: }
1328: }
1329: } catch (Exception eare) {
1330: logger.log(BasicLevel.ERROR,
1331: "Can not register the MBean for the client jar "
1332: + clientUrl, eare);
1333: }
1334:
1335: // Remove the Deployment descriptors
1336: if (ejbService != null) {
1337: ejbService.removeCache(earClassLoader);
1338: }
1339:
1340: if (webContainerService != null) {
1341: webContainerService.removeCache(earClassLoader);
1342: }
1343:
1344: if (wsService != null) {
1345: wsService.removeCache(earClassLoader);
1346: }
1347:
1348: // Create J2EEApplication MBeans
1349: ObjectName onEar = J2eeObjectName.J2EEApplication(
1350: getDomainName(), getJonasServerName(),
1351: sJ2EEApplicationName);
1352: // Store the ejb-jar, war and the rar urls associated with the ear URL
1353: // in case of success deploy
1354: Ear ear = new Ear(onEar.toString(), sJ2EEApplicationName,
1355: dirUnpackURL.getFile(), earUrl[0], earDD
1356: .getXmlContent(), jarUrls, warUrls,
1357: connectorUrls);
1358:
1359: try {
1360: if (mbeanServer != null) {
1361: Registry oRegistry = JonasMBeanTools.getRegistry();
1362: ManagedBean oManaged = oRegistry
1363: .findManagedBean("J2EEApplication");
1364: ModelMBean oMBean = oManaged.createMBean(ear);
1365: // Register Ear MBean (all the J2EEModule MBeans are already registered
1366: mbeanServer.registerMBean(oMBean, onEar);
1367: }
1368: } catch (Exception eare) {
1369: logger.log(BasicLevel.ERROR,
1370: "Can not register the MBean for the ear "
1371: + earUrl[0], eare);
1372: }
1373:
1374: ears.put(earUrl[0], ear);
1375:
1376: logger.log(BasicLevel.INFO, "Ear " + earUrl[0] + " available.");
1377:
1378: //set the timestamp dir
1379: File dirUnpackFile = new File(dirUnpackURL.getFile());
1380: dirUnpackFile.setLastModified((new Date()).getTime());
1381:
1382: // return ObjectName of the J2EEApplication MBean
1383: return onEar.toString();
1384: }
1385:
1386: /**
1387: * Deploy an ear with its given fileName
1388: * @param fileName file to deploy (ear)
1389: * @return The ObjectName of the J2EE Application MBean associated to the
1390: * deployed EAR
1391: * @throws Exception if the deployment of the EAR failed.
1392: * @see org.objectweb.jonas.ear.EarService#deployEar(java.lang.String)
1393: */
1394: public String deployEar(String fileName) throws Exception {
1395: return deployEarMBean(fileName);
1396: }
1397:
1398: /**
1399: * Deploy an EAR by delegating the operation to the deployEar() method. This
1400: * is used by jonasAdmin management application.
1401: * @param fileName the fileName of the ear which must be be deployed.
1402: * @return The ObjectName of the J2EE Application MBean associated to the
1403: * deployed EAR
1404: * @throws Exception if the deployment of the EAR failed.
1405: */
1406: public String deployEarMBean(String fileName) throws Exception {
1407: Context ctx = null;
1408: String mbeanOn = null;
1409: try {
1410: ctx = new CompNamingContext(fileName);
1411: ctx.rebind("filename", fileName);
1412: } catch (NamingException e) {
1413: String err = "Error when deploying the ear file ";
1414: logger.log(BasicLevel.ERROR, err, e);
1415: throw e;
1416: }
1417: try {
1418: mbeanOn = deployEar(ctx);
1419: } catch (ServiceException e) {
1420: logger.log(BasicLevel.ERROR, "Cannot deploy file '"
1421: + fileName + "'");
1422: throw new Exception(
1423: "Cannot deploy file '" + fileName + "'", e);
1424: }
1425: return mbeanOn;
1426: }
1427:
1428: /**
1429: * Start the EAR service.
1430: * @throws ServiceException if the startup failed.
1431: */
1432: protected void doStart() throws ServiceException {
1433:
1434: //url
1435: URL earApps = null;
1436: try {
1437: earApps = new File(WORK_APPS_DIR + File.separator
1438: + getJonasServerName()).toURL();
1439: } catch (MalformedURLException mue) {
1440: throw new ServiceException(
1441: "Error when trying to get the URL of the jonasroot/apps directory",
1442: mue);
1443: }
1444:
1445: File fLog = new File(earApps.getFile() + File.separator
1446: + getJonasServerName() + ".log");
1447: if (!fLog.exists()) {
1448: try {
1449: //create
1450: fLog.getParentFile().mkdirs();
1451: fLog.createNewFile();
1452: } catch (IOException e) {
1453: throw new ServiceException("cannot create the log file"
1454: + fLog, e);
1455: }
1456: }
1457:
1458: //get the logger
1459: try {
1460: earDeployerLog = new DeployerLog(fLog);
1461: } catch (DeployerLogException e) {
1462: throw new ServiceException("Can not get an EarDeployerLog",
1463: e);
1464: }
1465:
1466: // create the ear deployment work file control task
1467: EarCleanTask earCleanTask = new EarCleanTask(earApps,
1468: earDeployerLog);
1469:
1470: //get the cleaner ref
1471: workCleaner = WorkCleaner.getInstance();
1472:
1473: // add the ear deployment work file control task
1474: try {
1475: workCleaner.registerTask(earCleanTask);
1476: } catch (CleanerException ce) {
1477: throw new ServiceException(
1478: "Cannot register the EAR clean task", ce);
1479: }
1480:
1481: // force the cleaning now
1482: workCleaner.executeTasks();
1483:
1484: // Deploy all ear which are in descriptors section
1485: Iterator it = earNames.iterator();
1486: while (it.hasNext()) {
1487: String fileName = (String) it.next();
1488: Context contctx = null;
1489: try {
1490: contctx = new CompNamingContext(fileName);
1491: contctx.rebind("filename", fileName);
1492: } catch (NamingException e) {
1493: throw new ServiceException(
1494: "Cannot start the EarService", e);
1495: }
1496: try {
1497: deployEar(contctx);
1498: } catch (EarServiceException ese) {
1499: String err = "Cannot deploy the file '" + fileName
1500: + "' : " + ese.getMessage();
1501: logger.log(BasicLevel.WARN, err);
1502: } catch (Exception ue) {
1503: String err = "Cannot deploy the file (unexpected exception) '"
1504: + fileName + "' : " + ue.getMessage();
1505: logger.log(BasicLevel.WARN, err);
1506: }
1507: }
1508:
1509: try {
1510: // Register EarService MBean : EarServiceImplMBean
1511: if (mbeanServer != null) {
1512: mbeanServer.registerMBean(this , JonasObjectName
1513: .earService());
1514: }
1515: } catch (InstanceAlreadyExistsException iae) {
1516: throw new ServiceException(
1517: "Cannot start the EarService Already Exists", iae);
1518: } catch (MBeanRegistrationException mbre) {
1519: throw new ServiceException(
1520: "Cannot start the EarService (MBean registration error)",
1521: mbre);
1522: } catch (NotCompliantMBeanException ncmbe) {
1523: throw new ServiceException(
1524: "Cannot start the EarService (MBean Not compliant error)",
1525: ncmbe);
1526: }
1527: }
1528:
1529: /**
1530: * Undeploy an EAR by sending the request to the EJB container and to the
1531: * WEB container and the Resource service.
1532: * @param ctx the context which contains the configuration in order to
1533: * undeploy an EAR.
1534: * @throws EarServiceException if the undeployment of the EAR failed.
1535: */
1536: public void unDeployEar(Context ctx) throws EarServiceException {
1537:
1538: //Get the ear url param which we want to undeploy
1539: URL earUrl = null;
1540: try {
1541: earUrl = (URL) ctx.lookup("filename");
1542: } catch (NamingException e) {
1543: throw new EarServiceException(
1544: "Trying to remove the ear file but there is no filename specified",
1545: e);
1546: }
1547:
1548: //This ear is in loaded EARs files ?
1549: Ear ear = (Ear) ears.get(earUrl);
1550:
1551: //Not loaded
1552: if (ear == null) {
1553: throw new EarServiceException(
1554: "Trying to remove the ear file "
1555: + earUrl.getFile()
1556: + " but this file was not found in the loaded Ear files");
1557: }
1558:
1559: //undeploy wars if the web container service is started
1560: URL[] warsToUndeploy = ear.getWars();
1561: if (webContainerService != null && (warsToUndeploy.length > 0)) {
1562: webContainerService.unDeployWars(warsToUndeploy);
1563: }
1564:
1565: //undeploy jars if the ejb service is started
1566: URL[] jarsToUndeploy = ear.getEjbJars();
1567: if (ejbService != null && (jarsToUndeploy.length > 0)) {
1568: ejbService.unDeployJars(jarsToUndeploy);
1569: }
1570:
1571: //undeploy rars if the resource service is started
1572: URL[] rarsToUndeploy = ear.getRars();
1573: if (resourceService != null && (rarsToUndeploy.length > 0)) {
1574: resourceService.unDeployRars(rarsToUndeploy, earUrl);
1575: }
1576:
1577: File f = new File(earUrl.getFile());
1578: //Undeploy successful, we remove the ear
1579:
1580: //Only if there is no Exception !
1581: ears.remove(earUrl);
1582: //unregister mbean
1583: if (mbeanServer != null) {
1584: // Build the ObjectName if the ear's MBea
1585: //String sJ2EEApplicationName = buildJ2eeApplicationName(earUrl);
1586: //ObjectName onEar =
1587: // J2eeObjectName.J2EEApplication(getDomainName(),
1588: // getJonasServerName(), sJ2EEApplicationName);
1589: // Un-regsiter the MBean
1590: try {
1591: // unregister J2EEApplication
1592: ObjectName onJ2EEApplication = ObjectName
1593: .getInstance(ear.getObjectName());
1594: String appName = onJ2EEApplication
1595: .getKeyProperty("name");
1596: String domainName = onJ2EEApplication.getDomain();
1597: String serverName = onJ2EEApplication
1598: .getKeyProperty("J2EEServer");
1599: mbeanServer.unregisterMBean(onJ2EEApplication);
1600: // ubregister the AppClientModules, if any
1601: ObjectName onAppClientModules = J2eeObjectName
1602: .getAppClientModules(domainName, serverName,
1603: appName);
1604: List onList = J2eeObjectName
1605: .queryObjectNames(onAppClientModules);
1606: for (int i = 0; i < onList.size(); i++) {
1607: mbeanServer.unregisterMBean((ObjectName) onList
1608: .get(i));
1609: }
1610: } catch (Exception e) {
1611: logger.log(BasicLevel.ERROR,
1612: "Cannot remove the MBean for the ear "
1613: + earUrl.getFile(), e);
1614: }
1615: }
1616:
1617: logger.log(BasicLevel.INFO, "Ear " + f.getName()
1618: + " no longer available.");
1619:
1620: }
1621:
1622: /**
1623: * Undeploy an EAR by delegating the operation to the unDeployEar() method.
1624: * This is used for JMX management.
1625: * @param fileName the fileName of the ear which must be be undeployed.
1626: * @throws Exception if the undeployment of the EAR failed.
1627: * @see org.objectweb.jonas.ear.EarService#unDeployEar(java.lang.String)
1628: */
1629: public void unDeployEar(String fileName) throws Exception {
1630: unDeployEarMBean(fileName);
1631: }
1632:
1633: /**
1634: * Undeploy an EAR by delegating the operation to the unDeployEar() method.
1635: * This is used for JMX management.
1636: * @param fileName the fileName of the ear which must be be undeployed.
1637: * @throws Exception if the undeployment of the EAR failed.
1638: */
1639: public void unDeployEarMBean(String fileName) throws Exception {
1640:
1641: /*
1642: * We have only the name of the file, not its associated path, so we
1643: * look in the current directory and in the ear applications directory
1644: */
1645:
1646: //We check if the url exists in the hashtable
1647: //compare: First in the current dir, after in the apps directory
1648: URL url = null;
1649: URL earUrl = null;
1650: boolean found = false;
1651: try {
1652: Enumeration e = ears.keys();
1653: url = new File(fileName).getCanonicalFile().toURL();
1654: while (e.hasMoreElements() && !found) {
1655: earUrl = (URL) e.nextElement();
1656: if (earUrl.equals(url)) {
1657: //We have found
1658: found = true;
1659: }
1660: }
1661:
1662: if (fileName.toLowerCase().endsWith(".ear") && !found) {
1663: // In case of the name is an ear check also in
1664: // the JONAS_BASE/apps directory
1665: String earFileName = APPS_DIR + File.separator
1666: + fileName;
1667: e = ears.keys();
1668: url = new File(earFileName).getCanonicalFile().toURL();
1669: while (e.hasMoreElements() && !found) {
1670: earUrl = (URL) e.nextElement();
1671: if (earUrl.equals(url)) {
1672: //We have found
1673: found = true;
1674: }
1675: }
1676: }
1677: if (!found) {
1678: String err = "Cannot undeploy the ear '" + fileName
1679: + "', it is not deployed.";
1680: logger.log(BasicLevel.ERROR, err);
1681: throw new Exception(err);
1682: }
1683: } catch (MalformedURLException mue) {
1684: String err = "Error when trying to get the url from"
1685: + fileName;
1686: logger.log(BasicLevel.ERROR, err);
1687: throw new Exception(err, mue);
1688: } catch (IOException ioe) {
1689: String err = "Error when trying to get the canonical file from "
1690: + fileName;
1691: logger.log(BasicLevel.ERROR, err + ioe.getMessage());
1692: throw new Exception(err, ioe);
1693: }
1694:
1695: //We've got the file, now we bind the params
1696: Context ctx = null;
1697: try {
1698: ctx = new CompNamingContext(fileName);
1699: //The fileName is an url
1700: ctx.rebind("filename", url);
1701: } catch (NamingException e) {
1702: String err = "Error when binding parameters";
1703: logger.log(BasicLevel.ERROR, err + e.getMessage());
1704: throw new Exception(err, e);
1705: }
1706:
1707: //Call the function
1708: try {
1709: unDeployEar(ctx);
1710: } catch (EarServiceException e) {
1711: throw new Exception(e);
1712: }
1713:
1714: }
1715:
1716: /**
1717: * @return current number of ears deployed in the JOnAS server
1718: */
1719: public Integer getCurrentNumberOfEars() {
1720: return new Integer(ears.size());
1721: }
1722:
1723: /**
1724: * Return the list of installed Applications. The EAR files or the
1725: * directories with expanded Applications are searched in JONAS_BASE/apps
1726: * and all Applications directories 'autoload'.
1727: * @return The list of EAR files or the directories with expanded
1728: * Applications found
1729: * @throws Exception if the list can't be retrieved
1730: */
1731: public List getInstalledEars() throws Exception {
1732: // get EAR files found in JONAS_BASE/apps
1733: ArrayList al = JModule.getInstalledContainersInDir(APPS_DIR,
1734: JModule.EAR_EXTENSION, JModule.EAR_CHILD_DIR,
1735: JModule.EAR_CONFIRM_FILE);
1736: // get EAR files found in all autoload directories
1737: Iterator it = autoloadDirectories.iterator();
1738: while (it.hasNext()) {
1739: String name = (String) it.next();
1740: al.addAll(JModule.getInstalledContainersInDir(name,
1741: JModule.EAR_EXTENSION, JModule.EAR_CHILD_DIR,
1742: JModule.EAR_CONFIRM_FILE));
1743: }
1744: return al;
1745: }
1746:
1747: /**
1748: * This method is added temporarily. It will disapear when Ears will have
1749: * their associated MBeans (when Ears will become manageable)
1750: * @return the names of the ears currently deployed in the JOnAS server
1751: */
1752: public Set getEarNames() {
1753: HashSet names = new HashSet();
1754: URL earUrl = null;
1755: for (Enumeration e = ears.keys(); e.hasMoreElements();) {
1756: earUrl = (URL) e.nextElement();
1757: names.add(earUrl.getFile());
1758: }
1759: return names;
1760: }
1761:
1762: /**
1763: * Add recursively the ears of the specified directory. If the dir has a
1764: * relative path, this path is relative from where the Application Server is
1765: * launched. If the dir is not found it will be searched in
1766: * $JONAS_BASE/apps/ directory.
1767: * @param dirPath the path to the directory containing the ears to load.
1768: */
1769: private void addEars(String dirPath) {
1770: boolean found = false;
1771:
1772: // Look the directory relative to the $JONAS_BASE/apps directory
1773: File dir = new File(APPS_DIR + File.separator + dirPath);
1774: found = dir.isDirectory();
1775:
1776: if (found) {
1777: addEarsFrom(dir);
1778: } else {
1779: String err = "Warning: Cannot load dir: '" + dirPath + "' ";
1780: err += "is not a directory or directory doesn't exist";
1781: logger.log(BasicLevel.WARN, err);
1782: }
1783: }
1784:
1785: /**
1786: * Add the ears of the specified directory.
1787: * @param dir the directory from which the ears are loaded.
1788: * @throws EarServiceException if the argument is not a directory
1789: */
1790: private void addEarsFrom(File dir) throws EarServiceException {
1791: try {
1792: if (dir.isDirectory()) {
1793: File[] files = dir.listFiles();
1794: for (int i = 0; i < files.length; i++) {
1795: if (files[i].getPath().toLowerCase().endsWith(
1796: ".ear")) {
1797: earNames.add(files[i].getCanonicalPath());
1798: } else {
1799: if (files[i].isDirectory()) {
1800: addEarsFrom(files[i]);
1801: }
1802: }
1803: }
1804: } else {
1805: String err = "Cannot load dir: '" + dir.getPath();
1806: err += "' is not a directory";
1807: logger.log(BasicLevel.ERROR, err);
1808: throw new EarServiceException(err);
1809: }
1810: } catch (IOException e) {
1811: String err = "Invalid file name '" + dir.getPath();
1812: logger.log(BasicLevel.ERROR, err);
1813: throw new EarServiceException(err, e);
1814: }
1815: }
1816:
1817: /**
1818: * Test if the specified filename is already deployed or not. This method
1819: * is a management method provided by the EarServerice MBean.
1820: * @param fileName the name of the ear file.
1821: * @return true if the ear is deployed, else false.
1822: */
1823: public boolean isEarLoaded(String fileName) {
1824:
1825: URL url = null;
1826: boolean isLoaded = false;
1827: try {
1828: // Absolute filename
1829: try {
1830: url = new File(fileName).getCanonicalFile().toURL();
1831: //Check if the ear is already deployed or not
1832: if (ears.get(url) != null) {
1833: isLoaded = true;
1834: } else {
1835: // Not found force to test in relative Apps directory
1836: url = null;
1837: }
1838: } catch (Exception e) {
1839: url = null;
1840: }
1841: // Relative filename
1842: if (url == null) {
1843: url = new File(APPS_DIR + File.separator + fileName)
1844: .getCanonicalFile().toURL();
1845: //Check if the ear is already deployed or not
1846: if (ears.get(url) != null) {
1847: isLoaded = true;
1848: }
1849: }
1850: } catch (Exception e) {
1851: String err = "Can not found if the ear is deployed or not";
1852: logger.log(BasicLevel.ERROR, err);
1853: return false;
1854: }
1855:
1856: return isLoaded;
1857: }
1858:
1859: /**
1860: * Test if the specified filename is already deployed or not. This
1861: * method is defined in the EarService interface.
1862: * @param fileName the name of the ear file.
1863: * @return true if the ear is deployed, else false.
1864: */
1865: public Boolean isEarDeployed(String fileName) {
1866: return new Boolean(isEarLoaded(fileName));
1867: }
1868:
1869: /**
1870: * Test if the specified unpack name is already deployed or not. This
1871: * method is defined in the EarService interface.
1872: * @param unpackName the name of the ear file.
1873: * @return true if the ear is deployed, else false.
1874: */
1875: public boolean isEarDeployedByUnpackName(String unpackName) {
1876: if (logger.isLoggable(BasicLevel.DEBUG)) {
1877: logger.log(BasicLevel.DEBUG, "entering for unpackName= "
1878: + unpackName);
1879: }
1880: // for each ear loaded
1881: Enumeration lc = ears.elements();
1882: while (lc.hasMoreElements()) {
1883: Ear ear = (Ear) lc.nextElement();
1884:
1885: // get unpack name of the ear
1886: String deployedUnpackName = new File(ear.getUnpackName())
1887: .getName();
1888: if (logger.isLoggable(BasicLevel.DEBUG)) {
1889: logger.log(BasicLevel.DEBUG, "deployedUnpackName="
1890: + deployedUnpackName);
1891: }
1892:
1893: if (deployedUnpackName.equals(unpackName)) {
1894: return true;
1895: }
1896: // else, go to the next loop
1897: }
1898: // not found
1899: return false;
1900: }
1901:
1902: /**
1903: * Return the list of all loaded Applications.
1904: * @return The list of deployed Applications
1905: */
1906: public List getDeployedEars() {
1907: ArrayList al = new ArrayList();
1908: Ear oEar;
1909: URL oURL;
1910: for (Enumeration enumEars = ears.elements(); enumEars
1911: .hasMoreElements();) {
1912: oEar = (Ear) enumEars.nextElement();
1913: oURL = oEar.getEarUrl();
1914: al.add(oURL.getFile());
1915: }
1916: return al;
1917: }
1918:
1919: /**
1920: * Return the list of installed Applications ready to deploy.
1921: * @return The list of deployable Applications
1922: * @throws Exception if the list can't be built
1923: */
1924: public List getDeployableEars() throws Exception {
1925: List al = getInstalledEars();
1926: al.removeAll(getDeployedEars());
1927: return al;
1928: }
1929:
1930: /**
1931: * Return the list of "autoload" directories for applications.
1932: * @return The list of all "autoload" directories
1933: */
1934: public List getAutoloadDirectories() {
1935: ArrayList al = new ArrayList();
1936: Iterator it = autoloadDirectories.iterator();
1937: while (it.hasNext()) {
1938: String fileName = (String) it.next();
1939: try {
1940: al.add(new File(fileName).toURL().getPath());
1941: } catch (Exception e) {
1942: if (logger.isLoggable(BasicLevel.DEBUG)) {
1943: logger.log(BasicLevel.DEBUG,
1944: "Can't get autoload directories : "
1945: + e.getMessage());
1946: }
1947: }
1948: }
1949: return al;
1950: }
1951:
1952: /**
1953: * Return the Apps directory.
1954: * @return The Apps directory
1955: */
1956: public String getAppsDirectory() {
1957: String sRet = null;
1958: try {
1959: sRet = (new File(APPS_DIR)).toURL().getPath();
1960: } catch (Exception e) {
1961: throw new RuntimeException("Cannot get the APPS directory",
1962: e);
1963: }
1964: return sRet;
1965: }
1966:
1967: /**
1968: * Build the J2EEApplication name.
1969: * @param pUrl The URL of Ear file
1970: * @return The J2EEApplication name
1971: */
1972: public static String buildJ2eeApplicationName(URL pUrl) {
1973: String sName = null;
1974: try {
1975: sName = new File(pUrl.getFile()).getName();
1976: if ("file".equals(pUrl.getProtocol())) {
1977: sName = buildJ2eeApplicationName(sName);
1978: }
1979: } catch (NullPointerException e) {
1980: if (logger != null) {
1981: if (logger.isLoggable(BasicLevel.DEBUG)) {
1982: logger.log(BasicLevel.DEBUG,
1983: "Can't build j2ee application", e);
1984: }
1985: }
1986: }
1987: return sName;
1988: }
1989:
1990: /**
1991: * Build the J2EEApplication name.
1992: * @param pFilename The name of Ear file
1993: * @return The J2EEApplication name
1994: */
1995: public static String buildJ2eeApplicationName(String pFilename) {
1996: String sName = null;
1997: try {
1998: sName = new File(pFilename).getName();
1999: int iPos = sName.lastIndexOf('.');
2000: if (iPos > -1) {
2001: sName = sName.substring(0, iPos);
2002: }
2003: } catch (NullPointerException e) {
2004: if (logger != null) {
2005: if (logger.isLoggable(BasicLevel.DEBUG)) {
2006: logger.log(BasicLevel.DEBUG,
2007: "Can't build j2ee application : "
2008: + e.getMessage());
2009: }
2010: }
2011: }
2012: return sName;
2013: }
2014:
2015: /**
2016: * @return policy configuration factory
2017: */
2018: private PolicyConfigurationFactory getPolicyConfigurationFactory() {
2019: PolicyConfigurationFactory pcFactory = null;
2020: try {
2021: pcFactory = PolicyConfigurationFactory
2022: .getPolicyConfigurationFactory();
2023: } catch (Exception cnfe) {
2024: String err = "Cannot retrieve current policy configuration factory";
2025: logger.log(BasicLevel.ERROR, err + "': "
2026: + cnfe.getMessage());
2027: throw new EarServiceException(err, cnfe);
2028: }
2029: return pcFactory;
2030: }
2031:
2032: /**
2033: * Add context-id for given jar urls to a given List.
2034: * @param jarUrls list of EJB-Jars
2035: * @param contextIDs the list of context-id.
2036: */
2037: private void addEjbContextIdToList(URL[] jarUrls, List contextIDs) {
2038: // Get contextID of EJB
2039: if (ejbService != null) {
2040: for (int u = 0; u < jarUrls.length; u++) {
2041: contextIDs.add(ejbService.getContainer(
2042: jarUrls[u].getFile()).getContextId());
2043: }
2044: }
2045: }
2046:
2047: /**
2048: * Add context-id for given web urls to a given List.
2049: * Also, reset the context-id associated to it.
2050: * @param jarUrls list of EJB-Jars
2051: * @param contextIDs the list of context-id.
2052: * @param contextRoots the name of the context-root of the web applications.
2053: * @param resetPolicyConfiguration reset or not the associated policy configuration.
2054: * @throws EarServiceException if policy context cannot be get.
2055: */
2056: private void addWebBContextIdToList(URL[] warUrls,
2057: String[] contextRoots, List contextIDs,
2058: final boolean resetPolicyConfiguration)
2059: throws EarServiceException {
2060: if (warUrls != null) {
2061: for (int u = 0; u < warUrls.length; u++) {
2062: // build context ID of war
2063: String ctxId = warUrls[u].getFile() + contextRoots[u];
2064: // reset the policy configuration associated to this context ID.
2065: if (resetPolicyConfiguration) {
2066: try {
2067: getPolicyConfigurationFactory()
2068: .getPolicyConfiguration(ctxId, true);
2069: } catch (PolicyContextException pce) {
2070: String err = "Cannot retrieve a policy configuration";
2071: logger.log(BasicLevel.ERROR, err + "': "
2072: + pce.getMessage());
2073: throw new EarServiceException(err, pce);
2074: }
2075: }
2076: contextIDs.add(ctxId);
2077: }
2078: }
2079: }
2080:
2081: /**
2082: * Link policy configuration objects of EJB and Web Component
2083: * @param userToRoleMapping mapping for user-to-role
2084: * @param jarUrls list of jars which have been deployed
2085: * @param warUrls list of wars which have been deployed
2086: * @param contextRoots list of context-root elements for each war url
2087: * @throws EarServiceException if the policy objects can't be linked
2088: */
2089: private void linkPolicyObjects(Map userToRoleMapping,
2090: URL[] jarUrls, URL[] warUrls, String[] contextRoots)
2091: throws EarServiceException {
2092: List ctxIDs = new LinkedList();
2093: // Get contextID of EJB
2094: addEjbContextIdToList(jarUrls, ctxIDs);
2095:
2096: // Now for WebApp
2097: addWebBContextIdToList(warUrls, contextRoots, ctxIDs, true);
2098:
2099: try {
2100: // Now link the policy configuration objects
2101: for (Iterator itCtxId = ctxIDs.iterator(); itCtxId
2102: .hasNext();) {
2103: String toBeLinkedCtxId = (String) itCtxId.next();
2104: PolicyConfiguration toBeLinkedPC = getPolicyConfigurationFactory()
2105: .getPolicyConfiguration(toBeLinkedCtxId, false);
2106: for (Iterator linkCId = ctxIDs.iterator(); linkCId
2107: .hasNext();) {
2108: String linkedCtxId = (String) linkCId.next();
2109: if (!toBeLinkedCtxId.equals(linkedCtxId)) {
2110: PolicyConfiguration linkedPC = getPolicyConfigurationFactory()
2111: .getPolicyConfiguration(linkedCtxId,
2112: false);
2113: toBeLinkedPC.linkConfiguration(linkedPC);
2114: }
2115: }
2116: }
2117: } catch (PolicyContextException pce) {
2118: String err = "Cannot retrieve a policy configuration";
2119: logger
2120: .log(BasicLevel.ERROR, err + "': "
2121: + pce.getMessage());
2122: throw new EarServiceException(err, pce);
2123: }
2124:
2125: // Do user-to-role mapping
2126: if (userToRoleMapping != null) {
2127: for (Iterator itCtxId = ctxIDs.iterator(); itCtxId
2128: .hasNext();) {
2129: String contextId = (String) itCtxId.next();
2130: for (Iterator itMapping = userToRoleMapping.keySet()
2131: .iterator(); itMapping.hasNext();) {
2132: String principalName = (String) itMapping.next();
2133: List roles = (List) userToRoleMapping
2134: .get(principalName);
2135: String[] roleNames = (String[]) roles
2136: .toArray(new String[roles.size()]);
2137: JPolicyUserRoleMapping.addUserToRoleMapping(
2138: contextId, principalName, roleNames);
2139: }
2140: }
2141:
2142: }
2143: }
2144:
2145: /**
2146: * Commit policy configuration objects of EJB Component
2147: * @param jarUrls list of jars which have been deployed
2148: * @throws EarServiceException if the policy objects can't be committed
2149: */
2150: private void commitEJBPolicyObjects(final URL[] jarUrls) {
2151: List ctxIDs = new LinkedList();
2152: addEjbContextIdToList(jarUrls, ctxIDs);
2153: commitPolicyObjects(ctxIDs);
2154: }
2155:
2156: /**
2157: * Commit policy configuration objects of Web Component
2158: * @param warUrls list of wars which have been deployed
2159: * @param contextRoots list of context-root elements for each war url
2160: * @throws EarServiceException if the policy objects can't be committed
2161: */
2162: private void commitWebBPolicyObjects(final URL[] warUrls,
2163: final String[] contextRoots) {
2164: List ctxIDs = new LinkedList();
2165: addWebBContextIdToList(warUrls, contextRoots, ctxIDs, false);
2166: commitPolicyObjects(ctxIDs);
2167:
2168: }
2169:
2170: /**
2171: * Commit policy context IDs of the given list.
2172: * @param ctxIDs list of context ID to commit.
2173: */
2174: private void commitPolicyObjects(final List ctxIDs) {
2175: String ctxId = null;
2176: try {
2177: // commit the policy configuration objects
2178: for (Iterator itCtxId = ctxIDs.iterator(); itCtxId
2179: .hasNext();) {
2180: ctxId = (String) itCtxId.next();
2181: PolicyConfiguration pc = getPolicyConfigurationFactory()
2182: .getPolicyConfiguration(ctxId, false);
2183: pc.commit();
2184: }
2185: } catch (PolicyContextException pce) {
2186: String err = "Cannot commit policy configuration with Id '"
2187: + ctxId + "'";
2188: logger
2189: .log(BasicLevel.ERROR, err + "': "
2190: + pce.getMessage());
2191: throw new EarServiceException(err, pce);
2192: }
2193:
2194: // refresh policy
2195: Policy.getPolicy().refresh();
2196: }
2197:
2198: }
|