FileDocCategorySizeDatePackage
PELaunch.javaAPI DocGlassfish v2 API32231Tue Jul 31 23:51:24 BST 2007com.sun.enterprise.server

PELaunch

public class PELaunch extends Object
New Start up class for PE/RI. For AS9 this is set as the default in processLauncher.xml. To disable the new classloader hierarchy the following needs to be done: - Modify the system property '-Dcom.sun.aas.processName="as9-server"' to '-Dcom.sun.aas.processName="s1as8-server' in the startserv/stopserv scripts - Modify system-classpath attribute in the relevant java-config to if PE: "com.sun.aas.classloader.serverClassPath" element in processLauncher.xml if EE: "com.sun.aas.classloader.serverClassPath.ee" element in processLauncher.xml
author
Harsha RA, Sivakumar Thyagarajan

Fields Summary
private static final long
START_TIME_MILLIS
public static final String
USE_NEW_CLASSLOADER_PROPERTY
public static final String
PROPERTIES_FILES
private static final String
CLASSPATH_PREFIX_PROPERTY
private static final String
CLASSPATH_SUFFIX_PROPERTY
private static final String
SERVER_CLASSPATH_PROPERTY
private static final String
fileSeparator
private static final String
pathSeparator
private static final String
installRoot
private static final List
_appserverClasspath
private static final List
_sharedClasspath
private static final List
_optionalClasspath
private static volatile com.sun.appserv.server.util.ASURLClassLoader
_sharedClassLoader
private static volatile com.sun.appserv.server.util.ClassLoaderChain
_optionalChain
private static volatile com.sun.appserv.server.util.ClassLoaderChain
_asChain
private static final Map
addonsMap
private static final Map
addOnsManifestsMap
private static volatile com.sun.appserv.server.util.ClassLoaderChain
_addOnsChain
private static final boolean
bDebug
Constructors Summary
Methods Summary
private static synchronized java.util.List_getSharedClasspathInternal()

        if(_sharedClasspath.size() == 0) {
            initialiseSharedClasspath();
            assert(_sharedClasspath.size() != 0);
        }
            return _sharedClasspath;
    
private static voidappendOtherJarsToSharedChain()
Adds all the remaining jars in the installRoot/lib folder

        final List<String> list = new ArrayList<String>();
        list.addAll(_getSharedClasspathInternal());
        list.addAll(getAppServerClasspath());
        list.addAll(getOptionalClasspath());
        final File[] files = getAllLibrariesInLib(installRoot);
        
        //Remove all libraries listed in the excludesList.
        final String excludesListString = System.getProperty(
        		"com.sun.aas.classloader.excludesList", "");
        final List<String> excludesList = getLibraryList(
        		installRoot + fileSeparator + "lib" + fileSeparator, 
        		excludesListString);
        
        for(final File file:files){
            try{
                if((!list.contains(file.getCanonicalPath())) 
                		&& (!(isInExcludesList(excludesList, file)))){
                    _getSharedClasspathInternal().add(file.getCanonicalPath());
                    logFine("appendOtherJarsToSharedChain - " +
                    		"added " + file.getCanonicalPath());
                } else {
                	logFine("appendOtherJarsToSharedChain - " +
                			"not adding " + file.getCanonicalPath());
                    logFine(file.getCanonicalPath() + " exists in list ? " + list.contains(file.getCanonicalPath()));
                    logFine(file.getCanonicalPath() + "in excludes list ? " + isInExcludesList(excludesList, file));
                }
            }catch(java.io.IOException ioe){
                System.err.println("Error getting " + file.getAbsolutePath() 
                		+ " " + ioe.getMessage());
            }
        }

        //Finally ensure that the libraries listed in the includes list is added
        //to the shared chain
        final String includesListString = System.getProperty(
        		"com.sun.aas.classloader.includesList", "");
        final List<String> includesList = getLibraryList(installRoot, includesListString);
        for (final String f : includesList) {
			if(!(_sharedClasspath.contains(f))){
				logFine("appendOtherJarsToSharedChain - " +
						"adding " + f + " via includes");
				_sharedClasspath.add(f);
			}
            }
        
public static synchronized java.util.ListgetAddOnsClasspath()
Gets the paths for all addons. Used in ASClassLoaderUtil while computing WebModuleClassPath. This method is marked synchronized because there might be multiple callers to get addons classpath while we are iterating through the addons Map. [via ASClassLoaderUtil.getWebModuleClassPath]

return
An unmodifiable List containing the absolute paths of all libraries in the addons classloader chain.

    	final List<String> s = new ArrayList<String>();
    	for (final List<String> lst : addOnsManifestsMap.values()) {
			s.addAll(lst);
		}
    	logFine("addons classpath : " + s);
    	return Collections.unmodifiableList(s);
    
private static java.io.File[]getAllLibrariesInLib(java.lang.String asLib)

        final File installLib = new File(asLib,"lib");
        final File [] files = installLib.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                if(name.endsWith(".jar") || name.endsWith(".zip")) {
                    return true;
                } else {
                return false;
            }
            }
        });
        return files;
    
public static java.lang.ClassLoadergetAppServerChain()

        return _asChain;
    
private static java.util.ListgetAppServerClasspath()
Returns an unmodifiable list of all libraries in the appserver chain.

return
An unmodifiable List containing the absolute paths of all libraries in the appserver chain.

        return Collections.unmodifiableList(_appserverClasspath);
    
private static java.util.ListgetLibraryList(java.lang.String libraryRoot, java.lang.String librariesString)
Gets a List of absolute path names for the passed in librariesString rooted at libraryRoot

    	return updateClasspathList(libraryRoot, librariesString, 
    			new ArrayList<String>());
    
private static java.util.ListgetManifestAddonJars()
Read all Non-manifest jars under lib/addons directory and compute all addons and their dependencies and update manifestJars and addOnsManifestsMap accordingly

        final List<String> manifestJars = new ArrayList<String>();
        JarFile file = null;
        try {
        final String addonDir = installRoot + fileSeparator + "lib" + fileSeparator + "addons";
        final File libAddonDirectory = new File(addonDir);
        if(!libAddonDirectory.isDirectory())
            return manifestJars;
        
        final File[] fileArray = libAddonDirectory.listFiles();
        for(int i = 0;i<fileArray.length;i++) {
                final String addonJar = fileArray[i].getName();
                String addOnName = "";
                String jarExtension = "";
                int dotLastIndex = addonJar.lastIndexOf(".");
                if(dotLastIndex != -1) {
                    jarExtension = addonJar.substring(dotLastIndex + 1);
                    addOnName = addonJar.substring(0, dotLastIndex - 1);
                }
                
                
                if(jarExtension.equalsIgnoreCase("jar")) {
                    manifestJars.add(fileArray[i].getAbsolutePath()); 
                    updateAddOnManifests(addOnName, fileArray[i].getAbsolutePath());
                    
                    file = new JarFile(fileArray[i].getAbsolutePath());
                    Manifest mf = file.getManifest();
                    Attributes attributes = null;
                    if(mf != null) {
                        attributes = mf.getMainAttributes();
                        if(attributes != null) {
                            String classPath = attributes.getValue(Attributes.Name.CLASS_PATH);
                            if(classPath != null && !classPath.trim().equals("")) {
                                StringTokenizer stoken = new StringTokenizer(classPath);
                                while(stoken.hasMoreTokens()) {
                                    String classPathJar = addonDir + fileSeparator + stoken.nextElement();
                                    manifestJars.add(classPathJar);
                                    updateAddOnManifests(addOnName, classPathJar);
                                }
                            }
                            //Logger.getAnonymousLogger().log(Level.FINE, "Main Class "+mainClass); 
                        }
                        file.close();
                    }
                }
        }
        }catch(Exception e) {
            e.printStackTrace(System.err);
        }finally {
            try {
            if(file != null)
                file.close();
            }catch(Exception ex) {
                ex.printStackTrace(System.err);
            }
        }
        //Logger.getAnonymousLogger().log(Level.INFO, "nonManifestJars list: "+nonManifestJars);
        return manifestJars;
    
public static java.lang.ClassLoadergetOptionalChain()

        return _optionalChain;
    
private static java.util.ListgetOptionalClasspath()
Returns an unmodifiable list of all libraries in the optional chain.

return
An unmodifiable List containing the absolute paths of all libraries in the optional chain.

        return Collections.unmodifiableList(_optionalClasspath);
    
public static java.util.ListgetServerClassPath(java.lang.String configDir, java.lang.String domainDir)
SPI for Verifier to use when it runs in appserver mode. Returns the server classpath for an application. This as now includes all libraries in installRoot and server-classpath.

        ASenvPropertyReader reader = new ASenvPropertyReader(configDir,false);
        reader.setSystemProperties();

        //Add all libraries in as-install-dir/lib
        final String asLib = installRoot + fileSeparator ;        
        final List<String >serverClassPathList = new ArrayList<String>();
        final File[] fls= getAllLibrariesInLib(asLib); 
        
        for (File element : fls) {
            serverClassPathList.add(element.getAbsolutePath()); 
        }
        
        //add server-classpath
        final String mqlib = System.getProperty(SystemPropertyConstants.IMQ_LIB_PROPERTY);
        final String antlib = System.getProperty(SystemPropertyConstants.ANT_LIB_PROPERTY);
        final String jdmklib = System.getProperty(SystemPropertyConstants.JDMK_HOME_PROPERTY);
        final String hadbRoot = System.getProperty(SystemPropertyConstants.HADB_ROOT_PROPERTY);
        
        final String[] peServerClassPath = {installRoot + "/lib/install/applications/jmsra/imqjmsra.jar",
                        mqlib + "/jaxm-api.jar" , mqlib + "/fscontext.jar",
                        mqlib + "/imqbroker.jar", mqlib + "/imqjmx.jar",
                        mqlib + "/imqxm.jar",
                        antlib + "/ant.jar", jdmklib + "/lib/jdmkrt.jar"} ;
        final String[] eeServerClassPath = {hadbRoot + "/lib/hadbjdbc4.jar",
                        jdmklib + "/lib/jdmkrt.jar",hadbRoot + "/lib/dbstate.jar",
                        hadbRoot + "/lib/hadbm.jar", hadbRoot + "/lib/hadbmgt.jar"} ;
        for (final String element : peServerClassPath) {
            File f = new File(element);
            if(f.exists()) {
                serverClassPathList.add(f.getAbsolutePath());
            }
        }
        
        for (final String element : eeServerClassPath) {
            File f = new File(element);
            if(f.exists()) {
                serverClassPathList.add(f.getAbsolutePath());
            }
        }
        
        //add jars placed in domain-dir/lib
        final File[] domainfls= getAllLibrariesInLib(domainDir + fileSeparator);
        for (File elt : domainfls) {
            serverClassPathList.add(elt.getAbsolutePath()); 
        }

        logFine("Server Classpath for verifier " + serverClassPathList + "\n");
        Logger.getAnonymousLogger().log(Level.FINE, "Server Classpath for verifier " + serverClassPathList);
        return serverClassPathList;
    
public static synchronized java.util.ListgetServerClasspath()
ServerClassPath was earlier provided as "server-classpath" attribute in the "java-config" element of domain.xml and this is used by BaseManager Only. Marked synchronized as there could multiple threads trying to get server classpath.

        final String asLib = installRoot + fileSeparator + "lib" + fileSeparator;
        String serverJarsList = System.getProperty("com.sun.aas.classloader.serverClassPath");

        if (isEE()) {
            final String eeServerJarsList = System.getProperty("com.sun.aas.classloader.serverClassPath.ee");
            serverJarsList  += ("," + eeServerJarsList);
        }
        logFine("serverClassPathJarsList " + serverJarsList);
        
        final List<String> serverClasspathList = getLibraryList(asLib, serverJarsList);
        return serverClasspathList;
    
public static java.lang.ClassLoadergetSharedChain()



    //By default we set the new classloader hierarchy as the default 
     
        if (System.getProperty(USE_NEW_CLASSLOADER_PROPERTY) == null) {
            System.setProperty(USE_NEW_CLASSLOADER_PROPERTY, "true");
        }
    
        return _sharedClassLoader;
    
public static synchronized java.util.ListgetSharedClasspath()
Returns an unmodifiable list of the shared classpath components, for use by external classes like ASClassLoaderUtil.

return
An unmodifiable List containing the absolute paths of all libraries in the shared classloader chain.

    	return Collections.unmodifiableList(_sharedClasspath);
    
public static longgetStartTimeMillis()

         return START_TIME_MILLIS; 
private static java.net.URL[]getURLList(java.util.List librariesList)

        int i=0;
        final String [] sharedJars = librariesList.toArray(new String[] {});
        final URL [] urls = new URL[sharedJars.length];
        for(final String s:sharedJars){
            try{
                URL url = (new File(s)).toURI().toURL();
                logFine(s + " exists ? "+ (new File(s)).exists());
                urls[i++] = url;
            }catch(MalformedURLException e){
                Logger.getAnonymousLogger().warning(e.getMessage());
                Logger.getAnonymousLogger().log(Level.WARNING, "Exception while" 
                		+ "setting up shared chain", e);
            }
        }
        return urls;
    
private static voidinitOptionalOverrideableJars()

        final String asLib = installRoot + fileSeparator + "lib" + fileSeparator;
        String optionalJarsString = System.getProperty("com.sun.aas.classloader.optionalOverrideableChain");
        if (isEE()) {
            final String eeOptionalJarsList = System.getProperty("com.sun.aas.classloader.optionalOverrideableChain.ee");
            optionalJarsString  += ("," + eeOptionalJarsList);
        }
        
        logFine(" optionalOverrideableChain" + optionalJarsString );
        
        updateClasspathList(asLib, optionalJarsString, _optionalClasspath);
        logFine("Optional overrideable chain classpath : " + _optionalClasspath + "\n");
    
private static voidinitialiseSharedClasspath()

        //PE/EE Shared jars        
        final String asLib = installRoot + fileSeparator + "lib" + fileSeparator;        
        String sharedJarsList = System.getProperty("com.sun.aas.classloader.sharedChainJars");
        if (isEE()) {
            final String eeSharedJarsList = System.getProperty("com.sun.aas.classloader.sharedChainJars.ee");
            sharedJarsList  += ("," + eeSharedJarsList);
        }
        logFine("shared jar list " + sharedJarsList);
        
        final List<String> shr = getLibraryList(asLib, sharedJarsList);
        
        //Computing classpath prefix,suffix and server classpath
        final String prefixString = System.getProperty(CLASSPATH_PREFIX_PROPERTY);
        logFine(" prefixString " + prefixString );
        String[] classpathPrefix = null;
        if (!isEmpty(prefixString)) {
        	classpathPrefix = prefixString.split("" +File.pathSeparatorChar);
        }
        
        final String suffixString = System.getProperty(CLASSPATH_SUFFIX_PROPERTY);
        logFine(" suffixString " + suffixString);
        String[] classpathSuffix = null;
        if (!isEmpty(suffixString)) {
        	classpathSuffix = suffixString.split("" +File.pathSeparatorChar);
        }
        
        final String serverClassPathString = System.getProperty(SERVER_CLASSPATH_PROPERTY);
        logFine(" serverClassPathString " + serverClassPathString);
        String[] serverClassPath = null;
        if (!isEmpty(serverClassPathString)) {
        	serverClassPath = serverClassPathString.split("" +File.pathSeparatorChar);
        }
        
        //Creating final shared chain list.
        
        if (classpathPrefix != null) _sharedClasspath.addAll(Arrays.asList(classpathPrefix));
        _sharedClasspath.addAll(shr);
        if (serverClassPath != null) _sharedClasspath.addAll(Arrays.asList(serverClassPath));
        if (classpathSuffix != null) _sharedClasspath.addAll(Arrays.asList(classpathSuffix));
    
private static booleanisEE()
Determines if the AS process is running in EE. XXX: to refactor this to use the common implementation.

        boolean isEE = false;
        final String eepffc = "com.sun.enterprise.ee.server.pluggable.EEPluggableFeatureImpl";
        final String pn = "com.sun.appserv.pluggable.features";
        final String pv = System.getProperty(pn);
        if (eepffc.equals(pv)) {
            isEE = true;
        }
        return ( isEE );
    
private static booleanisEmpty(java.lang.String s)

    	return ((s == null) || (s.trim().length() == 0));
    
private static booleanisInExcludesList(java.util.List excludesList, java.io.File f)

    	return excludesList.contains(f.getCanonicalPath());
private static voidlogFine(java.lang.String s)

        if(bDebug) {
            System.err.println(s);
        }
    
public static voidmain(java.lang.String[] args)
Entry point into the application server

        try{
            Class peMainClass = null;
            
            if(Boolean.getBoolean(USE_NEW_CLASSLOADER_PROPERTY)){
                ASenvPropertyReader reader = new ASenvPropertyReader(
                    System.getProperty(SystemPropertyConstants.CONFIG_ROOT_PROPERTY),
                    false);
                reader.setSystemProperties();
                
                
                setupClassloaders();
                //Use the new classloader hierarchy
                peMainClass = _asChain.loadClass(
                                "com.sun.enterprise.server.PEMain", true);
                Thread.currentThread().setContextClassLoader(_asChain);            
            } else {
                peMainClass = Class.forName("com.sun.enterprise.server.PEMain");
            }
            
            Class[] argTypes = new Class[]{String[].class};
            Method m = peMainClass.getMethod("main", argTypes);           
            Object[] argListForInvokedMain = new Object[]{args};
            m.invoke(null, argListForInvokedMain);
        } catch(Exception e) {
            e.printStackTrace(System.err);
            System.exit(1);
        }
    
private static voidprepareAppServerJars()

        //AS only jars
        final String asLib = installRoot + fileSeparator + "lib" + fileSeparator;
        String appserverJarsStr = System.getProperty("com.sun.aas.classloader.appserverChainJars");
        if (isEE()) {
            final String eeAppserverJarsList = System.getProperty("com.sun.aas.classloader.appserverChainJars.ee");
            appserverJarsStr  += ("," + eeAppserverJarsList);
        }
        logFine("appserverJarsString " + appserverJarsStr );
        
        updateClasspathList(asLib, appserverJarsStr, _appserverClasspath);
        logFine("Application server classpath : " + _appserverClasspath + "\n");
    
private static voidsetupAddOnChain()

    	logFine("setting up addon chain");
        _addOnsChain = new ClassLoaderChain(_sharedClassLoader);
        _addOnsChain.setName("Addons Chain");
        getManifestAddonJars();
        
        for (final String addOnName : addOnsManifestsMap.keySet()) {
        	//create a classloader for an addon
			//get all jars associated with this addon
			URL[] addOnURLs = getURLList(addOnsManifestsMap.get(addOnName));
			logFine(" addon: " + addOnName + " urls: " + addOnURLs);
			
			//create a URLClassLoader for this addon - parent set to shared classloader
			ASURLClassLoader addonClassLoader = new ASURLClassLoader(addOnURLs, _sharedClassLoader);
			//keep a map so that we can remove it during uninstall-addon
			addonsMap.put(addOnName, addonClassLoader);
			
			//add it to the AddOns chain
			_addOnsChain.addToList(addonClassLoader);
		}
	
private static voidsetupAppServerChain()
The application server chain is composed of jars/libraries that are used and visible to application server classes only. The optional overrideable chain is also a part of this chain. The Shared ClassLoader chain is set as the parent of the application server chain.

        final URL[] urls = getURLList(_appserverClasspath);
        
        //parent set to Shared Chain
        _asChain = new ClassLoaderChain(_addOnsChain);
        _asChain.setName("ASChain");
        
        final ASURLClassLoader asimplloader = new ASURLClassLoader(urls, _asChain);
        asimplloader.setName("asimpl");
        _asChain.addToList(asimplloader);
        _asChain.addToList(_optionalChain);        
    
private static synchronized voidsetupClassloaders()

        prepareAppServerJars();
        initOptionalOverrideableJars();
        appendOtherJarsToSharedChain();
        setupSharedChain();
        setupAddOnChain();
        setupOptionalOverrideableChain();
        setupAppServerChain();
        
        List<String> cp = _getSharedClasspathInternal();
        //Seed the classpath string with the system classpath
        //to support users setting "env-classpath-ignored" to false.
        String oldcp = System.getProperty("java.class.path");
        StringBuilder classpath = null;
        
        if (oldcp != null) {
        	classpath = new StringBuilder(oldcp + pathSeparator);
        } else {
        	classpath = new StringBuilder();
        }
         
        for(final String s:cp){
            classpath.append(s);
            classpath.append(pathSeparator);
        }
        
        System.setProperty("java.class.path", classpath.toString());
    
private static voidsetupOptionalOverrideableChain()
The optional overrideable chain is "suffixed" to the chain of dependencies of an application. It consists of libraries that are by default provided to an application when an application has not specified an explicit dependency. This chain consists of all AS provided libraries that could be overridden by an application.

         
        _optionalChain = new ClassLoaderChain(_addOnsChain);
        _optionalChain.setName("optionalChain");
        
        final URL[] urls = getURLList(_optionalClasspath);
        //Parent set to Shared Chain
        final ASURLClassLoader optionalJarsLoader = new ASURLClassLoader(urls, 
                                                                _addOnsChain);
        _optionalChain.addToList(optionalJarsLoader);

    
private static voidsetupSharedChain()
The Shared chain is the child of SystemClassLoader in the AS classloader hierarchy and houses all immutable, platform classes. [eg j2ee.jar]

        final List<String> sharedChainJarList = _getSharedClasspathInternal();
        logFine("shared classpath jars : " + sharedChainJarList + "\n");
        final URL[] urls = getURLList(sharedChainJarList);
        logFine(" SharedChain URL List " + urls);
         _sharedClassLoader = new ASURLClassLoader(urls, 
                         ClassLoader.getSystemClassLoader());
        _sharedClassLoader.setName("Shared ClassLoader Chain");
    
public static synchronized voiduninstallAddon(java.lang.String addonName)
Used to un-install an addon during AS lifetime. [called when asadmin uninstall-addon is called] Uninstallation should result in removing the addon's classloader from the addons chain. This method is made synchronized to prevent invalid concurrent modifications to the classloader chain.

param
addonName Addon to uninstall.

    	logFine("Uninstalling addon " + addonName);
    	_addOnsChain.removeFromList(addonsMap.get(addonName));
    	logFine("removed addonclassloader " + addonsMap.get(addonName) + 
    			" for " + addonName);
    
private static voidupdateAddOnManifests(java.lang.String addOnName, java.lang.String addonJarPath)
Utility method to keep track of all jars [main addon jar and jars from manifest] of an addon. Used while creating the addon chain

param
addOnName
param
addonJarPath

    	logFine("updateAddOnManifests: adding " + addonJarPath + " for " + addOnName);
    	List<String> al = null;
    	final List<String> tmp = addOnsManifestsMap.get(addOnName);
    	al = (tmp != null) ? tmp : new ArrayList<String>();
    	al.add(addonJarPath);
    	addOnsManifestsMap.put(addOnName, al);
	
private static java.util.ListupdateClasspathList(java.lang.String libraryRoot, java.lang.String librariesList, java.util.List classpathAddressList)
Update the passed in classpathAddressList with the library jars referred to in librariesString

param
libraryRoot The directory root for the jars referred to in librariesString
param
librariesList A comma-separated list of all library jars under libraryRoot that needs to be added to the list.
param
classpathAddressList A list of jars [absolute paths] that defines a search path for a particular classloader.
return
the updated list of jars.

        String[] libList = librariesList.split(",");
		for (String library : libList) {
            library = library.trim();
			final File file = new File(library);
            if (!file.isAbsolute()) {
				classpathAddressList.add(libraryRoot + library);
            } else {
				classpathAddressList.add(library);
			}
            }
		return classpathAddressList;