jvm類載入和tomcat類載入機制
應用程式在啟動的時候需要啟動虛擬機器進行載入class檔案到記憶體中。然後等待程式的呼叫。那麼有時候我們的程式回報一個錯誤:
ClassNotFoundException異常。什麼情況下會報這個異常呢?也許你會說jvm找不到類。但是jvm它是怎麼進行載入的呢?載入的機制是怎麼樣的?
jvm採用委託上級的載入機制載入類。那麼jvm的載入器自上而下四個:
BootStraptClassLoader:虛擬機器啟動時載入虛擬機器內部的class檔案。引導載入器
ExtClassLoader:擴充套件類載入器載入jdk目錄下ext目錄裡面的jar。如圖:擴充套件類載入器
applicationClassLoader:應用載入器,載入應用classpath目錄下的檔案。也就是應用程式碼編譯後的檔案
customerClassLoader 使用者自定義載入器。最後是使用者自定義類載入器
整個載入過程採用委託上層載入器載入。自上而下,在各自的載入區域載入檔案,如果到customerClassLoader仍
找不到檔案,就會爆出CllassNotFourndException 異常,退出程式。
TOMCAT的載入機制:下面是tomcat的目錄
Bootstramp: 載入虛擬機器所需的jar.以及jdk中標準的擴充套件類jre/lib/ext目錄下面
System: 載入tomcat啟動檔案catalina.bat檔案中指定的類
Common:載入tomcat的lib包下面的類。
最後載入應用載入器首先載入CLASSPATH ,其次載入 WEB-INFO/lib目錄下的jar檔案
當應用需要到某個類時,則會按照下面的順序進行類載入:
1、使用bootstrap引導類載入器載入
2、使用system系統類載入器載入
3、使用應用類載入器在WEB-INF/classes中載入
4、使用應用類載入器在WEB-INF/lib中載入
5、使用common類載入器在CATALINA_HOME/lib中載入
問題擴充套件
通過對上面tomcat類載入機制的理解,就不難明白 為什麼java檔案放在Eclipse中的src資料夾下會優先jar包中的class?
這是因為Eclipse中的src資料夾中的檔案java以及webContent中的JSP都會在tomcat啟動時,被編譯成class檔案放在 WEB-INF/class中。
而Eclipse外部引用的jar包,則相當於放在 WEB-INF/lib 中。
因此肯定是 java檔案或者JSP檔案編譯出的class優先載入。
通過這樣,我們就可以簡單的把java檔案放置在src資料夾中,通過對該java檔案的修改以及除錯,便於學習擁有原始碼java檔案、卻沒有打包成xxx-source的jar包。
另外呢,開發者也會因為粗心而犯下面的錯誤。
在 CATALINA_HOME/lib 以及 WEB-INF/lib 中放置了 不同版本的jar包,此時就會導致某些情況下報載入不到類的錯誤。
還有如果多個應用使用同一jar包檔案,當放置了多份,就可能導致 多個應用間 出現類載入不到的錯誤。