最近做了一個小的網站。本來沒有什么值得說的。但是在部署的時候遇到的一些問題值得寫下來,所有這些問題都是關于Tomcat類加載機制的。

轉述一篇文章:

對于只用于某一個web應用的類或資源,放在這個web應用下的/WEB-INF/classes目錄下,如果是JAR,就放在這個web應用下的WEB-INF/lib目錄下。
對于讓所有的web應用共享的類或資源,放在$CATALINA_BASE/shared/classes目錄下,如果是JAR,就放在$CATALINA_BASE/shared/lib目錄下。
Tomcat中的類加載策略和JDK中的委托模型略有不同。當Tomcat啟動的時候,會創建一組類加載器,形成下面的層次關系:
                Bootstrap
                   |
                 System
                   |
                 Common
                 /    \
             Catalina  Shared
                      /      \
                   webapp1  webapp2 ..

各個類加載器的作用描述如下:
Bootstrap:負責加載由虛擬機提供的基本的運行時類和系統擴展目錄($JAVA_HOME/jre/lib/ext)下的JAR包;
System:通常這個加載器用來加載CLASSPATH環境變量中指定的類,但在Tomcat5的標準啟動腳本($CATALINA_HOME/bin/catalina.sh或%CATALINA_HOME%/bin/catalina.bat)中改變了它的行為,它只加載下面的類:
$CATALINA_HOME/bin/bootstrap.jar - Contains the main() method that is used to initialize the Tomcat 5 server, and the class loader implementation classes it depends on.
$JAVA_HOME/lib/tools.jar - Contains the "javac" compiler used to convert JSP pages into servlet classes.
$CATALINA_HOME/bin/commons-logging-api.jar - Jakarta commons logging API.
$CATALINA_HOME/bin/commons-daemon.jar - Jakarta commons daemon API.
jmx.jar - The JMX 1.2 implementation.

Common:它負責加載對于Tomcat本身和所有的web應用都需要看到的類,通常,應用的類不應該由他加載。$CATALINA_HOME/common/classes,$CATALINA_HOME/commons/endorsed和$CATALINA_HOME/common/lib下的都由這個加載器加載。缺省的,包括:  
ant.jar - Apache Ant.
commons-collection.jar - Jakarta commons collection.
commons-dbcp.jar - Jakarta commons DBCP, providing a JDBC connection pool to web applications.
commons-el.jar - Jakarta commons el, implementing the expression language used by Jasper.
commons-pool.jar - Jakarta commons pool.
jasper-compiler.jar - The JSP 2.0 compiler.
jasper-runtime.jar - The JSP 2.0 runtime.
jsp-api.jar - The JSP 2.0 API.
naming-common.jar - The JNDI implementation used by Tomcat 5 to represent in-memory naming contexts.
naming-factory.jar - The JNDI implementation used by Tomcat 5 to resolve references to enterprise resources (EJB, connection pools).
naming-resources.jar - The specialized JNDI naming context implementation used to represent the static resources of a web application.
servlet-api.jar - The Servlet and JSP API classes.
xerces.jar - The XML parser that is visible by default to Tomcat internal classes and to web applications.


Catalina:用來加載實現Tomcat自己需要的類。由他加載的類對web應用都是不可見的。$CATALINA_HOME/server/classes,$CATALINA_HOME/server/lib,都由這個加載器加載。缺省的,包括:
catalina.jar - Implementation of the Catalina servlet container portion of Tomcat 5.
jakarta-regexp-X.Y.jar - The binary distribution of the Jakarta Regexp regular expression processing library, used in the implementation of request filters.
servlets-xxxxx.jar - The classes associated with each internal servlet that provides part of Tomcat's functionality. These are separated so that they can be completely removed if the corresponding service is not required, or they can be subject to specialized security manager permissions.
tomcat-coyote.jar - Coyote connector for Tomcat 5.
tomcat-http11.jar - Standalone Java HTTP/1.1 connector.
tomcat-jk2.jar - Classes for the Java portion of the JK 2 web server connector, which allows Tomcat to run behind web servers such as Apache and iPlanet iAS and iWS.
tomcat-util.jar - Utility classes required by some Tomcat connectors.
Shared:被所有的web應用共享的類和資源由這個加載器加載。$CATALINA_BASE/shared/classed,$CATALINA_BASE/shared/lib,都由這個加載器加載。
WebappX:對每個Tomcat里的web應用都創建一個加載器,web應用下的WEB-INF/classes,WEB-INF/lib,都由這個加載器加載,由它所加載的類對其他的web應用是不可見的。
web應用的加載器(WebappX)和JDK的委托模型略有不同,這是根據Servlet2.3規范做出的。當WebappX被請求加載一個類時,它首先嘗試自己加載,而不是委托給它的父加載器。但是,對于下面的類,仍然要委托給父加載器:
Classes which are part of the JRE base classes cannot be overriden. For some classes (such as the XML parser components in JDK 1.4+), the JDK 1.4 endorsed feature can be used (see the common classloader definition above). In addition, for the following class patterns, the classloader will always delegate first (and load the class itself if no parent classloader loads it):
javax.*
org.xml.sax.*
org.w3c.dom.*
org.apache.xerces.*
org.apache.xalan.*
 Last, any JAR containing servlet API classes will be ignored by the classloader.

Tomcat中其他的加載器都是遵循委托模型的。
最后,以web應用的角度,要加載類或者資源時,會以下面的順序查找:
Bootstrap classes of your JVM
System class loader classses (described above)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
$CATALINA_HOME/common/classes
$CATALINA_HOME/common/endorsed/*.jar
$CATALINA_HOME/common/lib/*.jar
$CATALINA_BASE/shared/classes
$CATALINA_BASE/shared/lib/*.jar

本文來自CSDN博客:http://blog.csdn.net/findhappy7/archive/2008/05/12/2436702.aspx