2014-09-20 73 views
2

考慮以下幾點:support.jarJavaEE的模塊類加載和靜態變量

public class SupportUtil{ 

    private static Map<String, Resource> myResources; 

    void init(){ 
    initResources(); 
    } 
} 

然後我有2個獨立戰爭應用程序相同的JavaEE服務器(當前使用wildfly 8)內遠程conneting到另一個EJB模塊

war1 -> lib/support.jar 
war2 -> lib/support.jar 
ejb1 -> ear-lib/support.jar 

我的問題是,基於組件的類加載架構,將三個模塊看到相同的地圖關爲MyResources(考慮到這是一個類變量,類變量是由所有實例共享)

我需要澄清,對於野蠅或glassfish,classloading會如何影響這種行爲。

+0

一旦這個類已經被加載,靜態的myResources將會與它一起被加載,並且它的相同副本將會與你所有的模塊共享,直到有類的引用。 – 2014-09-20 09:43:19

+0

@DarshanLila會爲這三個模塊加載SupportUtil的同一個類加載器(讀取ModuleClassLoader的相同實例)嗎?請記住,這些是獨立的部署單元。 – maress 2014-09-20 09:52:15

回答

0

這場戰爭被認爲是單一模塊,所以WEB-INF/lib中定義的類與WEB-INF/classes中的類相同。戰爭中打包的所有類都將加載相同的類加載器。

默認情況下,EAR/lib目錄是單個模塊,每個WAR或EJB jar部署也是一個單獨的模塊。

每個模塊都會用自己的靜態字段值加載它自己的類實例。

子部署(戰爭和EJB-罐子)總是具有父模塊,這使他們在EAR/lib中訪問類的依賴關係,但是它們並不總是有在彼此的自動相關性。此行爲通過ee子系統配置中的ear-subdeployments-isolated設置進行控制。

WAR通常依賴於EAR/lib。所以你的WAR模塊會「看到」SupportUtil的兩個實例。當代碼在WAR模塊上下文中執行時(在Web應用程序請求期間),它會看到它自己的lib實例SupportUtil。當WAR在遠程(甚至是本地)調用EJB時​​,模塊上下文切換到EJB,並且SupportUtil的「當前」實例來自EAR/lib模塊。 (聲明:我沒有測試這個,但這是我的理解。)

我不會建議進入這個位置,當一個模塊可以訪問同一類的多個實例。我沒有任何失敗的故事來支持它,它似乎是一個潛在的混淆源:同一模塊中的代碼可以看到不同的值,具體取決於執行的方式。

雖然有一個特例。

ear-subdeployments-isolated元素值對.war文件的獨立類加載器沒有影響。即無論此標誌是設置爲true還是false,.war中的.war都將具有獨立的類加載器,並且該.ear中的其他子部署將無法訪問該.war中的類。這是根據規範。

戰爭總是孤立的!所以你可以在多個WAR中擁有相同的jar/classes,並且沒有模塊會看到更多的同一類的多個實例。

來源:Class Loading in WildFly