原文:
http://www.donews.net/lizongbo/archive/2005/03.aspxTomcat的class加載的優(yōu)先順序一覽
1.最先是$JAVA_HOME/jre/lib/ext/下的jar文件。
2.環(huán)境變量CLASSPATH中的jar和class文件。
3.$CATALINA_HOME/common/classes下的class文件。
4.$CATALINA_HOME/commons/endorsed下的jar文件。
5.$CATALINA_HOME/commons/i18n下的jar文件。
6.$CATALINA_HOME/common/lib?下的jar文件。
(JDBC驅(qū)動(dòng)之類的jar文件可以放在這里,這樣就可以避免在server.xml配置好數(shù)據(jù)源卻出現(xiàn)找不到JDBC?Driver的情況。)
7.$CATALINA_HOME/server/classes下的class文件。
8.$CATALINA_HOME/server/lib/下的jar文件。
9.$CATALINA_BASE/shared/classes?下的class文件。
10.$CATALINA_BASE/shared/lib下的jar文件。
11.各自具體的webapp?/WEB-INF/classes下的class文件。
12.各自具體的webapp?/WEB-INF/lib下的jar文件。
class的搜尋順序如下:
-------------
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/i18n/*.jar?
$CATALINA_HOME/common/lib/*.jar?
$CATALINA_BASE/shared/classes?
$CATALINA_BASE/shared/lib/*.jar?
--------------
因此放在不同webapp里的class文件,會(huì)被classloader加載成不同的實(shí)例。
例如假設(shè)下面兩個(gè)不同內(nèi)容的class。分別放在不同的webapp的class目錄下。
package?com.lizongbo;
public?class?TestClass?{
??private?String?NAME="lizongbo";
}
package?com.lizongbo;
public?class?TestClass?{
??private?String?NAME="li_zongbo";
}
在不同的webapp得到的com.lizongbo.NAME結(jié)果是不同的,且互不影響。
但是注意,以下包名開頭的class例外:
javax.*?
org.xml.sax.*?
org.w3c.dom.*?
org.apache.xerces.*?
org.apache.xalan.*?
ps,注意.在各個(gè)jar中的\META-INF\MAINFEST.MF文件里Class-Path鍵值對(duì),也會(huì)提供jar的加載優(yōu)先順序。
例如某jar的MAINFEST.MF內(nèi)容如下:
Manifest-Version:?1.0
Created-By:?lizongbo
Class-Path:?commons-beanutils.jar
Class-Path:?commons-collections.jar
Class-Path:?commons-dbcp.jar
Class-Path:?commons-digester.jar
Class-Path:?commons-logging.jar
Class-Path:?commons-pool.jar
Class-Path:?commons-services.jar
Class-Path:?commons-validator.jar
Class-Path:?jakarta-oro.jar
Main-Class:?com.lizongbo.MyTestClass
那么在加載這個(gè)jar的時(shí)候,會(huì)先在此jar所在目錄下依次先加載commons-beanutils.jar,commons-collections.jar。。。等jar文件。
在不同的地方放置jar和class可能會(huì)產(chǎn)生意想不到的后果,,尤其是不同版本的jar文件,因此在實(shí)際應(yīng)用部署web應(yīng)用時(shí)候要特別留心.
例如?使用javamail常見的一個(gè)出錯(cuò)信息:
javax.mail.NoSuchProviderException:?No?provider?for?smtp
其真實(shí)原因就很可能如下:
在不同的加載jar的目錄下放置了不同版本的mail.jar,比如一個(gè)是javamail1.3.1的mail.jar
在D:\jakarta-tomcat-5.5.8\common\lib下,而另外一個(gè)是javamail1.3.2的mail.jar在
D:\jakarta-tomcat-5.5.8\webapps\lizongbo\WEB-INF/lib下,
那么lizongbo這個(gè)webapp中使用到j(luò)avamail進(jìn)行郵件發(fā)送的時(shí)候,便會(huì)出現(xiàn)No?provider?for?smtp的錯(cuò)誤。
詳情見google:
http://www.google.com/search?hl=zh-CN&inlang=zh-CN&newwindow=1&q=javax.mail.NoSuchProviderException%3A+smtp&btnG=%E6%90%9C%E7%B4%A2&lr=lang_zh-CN?
其它詳情可參考:
http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html#JAR%20Manifesthttp://jakarta.apache.org/tomcat/tomcat-5.5-doc/class-loader-howto.html