1. 程式人生 > >jvm類載入和tomcat類載入機制

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包檔案,當放置了多份,就可能導致 多個應用間 出現類載入不到的錯誤。