如何在JBoss 7中部署两个交叉依赖的EAR以防止ClassCastExceptions?

时间:2014-01-20 16:57:46

标签: deployment jboss7.x classloader classcastexception ear

在Jboss 7中部署两个ear文件时遇到问题,感谢您的帮助。

以下方案:

EAR 1 包含在服务器启动时由 EAR 2 (也)查找的EJB。因此,必须在 EAR 2 之前部署 EAR 1 (通过 jboss-deployment-structure.xml 依赖项设置)。

在部署之后, EAR 1 还需要访问 EAR 2 中包含的类,因为Hibernate和JNDI相关的类加载(以及其他)。

但由于当时未部署 EAR 2 EAR 1 需要包含 EAR 2的客户端jar文件

现在,问题是在 EAR 1 EAR 2 配置(服务器启动时) ClassCastExceptions < / strong>发生因为......

  • (非EJB)Java对象 obj1 ,其类 C 由<的类加载器< strong> EAR 1 ,受JNDI约束
  • 并且在被查找之后,应该被投射到对象 obj2 ,其类 C 被加载 EAR 2
  • 的类加载器

现在我想知道,如果有可能在JBoss 7中使用相同的类加载器加载 EAR 1 EAR 2 这些常见类,我已经尝试过把它们放在一个服务器模块中,但是没有用完。

非常感谢您的帮助!

PS:我知道上面声明的设计不佳。但是由于限制,我必须跟进它。

1 个答案:

答案 0 :(得分:1)

为了避免类转换异常,需要将公共库放在两个EAR中所有应用程序通用的类加载器中,并且每个应用程序中不应存在这些库的其他副本。

如果只使用一个EAR而不是两个EAR,则将所有WAR放在一个EAR中,从WAR中删除公共类并将它们放在EAR库文件夹中。

这会将公共类与EAR类加载器相关联,这对于在EAR中运行的所有应用程序是通用的,这样就可以解决问题。

如果必须使用两个EARS,则需要将公共类放在所有应用程序共享的服务器级别的类加载器中。

JBoss 7是一个基于OSGI的容器,允许创建一个带有几个jar的隔离模块并将其链接到应用程序。所以如果你试试这个:

  • 使用公共库及其依赖项创建模块,请参阅说明here
  • 将模块链接到所有应用程序
  • 从所有应用程序中删除这些库的副本,并仅将其保留在模块

它会正常工作,但不要忘记将公共库的依赖项放在模块中,否则它将无法工作,依赖项需要在模块级别可见,并且可能没有模块和应用程序之间的重复jar(否则可能会发生类转换异常)。

另一种不太值得推荐的方法,但也可以使用,是将公共类放在公共类加载器的级别,请参阅此diagram。公共类加载器文件夹位于$CATALINA_HOME/lib(Jboss内部基于Tomcat)。

特别是如果在该服务器中运行其他应用程序,请不要尝试第二个选项。查看我为这类问题构建的工具JHades

可能会有所帮助