java - Jboss 5、类加载器和多个类实例

标签 java jboss dependencies

我的申请有问题。为了恢复这个问题,我不得不将应用程序从 jboss 4 迁移到 jboss 5。

在 war 部署期间,我遇到了这个错误:

java.lang.LinkageError: loader constraint violation: when resolving field "DATETIME"
the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class,
javax/xml/datatype/DatatypeConstants, and the class loader (instance of <bootloader>)
for the field's resolved type, javax/xml/namespace/QName,
have different Class objects for that type

经过多次搜索,我发现这个错误就在这里,因为我在不同的包中有好几次同一个类。一次在依赖包中(来 self 的 pom.xml),一次由 jboss 提供。

因此,为了解决这个问题,我为我的依赖项“提供”了一个范围。

但我不明白为什么这个解决方案有效。我认为在一个应用程序中多次使用同一个类是可行的。我知道这不是一件好事,但对于 jboss 4,它很管用。

有人可以解释为什么它适用于 jboss 4 而不适用于 jboss 5。

感谢您的解释:)

最佳答案

您看到的是应用服务器在单独的类加载器中加载 JBoss 库和 EAR 库的效果

您可以认为 EAR 的类加载器层次结构类似于(但不一定):

Bootstrap 类加载器 -> 系统类加载器 -> JBoss 系统类加载器 -> Ear 类加载器 -> War 类加载器。

war 类加载器的父类是 ear 类加载器等等。

现在,如果 Bootstrap ClasssLoader 加载了一个 jar A,并且 ear 也在部署 jar A,Bootstrap Class Lodaer 和 Ear Class Loader 将在不同的类加载器中创建两次相同的类。

我假设(不是 100% 确定)JBoss 4 没有与 javax/xml/namespace/QName 捆绑在一起。如果这是真的,那么 JBoss 5 更可能是一个不同的、升级的 Java 版本(4 -> 5 或 5 -> 6)。结果(在新的 JBoss 5 中),当您尝试将 javax/xml/namespace/QName 传递到您的其中一个类时,它会期待从耳朵听到该类。但是,由于类加载器首选项(父优先等),您从 Bootstrap 类加载器为其提供 QName 类。

由于类类型相等但类实例不相等,您会得到一个 LinkageError

编辑:

只是两个地址的两个评论 -

jtahlborn 指出的类加载行为绝对不同。在正常的应用程序中,像 QName 这样的系统类将始终在引导类加载器中查找。在您的错误中,它看起来好像正在 org/jboss/classloader/spi/base/BaseClassLoader 中加载 javax/xml/datatype/DatatypeConstants。让我们假设这就是 EAR 类加载器(或 WAR)。快速谷歌显示它是 xml-apis 家族的一部分,也可能是 jaxp-api。

因此您的代码(或位于 EAR 的类加载器中的另一个库代码)中的某处需要 DatatypeConstants - 这会强制在 EAR 的类加载器中查找类。尽管 QName 对象的创建从引导类加载器(而不是 EAR)加载了类。如果 QName 类已经被系统初始化,就会发生这种情况,它可能已经初始化了。

正如您想象的那样,这是不可能发生的。它实际上看起来像你有 parent 最后。因为当从 JBoss 类加载机制加载一个类时,如果启用了父级优先,则初始 DatatypeConstants 将返回父级( Bootstrap )的 DatatypeConstants 而不是子级。因此,正如 jtahlborn 所指出的,您可能希望忽略此处的子类加载器。

就解决方案而言,除非您出于特定原因需要依赖项(例如稍微更新的版本比当前版本更好),否则我会委托(delegate)给 jboss 的实现。如果不是这种情况,您可以查看 jboss 配置中的 class-loading java2ClassLoadingCompliance 元素。

关于java - Jboss 5、类加载器和多个类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5638191/

相关文章:

java - Google map v2 - 用不同颜色绘制路线 - Android

java - 为什么 getNextZipEntry 会跳过几个文件的根目录?

java - Eclipse Mars 不显示 Jboss 服务器

java - 无法在 KIE 工作台 (jBPM) 中添加 Java 导入

java - Maven 中未使用/未声明的依赖项是什么?该怎么办?

java - 在 Jboss 模块和项目依赖项之间选择库版本

java - 如何使用 Java 运行时执行文件

java - Ant 嵌套更新

c++ - g++ 生成依赖文件缺少用户定义的 header

java - 在 Windows 8.1 上 "javac -version"有效但 Cordova 无法识别