Jboss 5,类加载器和多个类实例

我的申请有问题。 要恢复这个问题,我必须将应用程序从jboss 4迁移到jboss 5。

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

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 ) for the field's resolved type, javax/xml/namespace/QName, have different Class objects for that type 

经过多次搜索,我发现这个错误在这里是因为我在不同的包中有过几次相同的类。 一旦进入依赖包(来自我的pom.xml)并且一次由jboss提供。

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

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

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

谢谢你的解释:)

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

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

Bootstrap ClassLoader – > System Class Loader – > JBoss System Class Loader – > Ear Class Loader – > War Class Loader。

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

现在,如果Bootstrap ClasssLoader加载了jar A并且还使用jar A部署了ear,则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的类加载器中查找类。 虽然从引导类加载器(而不是EAR)加载了类,但是创建了QName对象。 如果QName类已经被系统初始化(可能是它),就会发生这种情况。

你可以想象这不会发生。 它实际上看起来像你有父母的最后一个。 因为在从JBoss类加载机制加载类时,如果已启用parent-first,则初始DatatypeConstants将返回父级(bootstrap)DatatypeConstants而不是childs。 因此,jtahlborn指出,你会希望忽略孩子们的类加载器。

就解决方案而言,除非您因特定原因需要依赖项(比较新版本比当前更好),我将委托给jboss的实现。 如果不是这种情况,您可以查看jboss配置所具有的class-loading java2ClassLoadingCompliance元素。

-verbose:class VM args中的类将给出如何加载Class。 如果有重复,您可以删除冲突的jar / jar。

谢谢你的解释 – 这非常有帮助。

我了解到这个问题与在5.0.0版本中修复的JBoss错误有关。 但即使我运行的是旧版本的JBoss,我仍然遇到此错误。 无论如何,我做了大量研究并运行maven依赖树几次,以查看重复定义的来源。 我终于能够通过向我的主pom添加两个依赖项(将范围设置为提供)来解决此错误:
(sun.jaxb-impl 2.1,javax.jaxb-api 2.2)我希望这些信息有助于某人。