All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.jonas.web.base.BaseWebContainerService Maven / Gradle / Ivy

There is a newer version: 5.3.0
Show newest version
/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2009 Bull S.A.S.
 * Contact: [email protected]
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id: BaseWebContainerService.java 20789 2011-01-28 14:46:16Z sauthieg $
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.web.base;

import static org.ow2.jonas.ws.jaxws.IJAXWSService.KEY_WEB_SERVICES_METADATAS;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.URL;
import java.net.URLClassLoader;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Vector;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.naming.Context;
import javax.naming.LinkRef;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContextType;

import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
import org.ow2.easybeans.deployment.api.EZBInjectionHolder;
import org.ow2.easybeans.persistence.api.EZBPersistenceUnitManager;
import org.ow2.easybeans.resolver.api.EZBJNDIResolver;
import org.ow2.easybeans.resolver.api.EZBJNDIResolverException;
import org.ow2.jonas.Version;
import org.ow2.jonas.deployment.api.IEJBLocalRefDesc;
import org.ow2.jonas.deployment.api.IEJBRefDesc;
import org.ow2.jonas.deployment.api.IEnvEntryDesc;
import org.ow2.jonas.deployment.api.IMessageDestinationRefDesc;
import org.ow2.jonas.deployment.api.IResourceEnvRefDesc;
import org.ow2.jonas.deployment.api.IResourceRefDesc;
import org.ow2.jonas.deployment.api.IServiceRefDesc;
import org.ow2.jonas.deployment.common.DeploymentDescException;
import org.ow2.jonas.deployment.web.WebContainerDeploymentDesc;
import org.ow2.jonas.deployment.web.lib.WarDeployableMetadataFactoryHolder;
import org.ow2.jonas.deployment.web.lib.WebDeploymentDescManager;
import org.ow2.jonas.ejb3.IEasyBeansService;
import org.ow2.jonas.jmx.JmxService;
import org.ow2.jonas.lib.bootstrap.JProp;
import org.ow2.jonas.lib.bootstrap.LoaderManager;
import org.ow2.jonas.lib.loader.FilteringClassLoader;
import org.ow2.jonas.lib.loader.SimpleWebappClassLoader;
import org.ow2.jonas.lib.loader.WebappClassLoader;
import org.ow2.jonas.lib.naming.ComponentContext;
import org.ow2.jonas.lib.security.PermissionManagerException;
import org.ow2.jonas.lib.service.AbsServiceImpl;
import org.ow2.jonas.lib.util.JonasObjectName;
import org.ow2.jonas.lib.util.Log;
import org.ow2.jonas.lib.work.DeployerLog;
import org.ow2.jonas.lib.work.DeployerLogException;
import org.ow2.jonas.naming.JComponentContextFactory;
import org.ow2.jonas.naming.JNamingManager;
import org.ow2.jonas.service.ServiceException;
import org.ow2.jonas.versioning.VersioningService;
import org.ow2.jonas.web.JWebContainerService;
import org.ow2.jonas.web.JWebContainerServiceException;
import org.ow2.jonas.web.base.lib.PermissionManager;
import org.ow2.jonas.web.base.proxy.HttpOnDemandProxy;
import org.ow2.jonas.web.base.proxy.HttpOnDemandProxyException;
import org.ow2.jonas.workcleaner.CleanTask;
import org.ow2.jonas.workcleaner.WorkCleanerService;
import org.ow2.jonas.ws.jaxrpc.IJAXRPCService;
import org.ow2.jonas.ws.jaxws.IJAXWSService;
import org.ow2.util.archive.api.ArchiveException;
import org.ow2.util.archive.api.IArchive;
import org.ow2.util.archive.impl.ArchiveManager;
import org.ow2.util.ee.deploy.api.deployable.EARDeployable;
import org.ow2.util.ee.deploy.api.deployable.IDeployable;
import org.ow2.util.ee.deploy.api.deployable.WARDeployable;
import org.ow2.util.ee.deploy.api.deployer.DeployerException;
import org.ow2.util.ee.deploy.api.deployer.IDeployerManager;
import org.ow2.util.ee.deploy.impl.helper.DeployableHelper;
import org.ow2.util.ee.deploy.impl.helper.UnpackDeployableHelper;
import org.ow2.util.ee.metadata.common.api.enc.IENCBinding;
import org.ow2.util.ee.metadata.common.api.enc.IENCBindingHolder;
import org.ow2.util.ee.metadata.common.api.struct.IJEjbEJB;
import org.ow2.util.ee.metadata.common.api.struct.IJavaxPersistenceContext;
import org.ow2.util.ee.metadata.common.api.struct.IJavaxPersistenceUnit;
import org.ow2.util.ee.metadata.common.api.struct.IJaxwsWebServiceRef;
import org.ow2.util.ee.metadata.war.api.IWarDeployableMetadataFactory;
import org.ow2.util.file.FileUtils;
import org.ow2.util.file.FileUtilsException;
import org.ow2.util.url.URLUtils;


/**
 * This abstract class provides an implementation for a dynamic JWebContainerService service.
 * @author Florent Benoit
 * @author Ludovic Bert (J2EE 1.3)
 * @author Nicolas Van Caneghem (exploded ear)
 * @author Michel-Ange Anton (contributor)
 * @author S. Ali Tokmen (versioning)
 */
public abstract class BaseWebContainerService extends AbsServiceImpl implements JWebContainerService,
        BaseWebContainerServiceMBean {

    /**
     * The name of the JONAS_BASE directory.
     */
    protected static final String JONAS_BASE = JProp.getJonasBase();

    /**
     * The name of the working directory.
     */
    protected static final String WORK_DIR = JProp.getWorkDir();

    /**
     * The name of the working apps directory.
     */
    protected static final String WORK_WEBAPPS_DIR = WORK_DIR + File.separator + "webapps";

    /**
     * The name of the property used in work directory for single webapps (not ear case).
     */
    protected static final String SINGLE_WORK_WEBAPPS_DIR_SUFFIX = "single";

    /**
     * The name of the property used in work directory for EAR webapps (in ear case).
     */
    protected static final String INEAR_WORK_WEBAPPS_DIR_SUFFIX = "ear";

    /**
     * Length of the extension .war.
     */
    private static final int WAR_EXTENSION_LENGTH = ".war".length();

    /**
     * Logger for this service.
     */
    private static Logger logger = Log.getLogger(Log.JONAS_WEB_PREFIX);

    /**
     * Reference on the NamingManager.
     */
    private JNamingManager naming;

    /**
     * War deployer.
     */
    private WARDeployer warDeployer = null;

    /**
     * Reference on the ComponentContextFactory.
     */
    private JComponentContextFactory contextFactory;

    /**
     * Associates an URL of an unpacked WAR file to its classloader.
     */
    private Hashtable warLoaders = new Hashtable();

    /**
     * Associates an URL of a deployed WAR file to its classloader.
     */
    private Hashtable warBindings = new Hashtable();

    /**
     * JMX Service.
     */
    protected JmxService jmxService = null;

    /**
     * List of the war deployed by the Web container Service.
     */
    private List warDeployed = new Vector();

    /**
     * Map of the unpacked WARs.
     */
    private Map unpackedWARs = new HashMap();

    /**
     * Name of the server (Tomcat, Jetty, ...).
     */
    private String serverName = null;

    /**
     * Version of the web container.
     */
    private String serverVersion = null;

    /**
     * Reference to the JAX-RPC service.
     */
    private IJAXRPCService jaxrpcService = null;

    /**
     * External Classloader.
     */
    private ClassLoader extClassLoader;

    /**
     * DeployerManager service.
     */
    private IDeployerManager deployerManager;

    /**
     * Versioning service.
     */
    private VersioningService versioningService;

    /**
     * Working directory for applications.
     */
    private File workSingleWebAppsFile = null;

    /**
     * Reference to the {@link DeployerLog} of the Web Container service.
     */
    private DeployerLog deployerLog;

    /**
     * Reference to the JAXWS Service.
     */
    private IJAXWSService jaxwsService;

    /**
     * EasyBeans service.
     */
    private IEasyBeansService ejb3Service = null;


    /**
     * On demand feature enabled ?
     */
    private boolean onDemandFeatureEnabled = false;

    /**
     * Link to the OnDemandProxy.
     */
    private HttpOnDemandProxy onDemandProxy = null;

    /**
     * Given port used for redirecting the requests (OnDemand proxy).
     * This port will be used to launch the internal web container (tomcat, jetty, etc)
     */
    private int onDemandRedirectPort = 0;

    /**
     * Default constructor.
     */
    public BaseWebContainerService() {
        this.warDeployer = new WARDeployer();
        this.onDemandProxy = new HttpOnDemandProxy();
    }

    /**
     * @param validate must we parse web.xml files with validation ?
     */
    public void setParsingwithvalidation(final boolean validate) {
        WebDeploymentDescManager.setParsingWithValidation(validate);
        if (logger.isLoggable(BasicLevel.DEBUG)) {
            if (!validate) {
                logger.log(BasicLevel.DEBUG, "Web XML parsing without validation");
            } else {
                logger.log(BasicLevel.DEBUG, "Web XML parsing with validation");
            }
        }
    }

    /**
     * Start the service.
     * @throws ServiceException if the startup failed.
     */
    @Override
    protected void doStart() throws ServiceException {
        initWorkingDirectory();

        // get apps ClassLoader
        try {
            LoaderManager lm = LoaderManager.getInstance();
            extClassLoader = lm.getExternalLoader();
        } catch (Exception e) {
            logger.log(BasicLevel.ERROR, "Cannot get the Applications ClassLoader from Web Container Service: ", e);
            throw new ServiceException("Cannot get the Applications ClassLoader from Web Container Service", e);
        }

        if (onDemandFeatureEnabled && !getServerProperties().isDevelopment()) {
            logger.log(BasicLevel.INFO, "The OnDemand feature is disabled in production mode");
            onDemandFeatureEnabled = false;
        }

        // Start the proxy if with mode onDemand ?
        if (onDemandFeatureEnabled) {

            // Register proxy on the deployer
            warDeployer.setOnDemandProxy(onDemandProxy);

            // Register ourself on the proxy
            onDemandProxy.setWebContainerService(this);
            onDemandProxy.setHttpPortNumber(Integer.parseInt(getDefaultHttpPort()));
            // If 0, needs to send a random port
            if (onDemandRedirectPort == 0) {
                this.onDemandRedirectPort = getRandomPort();
            }
            onDemandProxy.setRedirectPortNumber(onDemandRedirectPort);

            // Start the proxy port
            try {
                onDemandProxy.enable();
            } catch (HttpOnDemandProxyException e) {
                logger.log(BasicLevel.ERROR, "Cannot start the OnDemand proxy for web container: ", e);
                throw new ServiceException("Cannot start the OnDemand proxy for web container", e);
            }

            logger.log(BasicLevel.INFO, "OnDemand Feature enabled: Listening on '" + onDemandProxy.getHttpPortNumber() + "' port (internal:" + onDemandProxy.getRedirectPortNumber() + ").");

        }

        // Init the deployer
        warDeployer.setWebContainerService(this);

        // Register the deployer
        deployerManager.register(warDeployer);

        // Register the MBean
        registerWebServiceMBean(this, getDomainName());
    }

    /**
     * Stop the service.
     * @throws ServiceException if the stop failed.
     */
    @Override
    protected void doStop() throws ServiceException {
        // Undeploy standalone WARs
        warDeployer.stop();

        if (deployerManager != null) {
            // Unregister the deployer
            deployerManager.unregister(warDeployer);
        }

        if (onDemandProxy != null) {
            try {
                onDemandProxy.disable();
            } catch (HttpOnDemandProxyException e) {
                logger.log(BasicLevel.WARN, "Cannot stop the OnDemand proxy", e);
            }
        }

        unregisterWebServiceMBean(getDomainName());

        logger.log(BasicLevel.DEBUG, "WebContainerService stopped");
    }

    /**
     * Create the environment and delegate the operation to the implementation of the web container.
     * @param ctx the context which contains the configuration in order to deploy a WAR.
     * @throws JWebContainerServiceException if the registration of the WAR failed.
     */
    protected abstract void doRegisterWar(Context ctx) throws JWebContainerServiceException;

    /**
     * Delegate the unregistration to the implementation of the web container.
     * @param ctx the context which contains the configuration in order to undeploy a WAR.
     * @throws JWebContainerServiceException if the unregistration failed.
     */
    protected abstract void doUnRegisterWar(Context ctx) throws JWebContainerServiceException;


    /**
     * Starts the specific code for the web container implementation.
     * This allows to start the internal container on demand (if there is an access on the http proxy port for example)
     * @throws JWebContainerServiceException if container is not started
     */
    public abstract void startInternalWebContainer() throws JWebContainerServiceException;

    /**
     * Checks if the internal web container has been started.
     * @return true if it is already started
     */
    public abstract boolean isInternalContainerStarted();


    /**
     * Return the URL where warURL has been unpacked.
     * @param warURL the URL of the war
     * @param earDeployable the EAR deployable (could be null)
     * @return the URL where warURL has been unpacked.
     * @throws JWebContainerServiceException when it is impossible to retrieve the unpacked URL.
     */
    protected URL getUnpackedURL(final URL warURL, final EARDeployable earDeployable) throws JWebContainerServiceException {

        String folder = WORK_WEBAPPS_DIR + File.separator + getJonasServerName() + File.separator;

        // Two cases :
        // war is alone --> unpack it in :
        // WEBAPPS_DIR/servername/single/war_filename_timestamp/
        // war come from an ear --> unpack it in :
        // WEBAPPS_DIR/servername/ear/ear_filename_timestamp/war_filename__timestamp/

        File warFile = URLUtils.urlToFile(warURL);

        // Build destination folder name
        if (earDeployable != null) {
            // The destination directory is built from the filename of the unpacked ear,
            // that is to say, the parent folder of the original war URL.
            String earFileName = warFile.getParentFile().getName();
            if (!getServerProperties().isDevelopment()) {
                try {
                    earFileName = URLUtils.urlToFile(earDeployable.getOriginalDeployable().getArchive().getURL()).getName();
                } catch (Exception e) {
                    logger.log(BasicLevel.ERROR, "Cannot retrieve the original deployable");
                }
            }
            folder += INEAR_WORK_WEBAPPS_DIR_SUFFIX + File.separator + earFileName;
        } else {
            folder += SINGLE_WORK_WEBAPPS_DIR_SUFFIX + File.separator;
        }

        // Build destination archive name
        String archiveName = warFile.getName();
        if (getServerProperties().isDevelopment() && earDeployable == null) {
            try {
                archiveName = FileUtils.lastModifiedFileName(warFile);
            } catch (FileUtilsException e) {
                throw new JWebContainerServiceException("Failed creating the destination name", e);
            }
        }

        try {
            IArchive archive = ArchiveManager.getInstance().getArchive(warFile);
            WARDeployable warDeployable = (WARDeployable) DeployableHelper.getDeployable(archive);
            UnpackDeployableHelper.unpack(warDeployable, new File(folder), archiveName, false);
            return warDeployable.getUnpackedDeployable().getArchive().getURL();
        } catch (Exception e) {
            throw new JWebContainerServiceException("Failed unpacking the war file " + warFile, e);
        }
    }

    /**
     * Return the class loader of the given warURL. Unpack the associated war and build the loader if it's not in the cache.
     * @param warURL the url of the war we want to get the loader
     * @param earDeployable If the WAR is in an EAR application
     * @param parentLoader the ejb class loader of the ear. May be null in non ear case.
     * @return the class loader of the given warURL.
     * @throws JWebContainerServiceException if the process failed.
     */
    public WebappClassLoader getClassLoader(final URL warURL, final EARDeployable earDeployable, final ClassLoader parentLoader)
            throws JWebContainerServiceException {

        WebappClassLoader loaderForCls = null;
        try {
            WebLoaderHolder holder = (WebLoaderHolder) warLoaders.get(warURL);
            if (holder != null) {
                loaderForCls = holder.getJonasWebLoader();
            }
        } catch (Exception e) {
            throw new JWebContainerServiceException("Error when getting '" + warURL + "' in cache", e);
        }

        if (loaderForCls == null) {
            // the war is not already used

            // Use the unpacked directory
            URL unpackedWarURL = getUnpackedURL(warURL, earDeployable);
            try {
                if (parentLoader != null) {
                    // ear case.
                    loaderForCls = new WebappClassLoader(unpackedWarURL, parentLoader);
                } else {
                    // Case of non-ear application : only a single war
                    loaderForCls = new WebappClassLoader(unpackedWarURL, extClassLoader);
                }
            } catch (IOException ioe) {
                throw new JWebContainerServiceException("Cannot create WebAppClassLoader from '" + unpackedWarURL + "'", ioe);
            }

            // add the class loader in cache.
            try {
                WebLoaderHolder holder = new WebLoaderHolder(loaderForCls, null);
                warLoaders.put(warURL, holder);
            } catch (Exception e) {
                throw new JWebContainerServiceException("Error when adding '" + warURL + "' in cache", e);
            }
        }

        return loaderForCls;
    }

    /**
     * @param warURL the URL of the webapp
     * @return Returns the ClassLoader used to link a JNDI environnment to a webapp
     */
    public ClassLoader getContextLinkedClassLoader(final URL warURL) {
        WebLoaderHolder holder = (WebLoaderHolder) warLoaders.get(warURL);
        if (holder != null) {
            return holder.getEnvWebLoader();
        }
        return null;
    }

    /**
     * Create the environment and delegate the operation to the implementation of the web container.
     * @param ctx the context which contains the configuration in order to deploy a WAR.
     * @throws JWebContainerServiceException if the registration of the WAR failed.
     */
    protected void registerWar(final Context ctx) throws JWebContainerServiceException {
        // There are 6 possible parameters :
        // - warURL is the URL of the war to deploy (required param).
        // - parentClassLoader is the parent classloader of
        // the web classloader (optional param).
        // - earClassLoader is the ear classloader (optional param).
        // - earURL is the URL of the ear (optional parameter :
        // if earURL is set it means that we are in the ear case, else it
        // means that we are in the non ear case).
        // - earDeployable the EARDeployable of the ear application file.
        // (optional parameter, same comment as earURL).
        // - altDD is the optional deployment descriptor (optional param).
        // - contextRoot is the context root for the Web application
        // (optional param).

        // Get the URL of the ear application file in the case of an
        // ear application, null otherwise.
        URL earURL = null;
        EARDeployable earDeployable = null;
        String contextRoot = null;
        String earAppName = null;
        String userURI = null;

        // Injection holder
        EZBInjectionHolder ezbInjectionHolder = null;
        try {
            earURL = (URL) ctx.lookup("earURL");
            earDeployable = (EARDeployable) ctx.lookup("earDeployable");
            contextRoot = (String) ctx.lookup("contextRoot");
        } catch (NamingException e) {
            if (earURL != null || earDeployable != null || contextRoot != null) {
                String err = "Error while getting parameter from context param :" + e.getMessage();
                logger.log(BasicLevel.ERROR, err);
                throw new JWebContainerServiceException(err, e);
            } // else nothing to do : non-ear case.
        }

        // Get EAR application name
        if (earDeployable != null) {
            earAppName = earDeployable.getModuleName();
        }

        // Get the URL of the war to deploy ...
        URL warURL = null;
        try {
            warURL = (URL) ctx.lookup("warURL");
        } catch (NamingException e) {
            String err = "Error while getting parameter from context param :" + e.getMessage();
            logger.log(BasicLevel.ERROR, err);
            throw new JWebContainerServiceException(err, e);
        }

        // Get injection holder
        try {
            ezbInjectionHolder = (EZBInjectionHolder) ctx.lookup(EZBInjectionHolder.class.getName());
        } catch (NamingException e) {
            logger.log(BasicLevel.DEBUG, "No injection holder");
            // Create a new one if not yet existing
            if (ejb3Service != null) {
                ezbInjectionHolder = ejb3Service.buildInjectionHolder(null, null);
            }
        }

        // ... and check if the war to deploy exists.
        File warFile = URLUtils.urlToFile(warURL);
        if (!warFile.exists()) {
            String err = "registerWar: '" + warFile.getPath() + "' not found";
            logger.log(BasicLevel.ERROR, err);
            throw new JWebContainerServiceException(err);
        }

        // Check if the war to deploy is not already deployed.
        War war = getWar(warURL);
        if (war != null) {
            // The war is already deployed.
            String err = "Cannot deploy war '" + warURL.getFile() + "' is already deployed."
                    + " You must undeploy the war before a new deployment.";
            throw new JWebContainerServiceException(err);
        }

        URLClassLoader parentLoader = null;
        URLClassLoader earClassLoader = null;
        boolean isInEar = true;
        try {
            parentLoader = (URLClassLoader) ctx.lookup("parentClassLoader");
            earClassLoader = (URLClassLoader) ctx.lookup("earClassLoader");
        } catch (NamingException ne) {
            if (logger.isLoggable(BasicLevel.DEBUG)) {
                logger.log(BasicLevel.DEBUG, "Not an ear case");
            }
            isInEar = false;
            // exception occurs when the earClassLoader is not found.
        }

        // Check WsGen for webapp outside of an Ear
        if (!isInEar) {
            try {
                applyWSGenIfNeeded(warFile.getCanonicalPath());
            } catch (Exception e) {
                throw new JWebContainerServiceException("Cannot apply WsGen on the file : " + warFile, e);
            }
        }

        // Get the war class loader.
        WebappClassLoader loaderForCls = getClassLoader(warURL, earDeployable, parentLoader);

        // Get the URL of the unpacked WAR
        URL unpackedWarURL = loaderForCls.getBaseURL();

        // The file is unpacked, so log it
        if (deployerLog != null && !isInEar && getServerProperties().isDevelopment()) {
            try {
                deployerLog.addEntry(warFile, URLUtils.urlToFile(unpackedWarURL));
            } catch (Exception e) {
                String err = "Error while adding the " + warFile + " entry in the log file";
                logger.log(BasicLevel.ERROR, err + " : " + e.getMessage());
                throw new JWebContainerServiceException(err, e);
            }
        }

        // Only if the JAX-RPC Service is started
        // And in non EAR case
        if (jaxrpcService != null && earClassLoader == null) {
            try {
                ComponentContext contctx = null;
                try {
                    contctx = new ComponentContext(unpackedWarURL.getFile());
                    File unpackedWarFile = URLUtils.urlToFile(unpackedWarURL);
                    contctx.rebind(IJAXRPCService.UNPACK_DIRECTORY_CTX_PARAM, unpackedWarFile);
                    contctx.rebind("jarUrls", new URL[0]);
                    contctx.rebind("warUrls", new URL[] {warURL});
                    if (parentLoader != null) {
                        contctx.rebind("ejbClassLoader", parentLoader);
                    }
                } catch (NamingException e) {
                    String err = "Can not bind params for the WebServices service, " + "Can't deploy Web Services Endpoint";
                    throw new JWebContainerServiceException(err, e);
                }
                jaxrpcService.deployWebServices(contctx);
            } catch (ServiceException se) {
                String err = "Error during the deployment of the WebServices of the War file '" + warURL + "'";
                logger.log(BasicLevel.ERROR, err + " : " + se.getMessage());
                throw new JWebContainerServiceException(err, se);
            }
        }

        // Get the deployment descriptor from file
        WebContainerDeploymentDesc webDD = null;
        try {
            WebDeploymentDescManager manager = WebDeploymentDescManager.getInstance();
            webDD = manager.getDeploymentDesc(unpackedWarURL, warURL, loaderForCls, earClassLoader);
        } catch (DeploymentDescException e) {
            String err = "Cannot read the deployment descriptors '" + warURL.getFile() + "'";
            logger.log(BasicLevel.ERROR, err + ": " + e);
            e.printStackTrace(System.err);
            throw new JWebContainerServiceException(err, e);
        }

        // Populate the java:comp/env (ENC) environment.
        ClassLoader webClassLoader = null;
        try {
            FilteringClassLoader filteringClassLoader = createFilteringClassLoader(parentLoader,
                                                                                   unpackedWarURL);
            webClassLoader = new SimpleWebappClassLoader(unpackedWarURL, filteringClassLoader);

        } catch (Exception e) {
            throw new JWebContainerServiceException("Unable to create classloader", e);
        }

        // Persistence unit entry present ?
        IArchive archive = ArchiveManager.getInstance().getArchive(URLUtils.urlToFile(unpackedWarURL));

        List persistenceArchives = new ArrayList();
        List urlsToAddToClassLoader = new ArrayList();
        // Add WEB-INF/classes for the classloader if there are persistence classes
        URL urlWebInfClasses = webClassLoader.getResource("WEB-INF/classes/");
        if (urlWebInfClasses != null) {
            urlsToAddToClassLoader.add(urlWebInfClasses);
        }

        // Check entry in the war
        URL persistenceXmlEntryInWarFile = webClassLoader.getResource("WEB-INF/classes/META-INF/persistence.xml");
        if (persistenceXmlEntryInWarFile != null) {
            // There is an entry, add the archive to be analyzed
            persistenceArchives.add(archive);

        }

        // Check entries in each library
        try {
            Iterator itURLEntries = archive.getResources();
            while (itURLEntries.hasNext()) {
                URL urlWarEntry = itURLEntries.next();
                // There are jar files
                if (urlWarEntry.toExternalForm().contains("/WEB-INF/lib/") && urlWarEntry.toExternalForm().endsWith(".jar")) {
                    IArchive archiveLib = ArchiveManager.getInstance().getArchive(URLUtils.urlToFile(urlWarEntry));
                    URL persistenceXmlInLib = archiveLib.getResource("META-INF/persistence.xml");
                    if (persistenceXmlInLib != null) {
                        persistenceArchives.add(archiveLib);
                    }
                    urlsToAddToClassLoader.add(urlWarEntry);
                }
            }
        } catch (ArchiveException e) {
            throw new JWebContainerServiceException("Cannot check for persistence", e);
        }

        // there are archives to analyze
        if (persistenceArchives.size() > 0) {
            if (ejb3Service != null) {

                // Add URLs to the classLoader
                for (URL urlToAdd : urlsToAddToClassLoader) {
                    ((SimpleWebappClassLoader) webClassLoader).addURL(urlToAdd);
                }
                // Create EasyBeans ClassLoader
                webClassLoader = ejb3Service.buildByteCodeEnhancementClassLoader(new URL[0], webClassLoader);

                // Analyze each persistence archive
                for (IArchive persistenceArchive : persistenceArchives) {
                    EZBPersistenceUnitManager persistenceUnitManager = null;
                    try {
                        persistenceUnitManager = ejb3Service.getPersistenceUnitManager(persistenceArchive, webClassLoader);
                    } catch (org.ow2.easybeans.persistence.api.PersistenceXmlFileAnalyzerException e) {
                        throw new JWebContainerServiceException("Unable to analyze persistence.xml file", e);
                    }

                    EZBPersistenceUnitManager existingPersistenceUnitManager = ezbInjectionHolder.getPersistenceUnitManager();
                    if (existingPersistenceUnitManager == null) {
                        ezbInjectionHolder = ejb3Service.buildInjectionHolder(persistenceUnitManager, ezbInjectionHolder
                                .getJNDIResolver());
                    } else {
                        // add unit infos
                        existingPersistenceUnitManager.merge(persistenceUnitManager);
                    }
                }
            } else {
                logger.log(BasicLevel.WARN, "Persistence archives + '" + persistenceArchives + "' found but no EJB3 service");
            }
        }
        try {
            if (logger.isLoggable(BasicLevel.DEBUG)) {
                logger.log(BasicLevel.DEBUG, "Populating environment of the file " + warURL.getFile());
            }
            Context ctxParam = new ComponentContext(unpackedWarURL.getFile());
            ctxParam.rebind("DeploymentDesc", webDD);
            ctxParam.rebind("warName", unpackedWarURL.getFile());

            if (earDeployable != null) {
                ctxParam.rebind("earDeployable", earDeployable);
            }
            ctxParam.rebind("parentCL", webClassLoader);

            // Do the populating of the java:comp/env (ENC) environment.
            setWebEnvironment(ctxParam, ezbInjectionHolder, webClassLoader);
        } catch (Exception e) {
            // populating environment failed.
            String err = "Error when populating ";
            logger.log(BasicLevel.ERROR, err + e.getMessage());
            throw new JWebContainerServiceException(err, e);
        }

        // TODO maybe to be removed ?
        WebLoaderHolder holder = (WebLoaderHolder) warLoaders.get(warURL);
        holder.setEnvWebLoader(webClassLoader);

        contextRoot = getContextRoot(contextRoot, earClassLoader, warURL, webDD);
        String versionID = null;
        if (isVersioningEnabled()) {
            if (earURL != null) {
                versionID = versioningService.getVersionID(earDeployable);
            } else {
                versionID = versioningService.getVersionID(warURL);
            }
            // TODO: prefix for deploying MBeans inside this WAR (filters, ...)
        }
        if (versionID == null) {
            userURI = contextRoot;
        } else {
            if (!contextRoot.contains(versionID)) {
                userURI = contextRoot;
                contextRoot += versionID;
            } else {
                userURI = contextRoot.replace(versionID, "");
            }

            if (userURI.equals("/") && contextRoot.charAt(0) == '/') {
                // ensure context-root is valid (remove starting /)
                contextRoot = contextRoot.substring(1);
            }
        }

        // Set the name of the host where to deploy the war if it is
        // specified in the jonas-web.xml.
        String hostName = webDD.getHost();

        // Check if the context to deploy is not already deployed.
        List deployedWars = getWar(contextRoot);
        for (Iterator itDeployed = deployedWars.iterator(); itDeployed.hasNext();) {
            War deployedWar = (War) itDeployed.next();
            String hostDeployed = deployedWar.getHostName();
            if ((hostDeployed == null && hostName == null) || (hostDeployed != null && hostDeployed.equals(hostName))) {
                // The war is already deployed.
                String err = "Cannot deploy war '" + warURL.getFile() + "' is already deployed with the context '"
                        + contextRoot + "'." + " You must undeploy the war before a new deployment.";
                throw new JWebContainerServiceException(err);
            }
        }

        // Context classloader must follow the java2 delegation model ?
        boolean java2DelegationModel = webDD.getJava2DelegationModel();

        // Create War
        war = new War(warURL, earURL, hostName, contextRoot, java2DelegationModel, webDD.getXmlContent(), webDD
                .getJOnASXmlContent(), webDD.getServletsName());

        // Configure JACC
        PermissionManager permissionManager = null;
        try {
            boolean removePContext = true;
            // Policy context is already existing (created by ear service), no need to remove it
            if (earClassLoader != null) {
                removePContext = false;
            }
            permissionManager = new PermissionManager(webDD, war.getContextId(), removePContext);
            permissionManager.translateServletDeploymentDescriptor();
            // if not in ear case, commit the policy configuration, else it is done
            // by EAR service after linking all policy configuration objects
            if (earClassLoader == null) {
                permissionManager.commit();
            }
        } catch (Exception e) {
            e.printStackTrace();
            String err = "Cannot build permission manager object for the webapp '" + unpackedWarURL + "'";
            logger.log(BasicLevel.ERROR, err + ": " + e.getMessage());
            throw new JWebContainerServiceException(err, e);
        }

        // Configure the context to give to doRegisterWar ...
        Context ctxParam = null;
        try {
            ctxParam = new ComponentContext(unpackedWarURL.getFile());
            ctxParam.rebind("warURL", warURL);
            if (earURL != null) {
                ctxParam.rebind("earURL", earURL);
            }
            ctxParam.rebind("unpackedWarURL", unpackedWarURL);
            ctxParam.rebind("parentCL", webClassLoader);
            if (hostName != null) {
                ctxParam.rebind("hostName", hostName);
            }
            ctxParam.rebind("contextRoot", contextRoot);
            if (earAppName != null) {
                ctxParam.rebind("earAppName", earAppName);
            }
            // Injection holder
            if (ezbInjectionHolder != null) {
                ctxParam.rebind(EZBInjectionHolder.class.getName(), ezbInjectionHolder);
            }

            ctxParam.rebind("webDD", webDD);
            ctxParam.rebind("java2DelegationModel", new Boolean(java2DelegationModel));
            ctxParam.rebind("permissionManager", permissionManager);

            ctxParam.rebind("userURI", userURI);

            // Trasmit the @WebServices classes too
            ctxParam.rebind(KEY_WEB_SERVICES_METADATAS, webDD.getWebServices());
        } catch (NamingException e) {
            String err = "Error when deploying the war  '" + unpackedWarURL.getFile() + "'";
            logger.log(BasicLevel.ERROR, err + e.getMessage());
            throw new JWebContainerServiceException(err, e);
        }

        war.setPermissionManager(permissionManager);

        // ... and delegate the registration of the war to the wrapper.
        doRegisterWar(ctxParam);

        // Finaly indicates that the war is deployed.
        warDeployed.add(war);
        warBindings.put(warURL, webClassLoader);
        unpackedWARs.put(warURL, unpackedWarURL);

        // Admin code
        registerWarMBean(war, getDomainName(), warURL.getFile());

        // Complete the Deployment of the WebServices
        // Only if the JAX-RPC Service is started
        // And in non EAR case
        if (jaxrpcService != null && earClassLoader == null) {
            try {
                ComponentContext contctx = null;
                try {
                    contctx = new ComponentContext(unpackedWarURL.getFile());
                    contctx.rebind(IJAXRPCService.CLASSLOADER_CTX_PARAM, loaderForCls);
                    contctx.rebind(IJAXRPCService.PARENT_OBJECTNAME_CTX_PARAM, ctxParam.lookup("WebModule"));
                    contctx.rebind(IJAXRPCService.ISINEAR_CTX_PARAM, Boolean.FALSE);
                } catch (NamingException e) {
                    String err = "Can not bind params for the WebServices service, "
                            + "can't complete deployment of Web Services Endpoints";
                    throw new JWebContainerServiceException(err, e);
                }
                jaxrpcService.completeWSDeployment(contctx);
            } catch (ServiceException se) {
                String err = "Error during the deployment of the WebServices of the War file '" + warURL + "'";
                logger.log(BasicLevel.ERROR, err + " : " + se.getMessage());
                throw new JWebContainerServiceException(err, se);
            }
        }

        StringBuffer txtInfo = new StringBuffer("War " + URLUtils.urlToFile(warURL).getName() + " available at the context ");
        if (!contextRoot.startsWith("/")) {
            txtInfo.append("/");
        }
        txtInfo.append(contextRoot);

        if (hostName != null) {
            txtInfo.append(" on the host ");
            txtInfo.append(hostName);
        }
        txtInfo.append(".");
        logger.log(BasicLevel.INFO, txtInfo.toString());

        // Remove the DD cache (WebServices)
        if (jaxrpcService != null && earClassLoader == null) {
            jaxrpcService.removeCache(loaderForCls);
        }
    }

    /**
     * Creates a {@code FilteringClassLoader} for this WebApp.
     * @param parentLoader the Ear parent's ClassLoader (may be null)
     * @param unpackedWarURL The Url of the unpacked webapp (only used in non-EAR case, never null)
     * @return a Filtering ClassLoader configured from {@code WEB-INF/classloader-filtering.xml} (if any).
     */
    private FilteringClassLoader createFilteringClassLoader(final URLClassLoader parentLoader,
                                                            final URL unpackedWarURL) {

        // Find the parent loader
        ClassLoader parent;
        if (parentLoader == null) {
            // Standalone case, simply be a child of the common classloader
            parent = extClassLoader;
        } else {
            // In Ear case, the filter sits between the EjbJars + Libraries loader
            // and the Web Application ClassLoader (to be created as child of this loader).
            parent = parentLoader;
        }

        // Create the child filtering loader from the parent
        FilteringClassLoader filteringClassLoader = new FilteringClassLoader(parent);

        // Construct the archive from the Url
        // First transform the URL into File (Avoid to fall in UTIL-94)
        File unpackedFile = URLUtils.urlToFile(unpackedWarURL);
        IArchive archive = ArchiveManager.getInstance().getArchive(unpackedFile);

        // Seek the XML definition file in the archive (if any)
        try {
            String name = "WEB-INF/" + FilteringClassLoader.CLASSLOADER_FILTERING_FILE;
            URL definition = archive.getResource(name);
            if (definition != null) {
                filteringClassLoader.setDefinitionUrl(definition);
            }
        } catch (ArchiveException ae) {
            // Ignored
            if (logger.isLoggable(BasicLevel.DEBUG)) {
                String message = "Cannot get classloader-filtering.xml file from the archive " + archive;
                logger.log(BasicLevel.DEBUG, message, ae);
            }
        } finally {
            archive.close();
        }

        filteringClassLoader.start();
        return filteringClassLoader;
    }

    /**
     * Apply WSGen on the given file if needed.
     * @param path the path to use
     * @return the modified file or the original file if WSGen has not been launched.
     * @throws DeployerException if WSGen cannot be applied.
     */
    private void applyWSGenIfNeeded(final String path) throws DeployerException {
        // JAX-RPC service started ?
        if (jaxrpcService == null) {
            logger.log(BasicLevel.DEBUG, "The JAX-RPC service is not present, no need to call WSGen");
            return;
        }

        // Auto WsGen enabled ?
        if (!jaxrpcService.isAutoWsGenEngaged()) {
            logger.log(BasicLevel.DEBUG, "Automatic WsGen is not enabled, no need to call WSGen");
            return;
        }

        IArchive archive = ArchiveManager.getInstance().getArchive(new File(path));

        // Check version in manifest
        String jonasVersionWsGen = archive.getMetadata().get("WsGen-JOnAS-Version");
        if (Version.getNumber().equals(jonasVersionWsGen)) {
            // no changes, just continue the normal deployment process
            logger.log(BasicLevel.DEBUG, "No change: no need to call WSGen");
            return;
        }

        try {
            IDeployable deployable = DeployableHelper.getDeployable(archive);
            jaxrpcService.applyWSGen(deployable);
        } catch (Exception e) {
            throw new DeployerException(e);
        }
    }

    /**
     * Gets the context root for a WAR.
     * @param contextRoot Current context root, null if none.
     * @param earClassLoader EAR classloader for the WAR, null if none.
     * @param warURL War file's URL.
     * @param webDD Deployment descriptor of the WAR file.
     * @return Context root, checked (always begin with one slash).
     */
    protected String getContextRoot(String contextRoot, final URLClassLoader earClassLoader, final URL warURL,
            final WebContainerDeploymentDesc webDD) {
        // Set the right context root for the web application, the priority is
        // the following :
        // 1 - context-root of application.xml
        // 2 - context-root of jonas-web.xml
        // 3 - context-root is the name of the WAR file without extension.
        if (earClassLoader == null && contextRoot == null) {
            String cRoot = webDD.getContextRoot();
            if (cRoot == null) {
                String file = new File(warURL.getFile()).getName();
                if (file.toLowerCase().endsWith(".war")) {
                    contextRoot = file.substring(0, file.length() - WAR_EXTENSION_LENGTH);
                } else {
                    // It's a directory which is deployed
                    contextRoot = file.substring(0, file.length());
                }
            } else {
                contextRoot = cRoot;
            }
        }

        // ensure context-root is valid (remove starting /)
        if (contextRoot.startsWith("/") && !contextRoot.equals("/")) {
            logger.log(BasicLevel.WARN, "Context-Root '" + contextRoot
                    + "' contains invalid starting / in the name. Fixing it.");
            int c = 0;
            while (contextRoot.charAt(c) == '/') {
                c++;
            }
            contextRoot = contextRoot.substring(c);
        }
        return contextRoot;
    }

    /**
     * Register a WAR by delegating the operation to the registerWar() method. This is used for JMX management.
     * @param fileName the name of the war to deploy.
     * @throws RemoteException if rmi call failed.
     * @throws JWebContainerServiceException if the registration failed.
     */
    public void registerWar(final String fileName) throws RemoteException, JWebContainerServiceException {
        // convert the file name to the appropriate url and check if the file
        // exists.
        URL warURL = checkWarFile(fileName);

        // create the context to call the registerWar method.
        Context ctx = null;
        try {
            ctx = new ComponentContext(fileName);
            ctx.rebind("warURL", warURL);
        } catch (NamingException e) {
            String err = "Error when deploying the war  '" + fileName + "'";
            logger.log(BasicLevel.ERROR, err + e.getMessage());
            throw new JWebContainerServiceException(err, e);
        }

        // call the registerWar method.
        registerWar(ctx);
    }

    /**
     * Set the environment of the web container inside the given context.
     * @param ctxParam the java:comp/env/ environment where is stored the values of the web container environment.
     * @param ezbInjectionHolder the easybeans injection handler.
     * @param webAppClassLoader the classloader of the web application.
     * @throws JWebContainerServiceException if the populating of the environment failed.
     */
    protected void setWebEnvironment(final Context ctxParam, final EZBInjectionHolder ezbInjectionHolder,
            final ClassLoader webAppClassLoader) throws JWebContainerServiceException {

        WebContainerDeploymentDesc dd = null;
        String warName = null;
        ClassLoader parentClassLoader = null;
        EARDeployable earDeployable = null;

        /*
         * get the parameters - Deployment desc of xml - Name of the war - Parent Class loader
         */
        try {
            dd = (WebContainerDeploymentDesc) ctxParam.lookup("DeploymentDesc");
            warName = (String) ctxParam.lookup("warName");
            earDeployable = (EARDeployable) ctxParam.lookup("earDeployable");
        } catch (NamingException e) {
            // Ignore if earDeployable not found, it's optional
            if (earDeployable != null) {
                String err = "Error while getting parameter from context param ";
                logger.log(BasicLevel.ERROR, err + e.getMessage());
                throw new JWebContainerServiceException(err, e);
            }
        }

        // Get the parentCL
        try {
            parentClassLoader = (ClassLoader) ctxParam.lookup("parentCL");
        } catch (NamingException e) {
            String err = "Error while getting parameter from context param ";
            logger.log(BasicLevel.ERROR, err + e.getMessage());
            throw new JWebContainerServiceException(err, e);
        }

        // Create the java:comp/env entry and bind the entries
        try {
            // Create a JNDI context for this war java:comp/env
            Context javaCtx = contextFactory.createComponentContext(warName);
            naming.setComponentContext(javaCtx, parentClassLoader);
            Context envCtx = javaCtx.createSubcontext("comp/env");

            // War Environment entries
            IEnvEntryDesc[] envt = dd.getEnvEntryDesc();
            for (int i = 0; i < envt.length; i++) {
                // get information in descriptor
                String name = envt[i].getName();
                Object obj = envt[i].getValue();

                // register object in JNDI
                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, warName + ": Binding object " + name + " -> " + obj);
                }
                envCtx.rebind(name, obj);
            }

            // Resource References
            IResourceRefDesc[] resref = dd.getResourceRefDesc();
            for (int i = 0; i < resref.length; i++) {
                // get information in descriptor
                String name = resref[i].getName();
                String type = resref[i].getTypeName();
                String resname = resref[i].getJndiName();
                // register object in JNDI
                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, warName + ": Linking resource " + name + " -> " + resname);
                }

                if (type.equalsIgnoreCase("java.net.URL")) {
                    // Specify the factory to use with the right URL
                    Reference ref = new Reference("java.net.URL", "org.ow2.jonas.lib.naming.URLFactory", null);
                    StringRefAddr refAddr = new StringRefAddr("url", resname);
                    ref.add(refAddr);
                    envCtx.rebind(name, ref);
                } else {
                    // build the LinkRef that will be registered:
                    // FactoryClassName = null, size = 1, refAddr = resname.
                    LinkRef lref = new LinkRef(resname);
                    envCtx.rebind(name, lref);
                }
            }

            // Resource Environment References
            IResourceEnvRefDesc[] resEnvref = dd.getResourceEnvRefDesc();
            for (int i = 0; i < resEnvref.length; i++) {
                // get information in descriptor
                String name = resEnvref[i].getName();
                String resname = resEnvref[i].getJndiName();
                LinkRef lref = new LinkRef(resname);

                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, warName + ": Linking resource environment " + name + " -> " + resname);
                }
                envCtx.rebind(name, lref);
            }

            // EJB References
            IEJBRefDesc[] ejbref = dd.getEjbRefDesc();
            for (int i = 0; i < ejbref.length; i++) {
                // get information in descriptor
                String name = ejbref[i].getEjbRefName();
                String ejbname = null;
                ejbname = ejbref[i].getJndiName();

                LinkRef lref = new LinkRef(ejbname);

                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, warName + ": Linking ejb " + name + " -> " + ejbname);
                }
                envCtx.rebind(name, lref);
            }

            // EJB Local Refs
            // We use here ejb-link tag. This should be used also for
            // ejb-ref when we are able to manage references to
            // another jar file.
            IEJBLocalRefDesc[] ejblocalref = dd.getEjbLocalRefDesc();
            for (int i = 0; i < ejblocalref.length; i++) {
                String name = ejblocalref[i].getEjbRefName();
                String ejbname = ejblocalref[i].getJndiLocalName();
                LinkRef lref = new LinkRef(ejbname);
                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, warName + ": Linking ejb " + name + " -> " + ejbname);
                }
                envCtx.rebind(name, lref);
            }

            // Message Destination References
            IMessageDestinationRefDesc[] mdref = dd.getMessageDestinationRefDesc();
            for (int i = 0; i < mdref.length; i++) {
                // get information in descriptor
                String name = mdref[i].getMessageDestinationRefName();
                String mdname = null;
                mdname = mdref[i].getJndiName();

                LinkRef lref = new LinkRef(mdname);

                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, warName + ": Linking message-destination " + name + " -> " + mdname);
                }
                envCtx.rebind(name, lref);
            }

            // Service Ref
            // We bind a Reference when full configuration is provided
            // Otherwise we bind only a LinkRef in JNDI
            // Only done when the JAX-RPC Service is active
            if (jaxrpcService != null) {
                IServiceRefDesc[] serviceRefs = dd.getServiceRefDesc();
                for (int i = 0; i < serviceRefs.length; i++) {

                    // Create the Service from the ServiceRef description
                    String name = serviceRefs[i].getServiceRefName();
                    // create a full Reference
                    Reference ref = jaxrpcService.buildServiceRef(serviceRefs[i], parentClassLoader);
                    envCtx.rebind(name, ref);
                    if (logger.isLoggable(BasicLevel.DEBUG)) {
                        logger.log(BasicLevel.DEBUG, "Adding service-ref 'java:comp/env/" + name + "'");
                    }
                }
            }

            // Gets the bindings
            IENCBindingHolder encBindingHolder = dd.getENCBindingHolder();

            // Persistence context
            if (ezbInjectionHolder != null) {
                EZBPersistenceUnitManager persistenceUnitManager = ezbInjectionHolder.getPersistenceUnitManager();
                if (persistenceUnitManager != null) {
                    for (IENCBinding binding : encBindingHolder.getPersistenceContextBindings()) {
                        String encName = binding.getName();
                        String unitName = binding.getValue().getUnitName();
                        PersistenceContextType type = binding.getValue().getType();
                        EntityManager em = persistenceUnitManager.getEntityManager(unitName, type);

                        envCtx.rebind(encName, em);
                        if (logger.isLoggable(BasicLevel.DEBUG)) {
                            logger.log(BasicLevel.DEBUG, "Adding persistence-context 'java:comp/env/" + encName + "'");
                        }
                    }
                }

                // Persistence unit
                for (IENCBinding binding : encBindingHolder.getPersistenceUnitBindings()) {
                    if (persistenceUnitManager != null) {
                        String encName = binding.getName();
                        String unitName = binding.getValue().getUnitName();
                        EntityManagerFactory emf = persistenceUnitManager.getEntityManagerFactory(unitName);

                        envCtx.rebind(encName, emf);
                        if (logger.isLoggable(BasicLevel.DEBUG)) {
                            logger.log(BasicLevel.DEBUG, "Adding persistence-unit 'java:comp/env/" + encName + "'");
                        }
                    }
                }

                // EJBs
                EZBJNDIResolver jndiResolver = ezbInjectionHolder.getJNDIResolver();
                if (jndiResolver != null) {
                    for (IENCBinding binding : encBindingHolder.getEJBBindings()) {
                        String encName = binding.getName();
                        IJEjbEJB jEjbEJB = binding.getValue();
                        String interfaceName = jEjbEJB.getBeanInterface();
                        String beanName = jEjbEJB.getBeanName();

                        String jndiName;
                        try {
                            jndiName = jndiResolver.getEJBJNDIUniqueName(interfaceName, beanName);

                            // Bind a link to this JNDI name
                            envCtx.rebind(encName, new LinkRef(jndiName));
                            if (logger.isLoggable(BasicLevel.DEBUG)) {
                                logger.log(BasicLevel.DEBUG, "Adding ejb 'java:comp/env/" + encName + "' from JNDIName '"
                                        + jndiName + "'.");
                            }

                        } catch (EZBJNDIResolverException e) {
                            logger.log(BasicLevel.ERROR, "Cannot get JNDI name for enc name '" + encName + "'", e);

                        }

                    }
                }
            }

            // If JAXWS Service is present
            if (jaxwsService != null) {
                for (IENCBinding binding : encBindingHolder.getWebServicesBindings()) {

                    // Ask the service for Reference creation
                    String name = binding.getName();
                    Reference ref = jaxwsService.createNamingReference(binding.getValue());

                    // Bind the reference into the JNDI Context
                    envCtx.rebind(name, ref);
                    if (logger.isLoggable(BasicLevel.DEBUG)) {
                        logger.log(BasicLevel.DEBUG, "Adding WebServiceRef 'java:comp/env/" + name + "'.");
                    }
                }
            }

            // JNDI lookup prefix
            if (earDeployable != null && isVersioningEnabled()) {
                String jndiPrefix = versioningService.getPrefix(earDeployable);
                if (jndiPrefix != null) {
                    envCtx.rebind("JNDILookupPrefix", jndiPrefix);
                }
                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, "Adding JNDI-lookup-prefix 'java:comp/env/JNDILookupPrefix'");
                }
            }
        } catch (NamingException e) {
            String err = "Error while populating environment of the war file " + warName;
            logger.log(BasicLevel.ERROR, err + "  :" + e.getMessage());
            throw new JWebContainerServiceException(err, e);
        }
    }

    /**
     * Delegate the unregistration to the implementation of the web container and delete the environment associated to the WAR
     * file.
     * @param ctx the context which contains the configuration in order to undeploy a WAR.
     * @throws JWebContainerServiceException if the unregistration failed.
     */
    protected void unRegisterWar(final Context ctx) throws JWebContainerServiceException {

        // Gets the 2 parameters :
        // warURL, isEarCase, hostName and contextRoot.
        URL warURL = null;
        boolean isEarCase = true;
        try {
            warURL = (URL) ctx.lookup("warURL");
            isEarCase = ((Boolean) ctx.lookup("isEarCase")).booleanValue();
        } catch (NamingException e) {
            String err = "Error while getting parameter from context param.";
            logger.log(BasicLevel.ERROR, err + e.getMessage());
            throw new JWebContainerServiceException(err, e);
        }

        // get the file name for displaying message.
        String fileName = warURL.getFile();

        // Check if the war is deployed.
        War war = null;
        war = getWar(warURL);
        if (war == null) {
            String err = "Cannot undeploy war: '" + fileName + "' is not deployed.";
            logger.log(BasicLevel.ERROR, err);
            throw new JWebContainerServiceException(err);
        }

        // Check if the war can be undeployed (2 case authorized) :
        // - case EAR and war is in an EAR.
        // - case non EAR and war isn't in an EAR.
        if (isEarCase != war.isInEarCase()) {
            String err = "Cannot undeploy war: '" + fileName
                    + "' it is in an ear application. You must undeploy the ear associated.";
            logger.log(BasicLevel.ERROR, err);
            throw new JWebContainerServiceException(err);
        }

        // Call the specific method of the implementation of the web container.
        try {
            String hostName = war.getHostName();
            if (hostName != null) {
                ctx.rebind("hostName", war.getHostName());
            }
            ctx.rebind("contextRoot", war.getContextRoot());
            ctx.rebind("webClassLoader", warBindings.get(warURL));
        } catch (NamingException e) {
            String err = "Error when undeploying the war  '" + fileName + "'";
            logger.log(BasicLevel.ERROR, err + e.getMessage());
            throw new JWebContainerServiceException(err, e);
        }

        // Remove permission manager
        PermissionManager permissionManager = war.getPermissionManager();
        try {
            permissionManager.delete();
            permissionManager = null;
        } catch (PermissionManagerException pme) {
            logger.log(BasicLevel.ERROR, "Cannot remove permission manager for file '" + fileName + "'.", pme);
        }

        doUnRegisterWar(ctx);

        // undeploy webservices
        if (jaxrpcService != null) {
            jaxrpcService.undeployWebServices(ctx);
        }

        // Remove the context.
        URLClassLoader loader = (URLClassLoader) warBindings.remove(warURL);
        naming.unSetComponentContext(loader);

        // Remove classloader
        warLoaders.remove(warURL);

        // Indicates that the war is not in the deployed war.
        // (here we are sure that the war is not null and isn't in an ear).
        warDeployed.remove(war);
        unpackedWARs.remove(warURL);

        // Admin code
        unregisterWarMBean(getDomainName(), fileName);

        logger.log(BasicLevel.INFO, "War " + URLUtils.urlToFile(warURL).getName() + " no longer available");
    }

    /**
     * Unregister a WAR by delegating the operation to the unRegisterWar() method. This is used for JMX management.
     * @param fileName the name of the war to undeploy.
     * @throws RemoteException if rmi call failed.
     * @throws JWebContainerServiceException if the unregistration failed.
     */
    public void unRegisterWar(final String fileName) throws RemoteException, JWebContainerServiceException {

        // Convert the given file name to an url and check if the war is
        // deployed ...
        URL warURL = checkWarDeployed(fileName);

        // ... and do the undeployment.
        Context ctx = null;
        try {
            ctx = new ComponentContext(fileName);
            ctx.rebind("warURL", warURL);
            ctx.rebind("isEarCase", new Boolean(false));
        } catch (NamingException e) {
            String err = "Error when undeploying the war file '" + fileName + "'";
            logger.log(BasicLevel.ERROR, err + e.getMessage());
            throw new JWebContainerServiceException(err, e);
        }
        unRegisterWar(ctx);
    }

    /**
     * Deploy the given wars of an ear file with the specified parent classloader (ejb classloader or ear classloader). (This
     * method is only used for the ear applications, not for the web applications).
     * @param ctx the context containing the configuration to deploy the wars. 
* This context contains the following parameters :
* - urls the list of the urls of the wars to deploy.
* - earURL the URL of the ear application file.
* - parentClassLoader the parent classLoader of the wars.
* - earClassLoader the ear classLoader of the j2ee app.
* - altDDs the optional URI of deployment descriptor.
* - contextRoots the optional context root of the wars.
* @throws JWebContainerServiceException if an error occurs during the deployment. */ public void deployWars(final Context ctx) throws JWebContainerServiceException { // Gets the parameters from the context : // - urls the list of the urls of the wars to deploy. // - earURL the URL of the ear application file. // - earDeployable the EARDeployable of the ear application file. // - parentClassLoader the parent classLoader of the wars. // - earClassLoader the ear classLoader of the j2ee app. // - altDDs the optional URI of deployment descriptor. // - contextRoots the optional context root of the wars. URL[] urls = null; URL earURL = null; EARDeployable earDeployable = null; ClassLoader parentClassLoader = null; ClassLoader earClassLoader = null; URL[] altDDs = null; String[] contextRoots = null; EZBInjectionHolder ejbInjectionHolder = null; try { urls = (URL[]) ctx.lookup("urls"); earURL = (URL) ctx.lookup("earURL"); earDeployable = (EARDeployable) ctx.lookup("earDeployable"); parentClassLoader = (ClassLoader) ctx.lookup("parentClassLoader"); earClassLoader = (ClassLoader) ctx.lookup("earClassLoader"); altDDs = (URL[]) ctx.lookup("altDDs"); contextRoots = (String[]) ctx.lookup("contextRoots"); } catch (NamingException e) { String err = "Error while getting parameter from context param "; logger.log(BasicLevel.ERROR, err + e.getMessage()); throw new JWebContainerServiceException(err, e); } // Get Injection holder try { ejbInjectionHolder = (EZBInjectionHolder) ctx.lookup(EZBInjectionHolder.class.getName()); } catch (NamingException e) { logger.log(BasicLevel.DEBUG, "No persistence unit manager"); } // webDDManager.setAltDD(earClassLoader, urls, altDDs); // Deploy all the wars of the ear application. for (int i = 0; i < urls.length; i++) { // Get the name of a war to deploy. String fileName = URLUtils.urlToFile(urls[i]).getPath(); if (logger.isLoggable(BasicLevel.DEBUG)) { logger.log(BasicLevel.DEBUG, "Deploy war '" + fileName + "' for the ear service"); } // The context to give for the creation of the container // associated to the ejb-jar. Context contctx = null; try { contctx = new ComponentContext(fileName); contctx.rebind("warURL", urls[i]); contctx.rebind("parentClassLoader", parentClassLoader); contctx.rebind("earClassLoader", earClassLoader); contctx.rebind("earDeployable", earDeployable); contctx.rebind("earURL", earURL); if (altDDs[i] != null) { contctx.rebind("altDD", altDDs[i]); } if (contextRoots[i] != null) { contctx.rebind("contextRoot", contextRoots[i]); } // Injection holder if (ejbInjectionHolder != null) { contctx.rebind(EZBInjectionHolder.class.getName(), ejbInjectionHolder); } registerWar(contctx); } catch (Exception e) { // A war is corrupted so undeploy all the deployed war // of the ear application. logger.log(BasicLevel.ERROR, "Error when deploying '" + fileName + "'"); logger.log(BasicLevel.ERROR, e.getMessage()); logger.log(BasicLevel.ERROR, "Undeploy war of the ear application"); for (int j = 0; j < i; j++) { String warFileName = urls[j].getFile(); try { // Try to undeploy a war of the ear application. ComponentContext context = new ComponentContext(warFileName); context.rebind("warURL", urls[j]); context.rebind("isEarCase", new Boolean(true)); unRegisterWar(context); } catch (Exception ex) { // Cannot undeploy a war of the ear application // So there is an error message. logger.log(BasicLevel.ERROR, "Error when undeploying '" + warFileName + "'"); logger.log(BasicLevel.ERROR, ex.getMessage()); logger.log(BasicLevel.ERROR, "Cannot undeploy war of the ear application"); } } throw new JWebContainerServiceException("Error during the deployment", e); } } } /** * Undeploy the given wars of an ear file with the specified parent classloader (ejb classloader or ear classloader). (This * method is only used for the ear applications, not for the war applications). * @param urls the list of the urls of the wars to undeploy. */ public void unDeployWars(final URL[] urls) { for (int i = 0; i < urls.length; i++) { String warFileName = urls[i].getFile(); try { // Try to undeploy a war of the ear application. ComponentContext context = new ComponentContext(warFileName); context.rebind("warURL", urls[i]); context.rebind("isEarCase", new Boolean(true)); unRegisterWar(context); } catch (Exception ex) { // Cannot undeploy a war of the ear application // So there is an error message. logger.log(BasicLevel.ERROR, "Error when undeploying '" + warFileName + "'"); logger.log(BasicLevel.ERROR, ex.getMessage()); logger.log(BasicLevel.ERROR, "Cannot undeploy war of the ear application"); } } } /** * Get the war identified by its URL (.war). * @param url the URL of the war to get. * @return the war indentified by its URL, or null if the war is not found. */ public War getWar(final URL url) { Iterator wars = warDeployed.iterator(); while (wars.hasNext()) { War war = (War) wars.next(); if (war.getWarURL().equals(url)) { return war; } } return null; } /** * Get a list of wars identified by their Context. * @param pContext the context of the war to get. * @return the list of wars indentified by their Context, or an empty list if no wars are found. */ protected List getWar(final String pContext) { List checkDeployed = new ArrayList(); Iterator wars = warDeployed.iterator(); while (wars.hasNext()) { War war = (War) wars.next(); if (war.getContextRoot().equals(pContext)) { checkDeployed.add(war); } } return checkDeployed; } /** * Make a cleanup of the cache of deployment descriptor. This method must be invoked after the ear deployment by the EAR * service. * @param earClassLoader the ClassLoader of the ear application to remove from the cache. */ public void removeCache(final ClassLoader earClassLoader) { WebDeploymentDescManager.getInstance().removeCache(earClassLoader); } /** * Check if the specified file name correspond to a file which is located relatively to where the JOnAS server is launched * or in the $JONAS_BASE/web-apps. * @param fileName the file to check if it exists. * @return the URL of the file found (either relatively to the JOnAS server or to the $JONAS_BASE/web-apps). * @throws JWebContainerServiceException if the specified file does't exists. */ protected URL checkWarFile(final String fileName) throws JWebContainerServiceException { File f = null; try { f = new File(fileName).getCanonicalFile(); if (!f.exists()) { boolean found = false; } } catch (IOException e) { String err = "Invalid war file name '" + fileName; logger.log(BasicLevel.ERROR, err); throw new JWebContainerServiceException(err, e); } URL warURL = null; try { warURL = f.toURL(); } catch (MalformedURLException e) { String err = "Invalid war file name '" + fileName + "'."; logger.log(BasicLevel.ERROR, err + e.getMessage()); throw new JWebContainerServiceException(err, e); } return warURL; } /** * Check if the specified file is already deployed in the JOnAS server and return the URL of this deployed war file. * @param fileName the name of the WAR file to check. * @return the URL of the deployed war file. * @throws JWebContainerServiceException if the file name doesn't correspond to a deployed war. */ protected URL checkWarDeployed(final String fileName) throws JWebContainerServiceException { URL url = null; try { Iterator wars = warDeployed.iterator(); while (wars.hasNext()) { War war = (War) wars.next(); url = (new File(fileName).getCanonicalFile()).toURL(); URL deployedWarURL = war.getWarURL(); String deployedWarPath = deployedWarURL.toString(); // Delete the char '/' at the end of the URL if present // FIXME: very strange to use File.separator on an URL as it should be always / ! ?? if (deployedWarPath.endsWith(File.separator)) { deployedWarPath = deployedWarPath.substring(0, deployedWarPath.length() - 1); } // For unpacked directory on Linux, the URL has a trailing / so check it also if (deployedWarPath.equals(url.toString()) ||(deployedWarPath + "/").equals(url.toString())) { return deployedWarURL; } } String err = "Cannot undeploy war: '" + fileName + "' is not deployed."; logger.log(BasicLevel.ERROR, err); throw new JWebContainerServiceException(err); } catch (MalformedURLException e) { String err = "Invalid war file name '" + fileName + "'."; logger.log(BasicLevel.ERROR, err + e.getMessage()); throw new JWebContainerServiceException(err, e); } catch (IOException e) { String err = "Invalid war file name '" + fileName; logger.log(BasicLevel.ERROR, err); throw new JWebContainerServiceException(err, e); } } /** * @return current number of wars deployed in the JOnAS server */ public Integer getCurrentNumberOfWars() { return new Integer(warDeployed.size()); } /** * Test if the specified filename is already deployed or not. * @param fileName the name of the war file. * @return true if the war is deployed, else false. */ public boolean isWarLoaded(final String fileName) { URL url = null; boolean isLoaded = false; try { // Absolute filename try { url = new File(fileName).getCanonicalFile().toURL(); // Check if the war is already deployed or not if (getWar(url) != null) { isLoaded = true; } else { // Not found force to test in relative Webapps directory url = null; } } catch (Exception e) { url = null; } } catch (Exception e) { String err = "Can not found if the war is deployed or not"; logger.log(BasicLevel.ERROR, err); return false; } return isLoaded; } /** * Return the list of all loaded web applications. * @return The list of deployed web applications */ public List getDeployedWars() { List al = new ArrayList(); for (Iterator wars = warDeployed.iterator(); wars.hasNext();) { War war = (War) wars.next(); URL warURL = war.getWarURL(); al.add(warURL.getFile()); } return al; } /** * Gets the name of the server which is the web container. * @return the name of the server which is the web container */ public String getServerName() { if (serverName == null) { updateServerInfos(); } return serverName; } /** * Gets the version of the server which is the web container. * @return the version of the server which is the web container */ public String getServerVersion() { if (serverVersion == null) { updateServerInfos(); } return serverVersion; } /** * Test if the specified unpack name is already deployed or not. This method is defined in the {@link JWebContainerService} * interface. * @param unpackName the name of the ear file. * @return true if the ear is deployed, else false. */ public boolean isWarDeployedByWorkName(final String unpackName) { for (URL unpackedURL : unpackedWARs.values()) { if (URLUtils.urlToFile(unpackedURL).getName().equals(unpackName)) { return true; } } return false; } /** * Update info of the serverName and serverVersion. */ protected abstract void updateServerInfos(); /** * Return the Default host name of the web container. * @return the Default host name of the web container. * @throws JWebContainerServiceException when it is impossible to get the Default Host. */ public abstract String getDefaultHost() throws JWebContainerServiceException; /** * Return the Default HTTP port number of the web container (can be null if multiple HTTP connector has been set). * @return the Default HTTP port number of the web container. * @throws JWebContainerServiceException when it is impossible to get the Default Http port. */ public abstract String getDefaultHttpPort() throws JWebContainerServiceException; /** * Return the Default HTTPS port number of the web container (can be null if multiple HTTPS connector has been set). * @return the Default HTTPS port number of the web container. * @throws JWebContainerServiceException when it is impossible to get the Default Https port. */ public abstract String getDefaultHttpsPort() throws JWebContainerServiceException; /** * @return Returns the logger. */ protected static Logger getLogger() { return logger; } /** * @return Returns the naming. */ protected JNamingManager getNaming() { return naming; } /** * @param serverName The serverName to set. */ protected void setServerName(final String serverName) { this.serverName = serverName; } /** * @param serverVersion The serverVersion to set. */ protected void setServerVersion(final String serverVersion) { this.serverVersion = serverVersion; } /** * Holds the ClassLoader used to retrieve the WebApp JNDI Context and the JOnAS Webapp ClasLoader. * @author Guillaume Sauthier */ public class WebLoaderHolder { /** * Web ClassLoader used by JOnAS. */ private WebappClassLoader jonasWebLoader; /** * Web ClassLoader used to retrieve the JNDI Context of the webapp. */ private ClassLoader envWebLoader; /** * Constructs a WebLoaderHolder with jonas Loader and en Loader. * @param jonas JOnAS Webapp Loader * @param env Environnement ClassLoader */ public WebLoaderHolder(final WebappClassLoader jonas, final ClassLoader env) { jonasWebLoader = jonas; envWebLoader = env; } /** * @return Returns the jonasWebLoader. */ public WebappClassLoader getJonasWebLoader() { return jonasWebLoader; } /** * @return Returns the envWebLoader. */ public ClassLoader getEnvWebLoader() { return envWebLoader; } /** * @param envWebLoader The envWebLoader to set. */ public void setEnvWebLoader(final ClassLoader envWebLoader) { this.envWebLoader = envWebLoader; } /** * @param jonasWebLoader The jonasWebLoader to set. */ public void setJonasWebLoader(final WebappClassLoader jonasWebLoader) { this.jonasWebLoader = jonasWebLoader; } } /** * @return the {@link JComponentContextFactory}. */ protected JComponentContextFactory getContextFactory() { return contextFactory; } // Admin code (JMX based) // --------------------- /** * Register WEB Container Service MBean. * @param service web container service to manage * @param domainName domain name */ protected void registerWebServiceMBean(final Object service, final String domainName) { ObjectName on = JonasObjectName.webContainerService(domainName); jmxService.registerMBean(service, on); } /** * Unregister WEB Container Service MBean. * @param domainName domain name */ protected void unregisterWebServiceMBean(final String domainName) { ObjectName on = JonasObjectName.webContainerService(domainName); jmxService.unregisterMBean(on); } /** * Register War MBean. * @param war War instance to manage * @param domainName domain name * @param fileName the war file name */ protected void registerWarMBean(final War war, final String domainName, final String fileName) { // ObjectName on = null; try { ObjectName on = JonasObjectName.war(domainName, fileName); jmxService.registerMBean(war, on); } catch (MalformedObjectNameException e) { logger.log(BasicLevel.WARN, "Could not register War MBean", e); } } /** * Unegister War MBean. * @param domainName domain name * @param fileName the war file name */ protected void unregisterWarMBean(final String domainName, final String fileName) { // ObjectName on = null; try { ObjectName on = JonasObjectName.war(domainName, fileName); jmxService.unregisterMBean(on); } catch (MalformedObjectNameException e) { logger.log(BasicLevel.WARN, "Could not unregister War MBean", e); } } /** * @param jmxService the jmxService to set */ public void setJmxService(final JmxService jmxService) { this.jmxService = jmxService; } /** * @param jaxrpcService the jaxrpcService to set */ public void setJAXRPCService(final IJAXRPCService jaxrpcService) { this.jaxrpcService = jaxrpcService; } /** * @param naming the naming to set */ public void setNaming(final JNamingManager naming) { this.naming = naming; } /** * @param contextFactory the contextFactory to set */ public void setContextFactory(final JComponentContextFactory contextFactory) { this.contextFactory = contextFactory; } /** * @param deployerManager the {@link IDeployerManager} to use. */ public void setDeployerManager(final IDeployerManager deployerManager) { this.deployerManager = deployerManager; } /** * Create working directory for applications. */ protected void initWorkingDirectory() { if (workSingleWebAppsFile == null) { // Create $JONAS_BASE/work/webapps/single directory file workSingleWebAppsFile = new File(WORK_WEBAPPS_DIR + File.separator + getServerProperties().getServerName() + File.separator + SINGLE_WORK_WEBAPPS_DIR_SUFFIX); workSingleWebAppsFile.mkdirs(); } } /** * Method called when the workCleanerService is bound to the component. * @param workCleanerService the workCleanerService reference */ public void setWorkCleanerService(final WorkCleanerService workCleanerService) { initWorkingDirectory(); File fileLog = new File(workSingleWebAppsFile.getPath() + File.separator + getServerProperties().getServerName() + ".log"); if (!fileLog.exists()) { try { // Create dirs fileLog.getParentFile().mkdirs(); fileLog.createNewFile(); } catch (IOException e) { logger.log(BasicLevel.ERROR, "cannot create the log file" + fileLog, e); } } // Create the logger try { deployerLog = new DeployerLog(fileLog); CleanTask cleanTask = new WarCleanTask(this, deployerLog); workCleanerService.registerTask(cleanTask); workCleanerService.executeTasks(); } catch (DeployerLogException e) { logger.log(BasicLevel.ERROR, "Cannot register the clean task", e); } } /** * @return Associates an URL of an unpacked WAR file to its classloader. */ protected Hashtable getWarLoaders() { return warLoaders; } /** * @return Associates an URL of a deployed WAR file to its classloader. */ protected Hashtable getWarBindings() { return warBindings; } /** * @return List of the war deployed by the Web container Service. */ protected List getWarDeployed() { return warDeployed; } /** * @return Reference to the JAX-RPC service. */ protected IJAXRPCService getJAXRPCService() { return jaxrpcService; } /** * @return Application Classloader. */ protected ClassLoader getAppsClassLoader() { return extClassLoader; } /** * @param versioningService The versioning service to set. */ public void setVersioningService(final VersioningService versioningService) { this.versioningService = versioningService; } /** * Sets the versioning service to null. */ public void unsetVersioningService() { this.versioningService = null; } /** * @return The versioning service. */ public VersioningService getVersioningService() { return this.versioningService; } /** * @return Whether versioning is enabled. */ public boolean isVersioningEnabled() { return (versioningService != null && versioningService.isVersioningEnabled()); } /** * @param warDeployableMetadataFactory the deployable metadata factory service */ public void setWarDeployableMetadataFactory(final IWarDeployableMetadataFactory warDeployableMetadataFactory) { WarDeployableMetadataFactoryHolder.setWarDeployableMetadataFactory(warDeployableMetadataFactory); } /** * Store the reference to the JAX-WS Service. * @param jaxwsService jaxws Service */ public void bindJaxwsService(final IJAXWSService jaxwsService) { this.jaxwsService = jaxwsService; } /** * @return the jaxws service */ protected IJAXWSService getJAXWSService() { return this.jaxwsService; } /** * Release the reference to the JAWS Service. * @param jaxwsService jaxws Service */ public void unbindJaxwsService(final IJAXWSService jaxwsService) { this.jaxwsService = null; } /** * @param service the EJB3 Service to be injected. */ public void setEjb3Service(final IEasyBeansService service) { this.ejb3Service = service; } /** * Unbind the {@link IEasyBeansService}. */ public void unsetEjb3Service() { this.ejb3Service = null; } /** * Enable or not the on demand feature. * @param onDemandFeatureEnabled boolean true/false */ public void setOnDemandFeature(final boolean onDemandFeatureEnabled) { this.onDemandFeatureEnabled = onDemandFeatureEnabled; } /** * Sets the redirect port number * @param onDemandRedirectPort the given port used for OnDemand proxy */ public void setOnDemandRedirectPort(final int onDemandRedirectPort) { if (isStarted()) { return; } this.onDemandRedirectPort = onDemandRedirectPort; } /** * @return true if the on demand feature is enabled and in development mode. */ public boolean isOnDemandFeatureEnabled() { return onDemandFeatureEnabled && getServerProperties().isDevelopment(); } public int getOnDemandRedirectPort() { return onDemandRedirectPort; } public int getRandomPort() { Random random = new Random(); random.setSeed(System.currentTimeMillis()); int portNumber = 0; int retry = 0; while (portNumber == 0 && retry < 50) { // try to use by starting at 8950 branch int randomPort = 8950 + random.nextInt(50); ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(randomPort); portNumber = randomPort; } catch (IOException e) { // invalid port number, try a new one logger.log(BasicLevel.DEBUG, "unable to listen on the server socket", e); } finally { if (serverSocket != null) { try { serverSocket.close(); } catch (IOException e) { logger.log(BasicLevel.DEBUG, "unable to close server socket", e); } } } // new try retry++; } if (retry == 50) { throw new IllegalStateException("Unable to choose a random free port"); } return portNumber; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy