微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WAS 6.1 java.lang.VerifyError:违反了类加载约束

环境是 Linux上的WAS 6.1,部署使用的webapp
来自xercesImpl.jar的类.

由于公司政策限制,应用程序必须部署
设置:

Class Loader Order
    Classes loaded with parent class loader first
->  Classes loaded with application class loader first

WAR class loader policy
    Class loader for each WAR file in application
->  Single class loader for application

WAR文件包含一个xercesImpl.jar的副本,与之相同
当应用程序被编译时在类路径中.

当启动webapp时,当Spring尝试解析其配置时
抛出:

java.lang.VerifyError: class loading constraint violated 
    (class: org/apache/xerces/jaxp/DocumentBuilderImpl 
    method: parse(Lorg/xml/sax/InputSource;)Lorg/w3c/dom/Document;)

分析这么远

看来,WAS提供了一个实现
org.apache.xerces.jaxp.DocumentBuilderImpl,因为我们可以删除
来自WAR文件的xercesImpl.jar仍然得到相同的错误(不是
ClassNotFoundException异常).因此,WAS似乎在解决参考
使用自己的副本与我们的引用不兼容
编译的类文件.但是,唯一的其他“xercesImpl.jar”
我可以找到(除了我们的应用程序部署的副本)在目录中
deploytool,似乎在应用服务器之外.

我扫描了WAS中的所有罐子(全部1300个)

for i in `find . -name \*.jar`; do jar tvf $i|grep -qi xerces && echo $i ; done

并发现./java/jre/lib/xml.jar包含org.apache.xerces.*中的所有类,
所以这很可能是类加载器解析引用的地方.

这里是我的一部分:

如果我们更改为“父类加载器第一”,我们看不到异常.
这违背了预期的行为.我们期待与
“应用程序类加载器第一”它会使用我们的xercesImpl.jar
提供和使用WAS的版本只有当我们设置“父类加载器
第一“,这似乎是从我们实际看到的倒退.

问题:

类加载器委派设置如何与上述信息进行交互以导致观察到的行为?

解决方法

您的WAR还包括org.xml.sax或org.w3c.dom类,然后您引用了也在引用这些类的应用程序之外的类.这设置了一个场景,您的应用程序类加载器可以看到同一个类的两个实例,这是一个链接错误.

例如,如果您的应用程序使用javax.xml.bind.Unmarshaller.unmarshal(InputSource),则将从JDK加载Unmarshaller,并且Unmarshaller类只能查看JDK InputSource.当您的应用程序创建其InputSource时,它将从WAR加载类(因为“应用程序第一”策略),然后您的应用程序将尝试将WAR InputSource的实例传递到JDK解组器,JDK解组器只能接受JDK InputSource.

有两个解决方案:

>从应用程序中删除所有API jar,并使用JDK中的那些.例如,删除包含org.xml.sax或org.w3c.dom的jar.
>在WAR中包含引用要引用的类的所有库.例如,在您的WAR中包含JAXB库的副本.

根据我的经验,链接错误很难跟踪,因为JVM提供了关于什么导致链接添加的不良信息.我通常启用类加载器跟踪,重现问题,然后向后移动,直到找到从应用程序外面加载的类似“听起来像”的类,它可能引用已知存在于应用程序中的类.

原文地址:https://www.jb51.cc/java/125422.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐