From fe0394a4e4b2b3901af8364897be5e516562bfab Mon Sep 17 00:00:00 2001 From: remm Date: Wed, 12 Apr 2006 10:54:41 +0000 Subject: [PATCH] - Improve the algorithm used when constructing classloaders, in particular to respect order. - Submitted by Rainer Jung. git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@393433 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/catalina/startup/Bootstrap.java | 1015 ++++++++++---------- .../catalina/startup/ClassLoaderFactory.java | 426 ++++---- 2 files changed, 776 insertions(+), 665 deletions(-) diff --git a/java/org/apache/catalina/startup/Bootstrap.java b/java/org/apache/catalina/startup/Bootstrap.java index e1272a12f..fa7f817bf 100644 --- a/java/org/apache/catalina/startup/Bootstrap.java +++ b/java/org/apache/catalina/startup/Bootstrap.java @@ -1,498 +1,517 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.catalina.startup; - - -import java.io.File; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.StringTokenizer; - -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.ObjectName; - -import org.apache.catalina.security.SecurityClassLoad; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - - -/** - * Boostrap loader for Catalina. This application constructs a class loader - * for use in loading the Catalina internal classes (by accumulating all of the - * JAR files found in the "server" directory under "catalina.home"), and - * starts the regular execution of the container. The purpose of this - * roundabout approach is to keep the Catalina internal classes (and any - * other classes they depend on, such as an XML parser) out of the system - * class path and therefore not visible to application level classes. - * - * @author Craig R. McClanahan - * @author Remy Maucherat - * @version $Revision: 304108 $ $Date: 2005-09-29 07:55:15 +0200 (jeu., 29 sept. 2005) $ - */ - -public final class Bootstrap { - - private static Log log = LogFactory.getLog(Bootstrap.class); - - // -------------------------------------------------------------- Constants - - - protected static final String CATALINA_HOME_TOKEN = "${catalina.home}"; - protected static final String CATALINA_BASE_TOKEN = "${catalina.base}"; - - - // ------------------------------------------------------- Static Variables - - - private static final String JMX_ERROR_MESSAGE = - "This release of Apache Tomcat was packaged to run on J2SE 5.0 \n" - + "or later. It can be run on earlier JVMs by downloading and \n" - + "installing a compatibility package from the Apache Tomcat \n" - + "binary download page."; - - - /** - * Daemon object used by main. - */ - private static Bootstrap daemon = null; - - - // -------------------------------------------------------------- Variables - - - /** - * Daemon reference. - */ - private Object catalinaDaemon = null; - - - protected ClassLoader commonLoader = null; - protected ClassLoader catalinaLoader = null; - protected ClassLoader sharedLoader = null; - - - // -------------------------------------------------------- Private Methods - - - private void initClassLoaders() { - try { - commonLoader = createClassLoader("common", null); - if( commonLoader == null ) { - // no config file, default to this loader - we might be in a 'single' env. - commonLoader=this.getClass().getClassLoader(); - } - catalinaLoader = createClassLoader("server", commonLoader); - sharedLoader = createClassLoader("shared", commonLoader); - } catch (Throwable t) { - log.error("Class loader creation threw exception", t); - System.exit(1); - } - } - - - private ClassLoader createClassLoader(String name, ClassLoader parent) - throws Exception { - - String value = CatalinaProperties.getProperty(name + ".loader"); - if ((value == null) || (value.equals(""))) - return parent; - - ArrayList unpackedList = new ArrayList(); - ArrayList packedList = new ArrayList(); - ArrayList urlList = new ArrayList(); - - StringTokenizer tokenizer = new StringTokenizer(value, ","); - while (tokenizer.hasMoreElements()) { - String repository = tokenizer.nextToken(); - - // Local repository - boolean packed = false; - if (repository.startsWith(CATALINA_HOME_TOKEN)) { - repository = getCatalinaHome() - + repository.substring(CATALINA_HOME_TOKEN.length()); - } else if (repository.startsWith(CATALINA_BASE_TOKEN)) { - repository = getCatalinaBase() - + repository.substring(CATALINA_BASE_TOKEN.length()); - } - - // Check for a JAR URL repository - try { - urlList.add(new URL(repository)); - continue; - } catch (MalformedURLException e) { - // Ignore - } - - if (repository.endsWith("*.jar")) { - packed = true; - repository = repository.substring - (0, repository.length() - "*.jar".length()); - } - if (packed) { - packedList.add(new File(repository)); - } else { - unpackedList.add(new File(repository)); - } - } - - File[] unpacked = (File[]) unpackedList.toArray(new File[0]); - File[] packed = (File[]) packedList.toArray(new File[0]); - URL[] urls = (URL[]) urlList.toArray(new URL[0]); - - ClassLoader classLoader = ClassLoaderFactory.createClassLoader - (unpacked, packed, urls, parent); - - // Retrieving MBean server - MBeanServer mBeanServer = null; - if (MBeanServerFactory.findMBeanServer(null).size() > 0) { - mBeanServer = - (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0); - } else { - mBeanServer = MBeanServerFactory.createMBeanServer(); - } - - // Register the server classloader - ObjectName objectName = - new ObjectName("Catalina:type=ServerClassLoader,name=" + name); - mBeanServer.registerMBean(classLoader, objectName); - - return classLoader; - - } - - - /** - * Initialize daemon. - */ - public void init() - throws Exception - { - - // Set Catalina path - setCatalinaHome(); - setCatalinaBase(); - - initClassLoaders(); - - Thread.currentThread().setContextClassLoader(catalinaLoader); - - SecurityClassLoad.securityClassLoad(catalinaLoader); - - // Load our startup class and call its process() method - if (log.isDebugEnabled()) - log.debug("Loading startup class"); - Class startupClass = - catalinaLoader.loadClass - ("org.apache.catalina.startup.Catalina"); - Object startupInstance = startupClass.newInstance(); - - // Set the shared extensions class loader - if (log.isDebugEnabled()) - log.debug("Setting startup class properties"); - String methodName = "setParentClassLoader"; - Class paramTypes[] = new Class[1]; - paramTypes[0] = Class.forName("java.lang.ClassLoader"); - Object paramValues[] = new Object[1]; - paramValues[0] = sharedLoader; - Method method = - startupInstance.getClass().getMethod(methodName, paramTypes); - method.invoke(startupInstance, paramValues); - - catalinaDaemon = startupInstance; - - } - - - /** - * Load daemon. - */ - private void load(String[] arguments) - throws Exception { - - // Call the load() method - String methodName = "load"; - Object param[]; - Class paramTypes[]; - if (arguments==null || arguments.length==0) { - paramTypes = null; - param = null; - } else { - paramTypes = new Class[1]; - paramTypes[0] = arguments.getClass(); - param = new Object[1]; - param[0] = arguments; - } - Method method = - catalinaDaemon.getClass().getMethod(methodName, paramTypes); - if (log.isDebugEnabled()) - log.debug("Calling startup class " + method); - method.invoke(catalinaDaemon, param); - - } - - - // ----------------------------------------------------------- Main Program - - - /** - * Load the Catalina daemon. - */ - public void init(String[] arguments) - throws Exception { - - init(); - load(arguments); - - } - - - /** - * Start the Catalina daemon. - */ - public void start() - throws Exception { - if( catalinaDaemon==null ) init(); - - Method method = catalinaDaemon.getClass().getMethod("start", (Class [] )null); - method.invoke(catalinaDaemon, (Object [])null); - - } - - - /** - * Stop the Catalina Daemon. - */ - public void stop() - throws Exception { - - Method method = catalinaDaemon.getClass().getMethod("stop", (Class [] ) null); - method.invoke(catalinaDaemon, (Object [] ) null); - - } - - - /** - * Stop the standlone server. - */ - public void stopServer() - throws Exception { - - Method method = - catalinaDaemon.getClass().getMethod("stopServer", (Class []) null); - method.invoke(catalinaDaemon, (Object []) null); - - } - - - /** - * Stop the standlone server. - */ - public void stopServer(String[] arguments) - throws Exception { - - Object param[]; - Class paramTypes[]; - if (arguments==null || arguments.length==0) { - paramTypes = null; - param = null; - } else { - paramTypes = new Class[1]; - paramTypes[0] = arguments.getClass(); - param = new Object[1]; - param[0] = arguments; - } - Method method = - catalinaDaemon.getClass().getMethod("stopServer", paramTypes); - method.invoke(catalinaDaemon, param); - - } - - - /** - * Set flag. - */ - public void setAwait(boolean await) - throws Exception { - - Class paramTypes[] = new Class[1]; - paramTypes[0] = Boolean.TYPE; - Object paramValues[] = new Object[1]; - paramValues[0] = new Boolean(await); - Method method = - catalinaDaemon.getClass().getMethod("setAwait", paramTypes); - method.invoke(catalinaDaemon, paramValues); - - } - - public boolean getAwait() - throws Exception - { - Class paramTypes[] = new Class[0]; - Object paramValues[] = new Object[0]; - Method method = - catalinaDaemon.getClass().getMethod("getAwait", paramTypes); - Boolean b=(Boolean)method.invoke(catalinaDaemon, paramValues); - return b.booleanValue(); - } - - - /** - * Destroy the Catalina Daemon. - */ - public void destroy() { - - // FIXME - - } - - - /** - * Main method, used for testing only. - * - * @param args Command line arguments to be processed - */ - public static void main(String args[]) { - - try { - // Attempt to load JMX class - new ObjectName("test:foo=bar"); - } catch (Throwable t) { - System.out.println(JMX_ERROR_MESSAGE); - try { - // Give users some time to read the message before exiting - Thread.sleep(5000); - } catch (Exception ex) { - } - return; - } - - if (daemon == null) { - daemon = new Bootstrap(); - try { - daemon.init(); - } catch (Throwable t) { - t.printStackTrace(); - return; - } - } - - try { - String command = "start"; - if (args.length > 0) { - command = args[args.length - 1]; - } - - if (command.equals("startd")) { - args[0] = "start"; - daemon.load(args); - daemon.start(); - } else if (command.equals("stopd")) { - args[0] = "stop"; - daemon.stop(); - } else if (command.equals("start")) { - daemon.setAwait(true); - daemon.load(args); - daemon.start(); - } else if (command.equals("stop")) { - daemon.stopServer(args); - } else { - log.warn("Bootsrap: command \"" + command + "\" does not exist."); - } - } catch (Throwable t) { - t.printStackTrace(); - } - - } - - public void setCatalinaHome(String s) { - System.setProperty( "catalina.home", s ); - } - - public void setCatalinaBase(String s) { - System.setProperty( "catalina.base", s ); - } - - - /** - * Set the catalina.base System property to the current - * working directory if it has not been set. - */ - private void setCatalinaBase() { - - if (System.getProperty("catalina.base") != null) - return; - if (System.getProperty("catalina.home") != null) - System.setProperty("catalina.base", - System.getProperty("catalina.home")); - else - System.setProperty("catalina.base", - System.getProperty("user.dir")); - - } - - - /** - * Set the catalina.home System property to the current - * working directory if it has not been set. - */ - private void setCatalinaHome() { - - if (System.getProperty("catalina.home") != null) - return; - File bootstrapJar = - new File(System.getProperty("user.dir"), "bootstrap.jar"); - if (bootstrapJar.exists()) { - try { - System.setProperty - ("catalina.home", - (new File(System.getProperty("user.dir"), "..")) - .getCanonicalPath()); - } catch (Exception e) { - // Ignore - System.setProperty("catalina.home", - System.getProperty("user.dir")); - } - } else { - System.setProperty("catalina.home", - System.getProperty("user.dir")); - } - - } - - - /** - * Get the value of the catalina.home environment variable. - */ - public static String getCatalinaHome() { - return System.getProperty("catalina.home", - System.getProperty("user.dir")); - } - - - /** - * Get the value of the catalina.base environment variable. - */ - public static String getCatalinaBase() { - return System.getProperty("catalina.base", getCatalinaHome()); - } - - -} +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.catalina.startup; + + +import java.io.File; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.StringTokenizer; + +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.ObjectName; + +import org.apache.catalina.security.SecurityClassLoad; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + + +/** + * Boostrap loader for Catalina. This application constructs a class loader + * for use in loading the Catalina internal classes (by accumulating all of the + * JAR files found in the "server" directory under "catalina.home"), and + * starts the regular execution of the container. The purpose of this + * roundabout approach is to keep the Catalina internal classes (and any + * other classes they depend on, such as an XML parser) out of the system + * class path and therefore not visible to application level classes. + * + * @author Craig R. McClanahan + * @author Remy Maucherat + * @version $Revision: 304108 $ $Date: 2005-09-29 07:55:15 +0200 (jeu., 29 sept. 2005) $ + */ + +public final class Bootstrap { + + private static Log log = LogFactory.getLog(Bootstrap.class); + + // -------------------------------------------------------------- Constants + + + protected static final String CATALINA_HOME_TOKEN = "${catalina.home}"; + protected static final String CATALINA_BASE_TOKEN = "${catalina.base}"; + + + // ------------------------------------------------------- Static Variables + + + private static final String JMX_ERROR_MESSAGE = + "This release of Apache Tomcat was packaged to run on J2SE 5.0 \n" + + "or later. It can be run on earlier JVMs by downloading and \n" + + "installing a compatibility package from the Apache Tomcat \n" + + "binary download page."; + + + /** + * Daemon object used by main. + */ + private static Bootstrap daemon = null; + + + // -------------------------------------------------------------- Variables + + + /** + * Daemon reference. + */ + private Object catalinaDaemon = null; + + + protected ClassLoader commonLoader = null; + protected ClassLoader catalinaLoader = null; + protected ClassLoader sharedLoader = null; + + + // -------------------------------------------------------- Private Methods + + + private void initClassLoaders() { + try { + commonLoader = createClassLoader("common", null); + if( commonLoader == null ) { + // no config file, default to this loader - we might be in a 'single' env. + commonLoader=this.getClass().getClassLoader(); + } + catalinaLoader = createClassLoader("server", commonLoader); + sharedLoader = createClassLoader("shared", commonLoader); + } catch (Throwable t) { + log.error("Class loader creation threw exception", t); + System.exit(1); + } + } + + + private ClassLoader createClassLoader(String name, ClassLoader parent) + throws Exception { + + String value = CatalinaProperties.getProperty(name + ".loader"); + if ((value == null) || (value.equals(""))) + return parent; + + ArrayList repositoryLocations = new ArrayList(); + ArrayList repositoryTypes = new ArrayList(); + int i; + + StringTokenizer tokenizer = new StringTokenizer(value, ","); + while (tokenizer.hasMoreElements()) { + String repository = tokenizer.nextToken(); + + // Local repository + boolean replace = false; + String before = repository; + while ((i=repository.indexOf(CATALINA_HOME_TOKEN))>=0) { + replace=true; + if (i>0) { + repository = repository.substring(0,i) + getCatalinaHome() + + repository.substring(i+CATALINA_HOME_TOKEN.length()); + } else { + repository = getCatalinaHome() + + repository.substring(CATALINA_HOME_TOKEN.length()); + } + } + while ((i=repository.indexOf(CATALINA_BASE_TOKEN))>=0) { + replace=true; + if (i>0) { + repository = repository.substring(0,i) + getCatalinaBase() + + repository.substring(i+CATALINA_BASE_TOKEN.length()); + } else { + repository = getCatalinaBase() + + repository.substring(CATALINA_BASE_TOKEN.length()); + } + } + if (replace && log.isDebugEnabled()) + log.debug("Expanded " + before + " to " + replace); + + // Check for a JAR URL repository + try { + URL url=new URL(repository); + repositoryLocations.add(repository); + repositoryTypes.add(ClassLoaderFactory.IS_URL); + continue; + } catch (MalformedURLException e) { + // Ignore + } + + if (repository.endsWith("*.jar")) { + repository = repository.substring + (0, repository.length() - "*.jar".length()); + repositoryLocations.add(repository); + repositoryTypes.add(ClassLoaderFactory.IS_GLOB); + } else if (repository.endsWith(".jar")) { + repositoryLocations.add(repository); + repositoryTypes.add(ClassLoaderFactory.IS_JAR); + } else { + repositoryLocations.add(repository); + repositoryTypes.add(ClassLoaderFactory.IS_DIR); + } + } + + String[] locations = (String[]) repositoryLocations.toArray(new String[0]); + Integer[] types = (Integer[]) repositoryTypes.toArray(new Integer[0]); + + ClassLoader classLoader = ClassLoaderFactory.createClassLoader + (locations, types, parent); + + // Retrieving MBean server + MBeanServer mBeanServer = null; + if (MBeanServerFactory.findMBeanServer(null).size() > 0) { + mBeanServer = + (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0); + } else { + mBeanServer = MBeanServerFactory.createMBeanServer(); + } + + // Register the server classloader + ObjectName objectName = + new ObjectName("Catalina:type=ServerClassLoader,name=" + name); + mBeanServer.registerMBean(classLoader, objectName); + + return classLoader; + + } + + + /** + * Initialize daemon. + */ + public void init() + throws Exception + { + + // Set Catalina path + setCatalinaHome(); + setCatalinaBase(); + + initClassLoaders(); + + Thread.currentThread().setContextClassLoader(catalinaLoader); + + SecurityClassLoad.securityClassLoad(catalinaLoader); + + // Load our startup class and call its process() method + if (log.isDebugEnabled()) + log.debug("Loading startup class"); + Class startupClass = + catalinaLoader.loadClass + ("org.apache.catalina.startup.Catalina"); + Object startupInstance = startupClass.newInstance(); + + // Set the shared extensions class loader + if (log.isDebugEnabled()) + log.debug("Setting startup class properties"); + String methodName = "setParentClassLoader"; + Class paramTypes[] = new Class[1]; + paramTypes[0] = Class.forName("java.lang.ClassLoader"); + Object paramValues[] = new Object[1]; + paramValues[0] = sharedLoader; + Method method = + startupInstance.getClass().getMethod(methodName, paramTypes); + method.invoke(startupInstance, paramValues); + + catalinaDaemon = startupInstance; + + } + + + /** + * Load daemon. + */ + private void load(String[] arguments) + throws Exception { + + // Call the load() method + String methodName = "load"; + Object param[]; + Class paramTypes[]; + if (arguments==null || arguments.length==0) { + paramTypes = null; + param = null; + } else { + paramTypes = new Class[1]; + paramTypes[0] = arguments.getClass(); + param = new Object[1]; + param[0] = arguments; + } + Method method = + catalinaDaemon.getClass().getMethod(methodName, paramTypes); + if (log.isDebugEnabled()) + log.debug("Calling startup class " + method); + method.invoke(catalinaDaemon, param); + + } + + + // ----------------------------------------------------------- Main Program + + + /** + * Load the Catalina daemon. + */ + public void init(String[] arguments) + throws Exception { + + init(); + load(arguments); + + } + + + /** + * Start the Catalina daemon. + */ + public void start() + throws Exception { + if( catalinaDaemon==null ) init(); + + Method method = catalinaDaemon.getClass().getMethod("start", (Class [] )null); + method.invoke(catalinaDaemon, (Object [])null); + + } + + + /** + * Stop the Catalina Daemon. + */ + public void stop() + throws Exception { + + Method method = catalinaDaemon.getClass().getMethod("stop", (Class [] ) null); + method.invoke(catalinaDaemon, (Object [] ) null); + + } + + + /** + * Stop the standlone server. + */ + public void stopServer() + throws Exception { + + Method method = + catalinaDaemon.getClass().getMethod("stopServer", (Class []) null); + method.invoke(catalinaDaemon, (Object []) null); + + } + + + /** + * Stop the standlone server. + */ + public void stopServer(String[] arguments) + throws Exception { + + Object param[]; + Class paramTypes[]; + if (arguments==null || arguments.length==0) { + paramTypes = null; + param = null; + } else { + paramTypes = new Class[1]; + paramTypes[0] = arguments.getClass(); + param = new Object[1]; + param[0] = arguments; + } + Method method = + catalinaDaemon.getClass().getMethod("stopServer", paramTypes); + method.invoke(catalinaDaemon, param); + + } + + + /** + * Set flag. + */ + public void setAwait(boolean await) + throws Exception { + + Class paramTypes[] = new Class[1]; + paramTypes[0] = Boolean.TYPE; + Object paramValues[] = new Object[1]; + paramValues[0] = new Boolean(await); + Method method = + catalinaDaemon.getClass().getMethod("setAwait", paramTypes); + method.invoke(catalinaDaemon, paramValues); + + } + + public boolean getAwait() + throws Exception + { + Class paramTypes[] = new Class[0]; + Object paramValues[] = new Object[0]; + Method method = + catalinaDaemon.getClass().getMethod("getAwait", paramTypes); + Boolean b=(Boolean)method.invoke(catalinaDaemon, paramValues); + return b.booleanValue(); + } + + + /** + * Destroy the Catalina Daemon. + */ + public void destroy() { + + // FIXME + + } + + + /** + * Main method, used for testing only. + * + * @param args Command line arguments to be processed + */ + public static void main(String args[]) { + + try { + // Attempt to load JMX class + new ObjectName("test:foo=bar"); + } catch (Throwable t) { + System.out.println(JMX_ERROR_MESSAGE); + try { + // Give users some time to read the message before exiting + Thread.sleep(5000); + } catch (Exception ex) { + } + return; + } + + if (daemon == null) { + daemon = new Bootstrap(); + try { + daemon.init(); + } catch (Throwable t) { + t.printStackTrace(); + return; + } + } + + try { + String command = "start"; + if (args.length > 0) { + command = args[args.length - 1]; + } + + if (command.equals("startd")) { + args[0] = "start"; + daemon.load(args); + daemon.start(); + } else if (command.equals("stopd")) { + args[0] = "stop"; + daemon.stop(); + } else if (command.equals("start")) { + daemon.setAwait(true); + daemon.load(args); + daemon.start(); + } else if (command.equals("stop")) { + daemon.stopServer(args); + } else { + log.warn("Bootstrap: command \"" + command + "\" does not exist."); + } + } catch (Throwable t) { + t.printStackTrace(); + } + + } + + public void setCatalinaHome(String s) { + System.setProperty( "catalina.home", s ); + } + + public void setCatalinaBase(String s) { + System.setProperty( "catalina.base", s ); + } + + + /** + * Set the catalina.base System property to the current + * working directory if it has not been set. + */ + private void setCatalinaBase() { + + if (System.getProperty("catalina.base") != null) + return; + if (System.getProperty("catalina.home") != null) + System.setProperty("catalina.base", + System.getProperty("catalina.home")); + else + System.setProperty("catalina.base", + System.getProperty("user.dir")); + + } + + + /** + * Set the catalina.home System property to the current + * working directory if it has not been set. + */ + private void setCatalinaHome() { + + if (System.getProperty("catalina.home") != null) + return; + File bootstrapJar = + new File(System.getProperty("user.dir"), "bootstrap.jar"); + if (bootstrapJar.exists()) { + try { + System.setProperty + ("catalina.home", + (new File(System.getProperty("user.dir"), "..")) + .getCanonicalPath()); + } catch (Exception e) { + // Ignore + System.setProperty("catalina.home", + System.getProperty("user.dir")); + } + } else { + System.setProperty("catalina.home", + System.getProperty("user.dir")); + } + + } + + + /** + * Get the value of the catalina.home environment variable. + */ + public static String getCatalinaHome() { + return System.getProperty("catalina.home", + System.getProperty("user.dir")); + } + + + /** + * Get the value of the catalina.base environment variable. + */ + public static String getCatalinaBase() { + return System.getProperty("catalina.base", getCatalinaHome()); + } + + +} diff --git a/java/org/apache/catalina/startup/ClassLoaderFactory.java b/java/org/apache/catalina/startup/ClassLoaderFactory.java index 3ca120fd9..1d7a297dc 100644 --- a/java/org/apache/catalina/startup/ClassLoaderFactory.java +++ b/java/org/apache/catalina/startup/ClassLoaderFactory.java @@ -1,167 +1,259 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.catalina.startup; - - -import java.io.File; -import java.net.URL; -import java.util.ArrayList; - -import org.apache.catalina.loader.StandardClassLoader; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - - -/** - *

Utility class for building class loaders for Catalina. The factory - * method requires the following parameters in order to build a new class - * loader (with suitable defaults in all cases):

- * - * - * @author Craig R. McClanahan - * @version $Revision: 303210 $ $Date: 2004-09-08 01:13:01 +0200 (mer., 08 sept. 2004) $ - */ - -public final class ClassLoaderFactory { - - - private static Log log = LogFactory.getLog(ClassLoaderFactory.class); - - // --------------------------------------------------------- Public Methods - - - /** - * Create and return a new class loader, based on the configuration - * defaults and the specified directory paths: - * - * @param unpacked Array of pathnames to unpacked directories that should - * be added to the repositories of the class loader, or null - * for no unpacked directories to be considered - * @param packed Array of pathnames to directories containing JAR files - * that should be added to the repositories of the class loader, - * or null for no directories of JAR files to be considered - * @param parent Parent class loader for the new class loader, or - * null for the system class loader. - * - * @exception Exception if an error occurs constructing the class loader - */ - public static ClassLoader createClassLoader(File unpacked[], - File packed[], - ClassLoader parent) - throws Exception { - return createClassLoader(unpacked, packed, null, parent); - } - - - /** - * Create and return a new class loader, based on the configuration - * defaults and the specified directory paths: - * - * @param unpacked Array of pathnames to unpacked directories that should - * be added to the repositories of the class loader, or null - * for no unpacked directories to be considered - * @param packed Array of pathnames to directories containing JAR files - * that should be added to the repositories of the class loader, - * or null for no directories of JAR files to be considered - * @param urls Array of URLs to remote repositories, designing either JAR - * resources or uncompressed directories that should be added to - * the repositories of the class loader, or null for no - * directories of JAR files to be considered - * @param parent Parent class loader for the new class loader, or - * null for the system class loader. - * - * @exception Exception if an error occurs constructing the class loader - */ - public static ClassLoader createClassLoader(File unpacked[], - File packed[], - URL urls[], - ClassLoader parent) - throws Exception { - - if (log.isDebugEnabled()) - log.debug("Creating new class loader"); - - // Construct the "class path" for this class loader - ArrayList list = new ArrayList(); - - // Add unpacked directories - if (unpacked != null) { - for (int i = 0; i < unpacked.length; i++) { - File file = unpacked[i]; - if (!file.exists() || !file.canRead()) - continue; - file = new File(file.getCanonicalPath() + File.separator); - URL url = file.toURL(); - if (log.isDebugEnabled()) - log.debug(" Including directory " + url); - list.add(url); - } - } - - // Add packed directory JAR files - if (packed != null) { - for (int i = 0; i < packed.length; i++) { - File directory = packed[i]; - if (!directory.isDirectory() || !directory.exists() || - !directory.canRead()) - continue; - String filenames[] = directory.list(); - for (int j = 0; j < filenames.length; j++) { - String filename = filenames[j].toLowerCase(); - if (!filename.endsWith(".jar")) - continue; - File file = new File(directory, filenames[j]); - if (log.isDebugEnabled()) - log.debug(" Including jar file " + file.getAbsolutePath()); - URL url = file.toURL(); - list.add(url); - } - } - } - - // Add URLs - if (urls != null) { - for (int i = 0; i < urls.length; i++) { - if (log.isDebugEnabled()) - log.debug(" Including URL " + urls[i]); - list.add(urls[i]); - } - } - - // Construct the class loader itself - URL[] array = (URL[]) list.toArray(new URL[list.size()]); - StandardClassLoader classLoader = null; - if (parent == null) - classLoader = new StandardClassLoader(array); - else - classLoader = new StandardClassLoader(array, parent); - return (classLoader); - - } - - -} +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.catalina.startup; + + +import java.io.File; +import java.net.URL; +import java.util.ArrayList; + +import org.apache.catalina.loader.StandardClassLoader; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + + +/** + *

Utility class for building class loaders for Catalina. The factory + * method requires the following parameters in order to build a new class + * loader (with suitable defaults in all cases):

+ * + * + * @author Craig R. McClanahan + * @version $Revision: 303210 $ $Date: 2004-09-08 01:13:01 +0200 (mer., 08 sept. 2004) $ + */ + +public final class ClassLoaderFactory { + + + private static Log log = LogFactory.getLog(ClassLoaderFactory.class); + + protected static final Integer IS_DIR = new Integer(0); + protected static final Integer IS_JAR = new Integer(1); + protected static final Integer IS_GLOB = new Integer(2); + protected static final Integer IS_URL = new Integer(3); + + // --------------------------------------------------------- Public Methods + + + /** + * Create and return a new class loader, based on the configuration + * defaults and the specified directory paths: + * + * @param unpacked Array of pathnames to unpacked directories that should + * be added to the repositories of the class loader, or null + * for no unpacked directories to be considered + * @param packed Array of pathnames to directories containing JAR files + * that should be added to the repositories of the class loader, + * or null for no directories of JAR files to be considered + * @param parent Parent class loader for the new class loader, or + * null for the system class loader. + * + * @exception Exception if an error occurs constructing the class loader + */ + public static ClassLoader createClassLoader(File unpacked[], + File packed[], + ClassLoader parent) + throws Exception { + return createClassLoader(unpacked, packed, null, parent); + } + + + /** + * Create and return a new class loader, based on the configuration + * defaults and the specified directory paths: + * + * @param unpacked Array of pathnames to unpacked directories that should + * be added to the repositories of the class loader, or null + * for no unpacked directories to be considered + * @param packed Array of pathnames to directories containing JAR files + * that should be added to the repositories of the class loader, + * or null for no directories of JAR files to be considered + * @param urls Array of URLs to remote repositories, designing either JAR + * resources or uncompressed directories that should be added to + * the repositories of the class loader, or null for no + * directories of JAR files to be considered + * @param parent Parent class loader for the new class loader, or + * null for the system class loader. + * + * @exception Exception if an error occurs constructing the class loader + */ + public static ClassLoader createClassLoader(File unpacked[], + File packed[], + URL urls[], + ClassLoader parent) + throws Exception { + + if (log.isDebugEnabled()) + log.debug("Creating new class loader"); + + // Construct the "class path" for this class loader + ArrayList list = new ArrayList(); + + // Add unpacked directories + if (unpacked != null) { + for (int i = 0; i < unpacked.length; i++) { + File file = unpacked[i]; + if (!file.exists() || !file.canRead()) + continue; + file = new File(file.getCanonicalPath() + File.separator); + URL url = file.toURL(); + if (log.isDebugEnabled()) + log.debug(" Including directory " + url); + list.add(url); + } + } + + // Add packed directory JAR files + if (packed != null) { + for (int i = 0; i < packed.length; i++) { + File directory = packed[i]; + if (!directory.isDirectory() || !directory.exists() || + !directory.canRead()) + continue; + String filenames[] = directory.list(); + for (int j = 0; j < filenames.length; j++) { + String filename = filenames[j].toLowerCase(); + if (!filename.endsWith(".jar")) + continue; + File file = new File(directory, filenames[j]); + if (log.isDebugEnabled()) + log.debug(" Including jar file " + file.getAbsolutePath()); + URL url = file.toURL(); + list.add(url); + } + } + } + + // Construct the class loader itself + URL[] array = (URL[]) list.toArray(new URL[list.size()]); + StandardClassLoader classLoader = null; + if (parent == null) + classLoader = new StandardClassLoader(array); + else + classLoader = new StandardClassLoader(array, parent); + return (classLoader); + + } + + + /** + * Create and return a new class loader, based on the configuration + * defaults and the specified directory paths: + * + * @param locations Array of strings containing class directories, jar files, + * jar directories or URLS that should be added to the repositories of + * the class loader. The type is given by the member of param types. + * @param types Array of types for the members of param locations. + * Possible values are IS_DIR (class directory), IS_JAR (single jar file), + * IS_GLOB (directory of jar files) and IS_URL (URL). + * @param parent Parent class loader for the new class loader, or + * null for the system class loader. + * + * @exception Exception if an error occurs constructing the class loader + */ + public static ClassLoader createClassLoader(String locations[], + Integer types[], + ClassLoader parent) + throws Exception { + + if (log.isDebugEnabled()) + log.debug("Creating new class loader"); + + // Construct the "class path" for this class loader + ArrayList list = new ArrayList(); + + if (locations != null && types != null && locations.length == types.length) { + for (int i = 0; i < locations.length; i++) { + String location = locations[i]; + if ( types[i] == IS_URL ) { + URL url = new URL(location); + if (log.isDebugEnabled()) + log.debug(" Including URL " + url); + list.add(url); + } else if ( types[i] == IS_DIR ) { + File directory = new File(location); + directory = new File(directory.getCanonicalPath()); + if (!directory.exists() || !directory.isDirectory() || + !directory.canRead()) + continue; + URL url = directory.toURL(); + if (log.isDebugEnabled()) + log.debug(" Including directory " + url); + list.add(url); + } else if ( types[i] == IS_JAR ) { + File file=new File(location); + file = new File(file.getCanonicalPath()); + if (!file.exists() || !file.canRead()) + continue; + URL url = file.toURL(); + if (log.isDebugEnabled()) + log.debug(" Including jar file " + url); + list.add(url); + } else if ( types[i] == IS_GLOB ) { + File directory=new File(location); + if (!directory.exists() || !directory.isDirectory() || + !directory.canRead()) + continue; + if (log.isDebugEnabled()) + log.debug(" Including directory glob " + + directory.getAbsolutePath()); + String filenames[] = directory.list(); + for (int j = 0; j < filenames.length; j++) { + String filename = filenames[j].toLowerCase(); + if (!filename.endsWith(".jar")) + continue; + File file = new File(directory, filenames[j]); + file = new File(file.getCanonicalPath()); + if (!file.exists() || !file.canRead()) + continue; + if (log.isDebugEnabled()) + log.debug(" Including glob jar file " + + file.getAbsolutePath()); + URL url = file.toURL(); + list.add(url); + } + } + } + } + + // Construct the class loader itself + URL[] array = (URL[]) list.toArray(new URL[list.size()]); + if (log.isDebugEnabled()) + for (int i = 0; i < array.length; i++) { + log.debug(" location " + i + " is " + array[i]); + } + StandardClassLoader classLoader = null; + if (parent == null) + classLoader = new StandardClassLoader(array); + else + classLoader = new StandardClassLoader(array, parent); + return (classLoader); + + } + + +} -- 2.11.0