${catalina.home}/conf/catalina.properties文件可以用来配置tomcat内置classloader的load范围,一般默认情况如下
# List of comma-separated paths defining the contents of the "common"
# classloader. Prefixes should be used to define what is the repository type.
# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
# If left as blank,the JVM system loader will be used as Catalina's "common"
# loader.
# Examples:
# "foo": Add this folder as a class repository
# "foo/*.jar": Add all the JARs of the specified folder as class
# repositories
# "foo/bar.jar": Add bar.jar as a class repository
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
#
# List of comma-separated paths defining the contents of the "server"
# classloader. Prefixes should be used to define what is the repository type.
# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
# If left as blank, the "common" loader will be used as Catalina's "server"
# loader.
# Examples:
# "foo": Add this folder as a class repository
# "foo/*.jar": Add all the JARs of the specified folder as class
# repositories
# "foo/bar.jar": Add bar.jar as a class repository
server.loader=
#
# List of comma-separated paths defining the contents of the "shared"
# classloader. Prefixes should be used to define what is the repository type.
# Path may be relative to the CATALINA_BASE path or absolute. If left as blank,
# the "common" loader will be used as Catalina's "shared" loader.
# Examples:
# "foo": Add this folder as a class repository
# "foo/*.jar": Add all the JARs of the specified folder as class
# repositories
# "foo/bar.jar": Add bar.jar as a class repository
# Please note that for single jars, e.g. bar.jar, you need the URL form
# starting with file:.
shared.loader=
下面两个方法都是copy自/Tomcat 6.0/java/org/apache/catalina/startup/Bootstrap.java,tomcat的启动类
//下面三个classloader创建好,上面配置文件指定了load path,注意classpath下面并没有tomcat的自身类,所以
//appclassloader是加载不到的
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); } }
public void init() throws Exception { // Set Catalina path setCatalinaHome(); setCatalinaBase(); initClassLoaders(); Thread.currentThread().setContextClassLoader(catalinaLoader); //tomcat的启动类是在classpath下面的,由appclassloader加载,然后接下来的各个tomcat自身类由catalinaLoader加载,由于classloader的传递特性 //due to the classloader here, so the later classloader will be catalinaLoader Class startupClass = catalinaLoader.loadClass ("org.apache.catalina.startup.Catalina"); Object startupInstance = startupClass.newInstance(); Method method = startupInstance.getClass().getMethod(methodName, paramTypes); method.invoke(startupInstance, paramValues); catalinaDaemon = startupInstance; }