2011-09-20 69 views
3

是否有一個標準的方式(即,通過一些Java/J2EE /等規範中定義),以提供一個自定義的類加載器將Java Servlet容器應用來加載WAR文件?爲WAR文件強制自定義ClassLoader?

上,我們正在展開一個大型商業Java軟件包(美孚)與Web服務需要部署一定的靈活性(作爲單獨的服務等)的新項目。特別是,我們希望避免在每個WAR文件中包含所有Foo軟件​​依賴性Jar文件,因爲它們很多,很大,並且隨着我們的開發,將會隨補丁/錯誤修復版本發生變化。同樣,不得不將所有依賴複製到每個Servlet容器的「lib」目錄中。

理想情況下,我想告訴大家,這些WAR文件必須使用自定義的類裝載器,我將提供自動包括富軟件的依賴罐子裝的Java應用服務器。像這樣的東西(在Java的僞代碼):

public class MyWarFileClassLoader extends ClassLoader { 
    protected URLClassLoader urlcl; 
    public MyWarFileClassLoader(File warFile) { 
    File installDir = System.getEnv("FOO_HOME"); 
    List<File> fooEntries = new File(installDir, "jars").listFiles("*.jar"); 
    fooEntries.add(new File(installDir, "resources")); 
    fooEntries.add(warFile); 
    this.urlcl = new URLClassLoader(fooEntries); 
    } 
    public Class<?> findClass(String name) { 
    return this.urlcl.findClass(name); 
    } 
} 

如果沒有做到這一點沒有標準方式,有一個簡單的方法來達到幾個WAR文件相同的目標,不管目標servlet容器?

[編輯]

換一種方式:有允許WAR文件在運行時管理它們自己的依賴,而不是依賴於Servlet容器配置的通用模式?當然,我可以讓WAR文件清單包含Class-Path屬性,但是這些條目在構建時仍然是「硬編碼」的,而不是在運行時自動檢測到的。

回答

4

有執行在Java EE應用程序使用特定的自定義類裝載器的,從預定義的源加載類的標準方法。然而,在Java EE應用程序中捆綁庫的能力使得多個模塊(包括駐留在WAR中的Web模塊)可以加載和訪問捆綁庫中的類。

Java EE規範允許企業應用程序部署(一個.ear文件)捆綁在一個庫中部署目錄庫;默認情況下,這是.ear文件中的lib目錄。這些庫可能會被.ear文件的根目錄中的多個Web模塊(位於不同的.war文件中)使用。在Java EE 6規範的相關部分是部分EE 8.2.1,其中以下陳述:

一個.ear文件可能包含與包含打包在JAR文件庫的目錄。 .ear文件的部署描述符的library-directory元素包含此目錄的名稱。如果沒有指定library-directory元素,或者如果.ear文件不包含部署描述符,用來命名lib的目錄。可以使用空的library-directory元素來指定不存在庫目錄。

帶有.jar擴展名的此目錄(但不包括子目錄)中的所有文件必須可供包裝在EAR文件中的所有組件(包括應用程序客戶端)使用。這些庫可以引用其他庫,或者與應用程序捆綁在一起,或者單獨安裝,使用這裏描述的任何技術。

重要的是要注意,所有符合Java EE的應用程序服務器(WebLogic/WebSphere/JBoss等)都將支持使用捆綁庫部署EAR文件。但是,有些servlet容器(如Tomcat和Jetty)不符合整個Java EE規範;這樣的容器將不支持部署EAR文件。

如果servlet容器中的多個Web模塊需要訪問庫(由於容器的選擇或WAR文件的偏好),您應該依賴servlet容器支持共享庫在不使用庫的情況下部署WAR文件。 Java EE規範沒有強制要求在這方面使用已安裝的庫。一些容器通過支持版本化的共享庫(部署的應用程序可能只使用一個版本中的一個版本)而比其他版本更好地支持共享庫,而另一些(如Tomcat)則不支持。

+0

感謝這個信息,Vineet,非常有趣。我會細化我的問題,特別提到Servlet容器,因爲我們不需要完整的AppServer。 – maerics

+0

@maerics,我的答案將繼續保持不變,除了您可能依賴JAR清單中的'Extension-List'屬性來允許加載共享庫(它仍將安裝在服務器中適用於每個服務器的方式)。您可能需要閱讀Java EE 6規範中有關庫支持(第8.2節)的整個部分。 –