一天前,我的应用程序是一个 EAR,包含一个 WAR、一个 EJB JAR 和几个实用程序 JAR 文件。我在其中一个实用程序文件中有一个 POJO 单例类,它可以正常工作,并且一切都很好:
EAR
|--- WAR
|--- EJB JAR
|--- Util 1 JAR
|--- Util 2 JAR
|--- etc.
然后我创建了第二个 WAR 并发现(很难)每个 WAR 都有自己的 ClassLoader,所以每个 WAR 看到一个不同的单例,然后事情就从那里崩溃了。这不是很好。
EAR
|--- WAR 1
|--- WAR 2
|--- EJB JAR
|--- Util 1 JAR
|--- Util 2 JAR
|--- etc.
所以,我正在寻找一种方法来创建一个可以跨 WAR(跨 ClassLoaders?)工作的 Java 单例对象。EJB 注释似乎很有希望,@Singleton
直到我发现 JBoss 5.1 似乎不支持该注释(它是作为 EJB 3.1 的一部分添加的)。我错过了什么吗 - 我可以@Singleton
与 JBoss 5.1 一起使用吗?升级到 JBoss AS 6 现在不是一个选项。
或者,我很高兴不必使用 EJB 来实现我的单例。我还能做些什么来解决这个问题?基本上,我需要一个半应用程序范围* 挂钩到一大堆其他对象,如各种缓存数据和应用程序配置信息。作为最后的手段,我已经考虑将我的两个 WAR 合并为一个,但这将是非常糟糕的。
*含义:基本上在某一层以上的任何地方都可用;现在,主要是在我的 WAR 中——视图和控制器(在松散的意义上)。
编辑:我真的应该称它为Java EE而不是 J2EE,不是吗?
编辑2:再次感谢@Yishai 的所有帮助。经过一些试验和错误后,看起来我已经弄清楚如何在 JBoss 5 下跨 WAR 使用单个 ClassLoader。为了我自己,我将在下面详细说明这一点,希望其他人也会发现这也很有用。
注意这与在 JBoss 4 下执行此操作有很大不同(请参阅 Yishai 的回答或我下面的链接)。
不要jboss-web.xml
为每个 WAR编写一个文件,也不要jboss.xml
为 ear EJB-JAR编写一个文件,而是jboss-classloading.xml
在每个 WAR 中放置一个文件,与 DD ( ) 位于相同的位置web.xml
。的内容jboss-classloading.xml
应该是:
<?xml version="1.0" encoding="UTF-8"?>
<classloading
xmlns="urn:jboss:classloading:1.0"
name="mywar.war"
domain="DefaultDomain"
parent-domain="Ignored"
export-all="NON_EMPTY"
import-all="true">
</classloading>
这来自 JBoss CW here,而(我认为)适用于 JBoss 4.x 的内容在此处描述。有关 JBoss 类加载(ing/ers)的更多一般信息:
据我所知,与 JBoss 4 相比,JBoss 5 的 JBoss 社区 wiki 文档相当缺乏。