您所看到的是应用程序服务器在单独的类加载器中加载JBoss的库和EAR库的效果
您可以想到EAR的类加载器层次结构类似于(但不一定)类似于:
Bootstrap ClassLoader->系统类加载器-> JBoss系统类加载器-> Ear Class Loader-> War Class
Loader。
战争类装载者的父母是耳朵类装载者,依此类推。
现在,如果Bootstrap ClasssLoader加载了jar A,并且耳朵也与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之类的系统类。在您的错误中,看起来好像javax
/ xml / datatype / DatatypeConstants被加载到org / jboss / classloader / spi / base
/ baseClassLoader中。让我们假设EAR类加载器(或WAR)。一个快速的谷歌显示它是xml-apis家族的一部分,并且可能是jaxp-api。
因此,您的代码中的某个地方(或EAR的类加载器中的其他库代码)需要DatatypeConstants-
强制在EAR的类加载器中查找类。尽管QName对象的创建是从引导类加载器(而不是EAR)加载了类。如果QName类可能已经被系统初始化,则会发生这种情况。
您可以想像这是不可能发生的。实际上看起来您有双亲。因为从JBoss类加载机制中加载类时,如果启用了父级优先,则初始DatatypeConstants将返回父级(引导)的DatatypeConstants而不是子级。因此,正如jtahlborn指出的那样,您希望此处的孩子的类加载器被忽略。
就解决方案而言,除非出于特定原因需要依赖项(例如比当前版本更好的更新版本),否则我将委托给jboss的实现。如果不是这种情况,您可以看一下
class-loading java2ClassLoadingCompliancejboss配置中包含的元素。



