WAS的類加載機制二

12.2 概覽Websphere 類加載器

注意:每一個JVM都有自己的類加載器。在WebSphere 環境中會有多個應用程序服務器(JVM),也就是說JVM的類加載器是分開的,儘管它們運行在同一個物理機器上。

還需要注意的是:Java虛擬機(JVM) 使用的擴展和應用程序類加載器,你能夠看到WebSphere 運行環境也使用名爲擴展和應用程序類加載器,儘管它們的名字有些一致,但它們和JVM使用的是不一樣的。

WebSphere 提供了幾個客戶化委託類加載器,如下圖12-2:

圖12-2 Webspere 類加載器層次圖


最頂端的方框表示Java類加載器(引導、擴展和應用程序)。WebSphere 在這裏加載它自己的引導類加載器和初始化WebSphere擴展類加載器。

12.2.1 WebSphere 擴展類加載器

V6.1新特性: WebSphere 擴展類加載器是WebSphere 加載自己的地方。在WebSphere之前的版本,運行環境被單一的類加載器加載。然而,從WAS6.1開始,WebSphere 被打包成若干OSGi(Open Services Gateway Initiative) 包。每一個OSGi 包都由自己的類加載器加載。OSGi 類加載器的網絡通過OSGi網關類加載器跟擴展類加載器和類加載器層次結構中的其餘部分相連。

    不管WebSphere裝入自己類的方式如何改變,應用程序也不會有改變。還是同樣的可見性、同樣的類加載選擇。

V6.1新特性:WAS之前的版本中,WebSphere運行時類文件保存在<was_home>目錄下的classes、lib、lib\ext和installedChannels 目錄下。由於OSGi包,這些目錄都不存在了,運行時類文件會存放在<was_home>\plugins 目錄下。

擴展類加載器的類路徑是由ws.ext.dirs 系統屬性指定,也就是setupCmdLine 腳本文件中指定的WAS_EXT_DIRS環境變量設置。ws.ext.dirs 的缺省值如例12-3:

例12-3 we.ext.dirs 的缺省值

SET

WAS_EXT_DIRS=%JAVA_HOME%\lib;%WAS_HOME%\classes;%WAS_HOME%\lib;%WAS_HOME%\insta

lledChannels;%WAS_HOME%\lib\ext;%WAS_HOME%\web\help;%ITP_LOC%\plugins\com.ibm.e

tools.ejbdeploy\runtime

ws.ext.dirs 環境變量中列出的每個路徑都會被添加到WebSphere擴展類加載器的類路徑中,並且該目錄中的每個JAR文件和ZIP文件都會被添加到類路徑中。

正如所看到的,儘管在<was_home>目錄中不再有classes、lib、lib\ext 和installedChannels文件夾,但是setupCmdLine 腳本文件會把它們添加到擴展類路徑中。這就意味着,如果之前你已經把自己的JAR文件添加到<was_home>\lib 目錄下,你可以創建這個目錄並且把JAR文件添加進去,它們依然會被擴展類加載器加載。然而,不推薦這麼做,在安裝過程中還是正確的遷移比較好。

另一方面,如果你已經開發了Java應用程序,它依賴之前在<was_home>\lib 目錄下的WebSphere JAR文件,你需要讓你的程序保留兼容性。WAS 6.1 針對這樣的應用程序提供了兩種瘦客戶端庫:管理客戶端庫和Web 服務客戶端庫。可以在<was_home>\runtimes 目錄下面找到這兩個客戶端庫:

_ com.ibm.ws.admin.client_6.1.0.jar

_ com.ibm.ws.webservices.thinclient_6.1.0.jar

這些庫爲應用程序提供了連接和與WebSphere一起工作的所有內容。

缺省設置是Allow,意思是你的應用程序可以無限制的調用非公用的內部WebSphere 類。但是不推薦這麼使用,在未來的版本這個功能可能會被限制。因此,作爲管理員,如果應用程序還能正常運行,最好把這個設置改成Restrict。如果它們依賴非公用的WebSphere內部類,你就收到一個ClassNotFoundException,這樣還得改成Allow。這樣開發人員就需要對應用程序進行移植,以保證應用程序能夠兼容未來的WAS版本。

V6.1新特性:WAR 6.1 限制對WebSphere內部類的訪問,這樣你的程序纔不會依賴那些未公開發布的WAS 的API。這個設置針對每個服務器(JVM),稱爲訪問內部服務器類。

12.2.2 應用程序和Web模塊類加載器

J2EE 應用程序包含五個主要元素:Web 模塊,EJB 模塊,應用程序客戶端模塊,資源適配器(RAR文件),工具JAR。工具JAR包含了EJB 和Servlet使用的代碼。log4j  就是一個好的典型的工具框架的例子。EJB 模塊、工具JAR、資源適配器文件和應用程序關聯的共享庫都會歸結到同一個類加載器。這個類加載器稱爲應用程序類加載器。根據類加載器的規則,缺省情況下,多個應用程序(EAR)可以共享這個類加載器或者每一個應用程序都有對應的類加載器。

缺省情況下,Web 模塊使用它們自己的類加載器(WAR類加載器)加載WEB-INF/classes 和EB-INF/lib 目錄下的內容。通過修改應用程序WAR類加載策略可以改變這個缺省情況。

缺省情況,應用程序中每個WAR文件都有自己的類加載器(早期的版本,這個設置稱爲 Module)。如果WAR類加載策略設置成Single(早期的版本稱爲Application)類加載器,除了EJB、RAR、工具JAR以及共享庫之外,Application類加載器還加載Web模塊的內容。Application類加載器是WAR類加載器的父親。Application類加載器和WAR類加載器都是可重裝入的類加載器。一旦它們自動監測到程序代碼改變了,就會重裝入修改的類。我們可以在部署應用程序的時候改變這個行爲。

12.2.3 操縱JNI 代碼

因爲JVM只有一個地址空間,每個地址空間中native代碼只能裝入一次,JVM規範要求在JVM中native代碼只能被一個類加載器加載。

例如,這將導致一個問題,如果你有一個包含兩個Web模塊的應用程序(EAR文件),兩個Web模塊都需要通過Java Native Interface(JNI)裝入native 代碼,那麼只有第一個被加載的Web模塊能夠成功。

爲了解決這個問題,你可以把加載到類中的native 代碼拆分成多個Java代碼並且把它放在WebShpere應用程序類加載器(放在工具JAR)中。然而,如果要在同一個應用程序(JVM)中部署多個這樣的應用程序(EAR文件),你需要把類文件放到WebSphere擴展類加載器上,取代每個JVM只能加載一次native代碼。

如果native 代碼放在一個可加載的類加載器(比如應用程序類加載器或者WAR類加載器),有一點很重要:能夠正確的卸載自己的native代碼而Java代碼能夠重加載。WebSphere 無法控制native代碼,如果native代碼不能正確的卸載或者加載,應用程序可能失敗。

    如果native 庫依賴另一個,事情就會變得很複雜。關於native庫的依賴關係,請查看信息中心。

12.3 配置 WebSphere 類加載器

在之前的內容中,我們瞭解了WebSphere 類加載器以及類加載器如何協同工作。這一部分我們會討論如何修改WAS的配置來影響Websphere類加載的行爲。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章