2014-09-20 74 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