WAS 6.1 java.lang.VerifyError:违反了类加载约束
环境是Linux上的WAS 6.1,部署了一个使用 来自xercesImpl.jar的类 由于公司政策限制,应用程序必须使用 设置:WAS 6.1 java.lang.VerifyError:违反了类加载约束,java,websphere,classloader,verifyerror,Java,Websphere,Classloader,Verifyerror,环境是Linux上的WAS 6.1,部署了一个使用 来自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 f
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试图解析其配置时,它
抛出:
迄今为止的分析
似乎WAS提供了
org.apache.xerces.jaxp.DocumentBuilderImpl,因为我们可以删除
从WAR文件中删除xercesImpl.jar,仍然会收到相同的错误(不是
ClassNotFoundException)。因此,WAS似乎正在解决引用问题
使用与本文档中的引用不兼容的自己的副本
编译类文件。但是,“xercesImpl.jar”的唯一其他实例
我可以在目录中找到(与我们的应用程序一起部署的副本除外)
deploytool
,它似乎位于应用程序服务器之外
我扫描了里面所有的罐子(全部1300个)
并发现/java/jre/lib/xml.jar
包含org.apache.xerces.*
中的所有类,
因此,这可能是类加载器解析引用的地方
这是奇怪的部分:
如果我们改为“父类加载器优先”,我们不会看到异常。
这与预期的行为背道而驰。我们期待着这一点
“应用程序类加载器优先”它将使用我们使用的xercesImpl.jar
仅当我们设置“父类加载器”时才使用WAS的版本
第一”。这似乎与我们实际看到的情况相反
问题是:
classloader委派设置是如何与上述信息交互以产生观察到的行为的?您的WAR还包括org.xml.sax或org.w3c.dom类,然后您引用的是应用程序外部的一个类,该类也引用了这些类。这将设置一个场景,在该场景中,应用程序类加载器可以看到同一类的两个实例,这是一个链接错误 例如,如果应用程序使用javax.xml.bind.Unmarshaller.unmarshal(InputSource),则将从JDK加载Unmarshaller,并且Unmarshaller类仅对JDK InputSource可见。当您的应用程序创建其InputSource时,它将从WAR加载类(因为“应用程序优先”策略),然后您的应用程序将尝试将WAR InputSource的实例传递给JDK解组器,该解组器只能接受JDK InputSource的实例 有两种解决方案:
我们的问题是部署在was 8.5上 在我们的web应用程序中,我们有一个由cxf生成的web服务客户端。没有问题 当我们在tika解析器中添加mime类型检测时,我们遇到了这个问题 我们排除了三个依赖项:
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>${apache.tika.version}</version>
<exclusions>
<exclusion>
<artifactId>geronimo-stax-api_1.0_spec</artifactId>
<groupId>org.apache.geronimo.specs</groupId>
</exclusion>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
<exclusion>
<artifactId>xmlbeans</artifactId>
<groupId>org.apache.xmlbeans</groupId>
</exclusion>
</exclusions>
</dependency>
org.apache.tika
提卡解析器
${apache.tika.version}
geronimo-stax-api_1.0_规范
org.apache.geronimo.specs
干细胞移植
薛西斯
xmlbeans
org.apache.xmlbeans
一旦它们被排除,我们的应用程序就成功启动了 禁用字节码验证
java.lang.VerifyError-运行时未检查异常
一旦类文件加载到WebSphereJVM中,那么字节码变异就是下一个过程。在字节码验证期间,如果我们的类违反了JVM约束,则会出现此错误
禁用字节码验证。去
管理控制台->
server1->
java和进程管理->进程定义->
JVM参数`
在JVM参数中传递以下字符串
-Xverify:none
在工作区中打开ApplicationDeploymentDescriptor xml文件,转到deployment选项卡,选择PARENT_LAST for war,以及第一个选项。这将停止xml验证错误。可能为时已晚,但我们解决了此问题,删除了server.xml中的这一行:
jaxb-2.1听起来不错。如果我理解你的话,问题不在于DocumentBuilderImpl,而在于它是从JDK解决的,而它引用的一个类是在战争中发现的。这并不能解释为什么当我们在WAR中包含xercesImpl.jar时,仍然会出现完全相同的错误,引用相同的方法和类名。你是说消息中引用的方法和类名与问题无关吗?听起来不错。如果我理解你的话,问题不在于DocumentBuilderImpl,而在于它是从JDK解决的,而它引用的一个类是在战争中发现的。这并不能解释为什么在t中包含xercesImpl.jar
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>${apache.tika.version}</version>
<exclusions>
<exclusion>
<artifactId>geronimo-stax-api_1.0_spec</artifactId>
<groupId>org.apache.geronimo.specs</groupId>
</exclusion>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
<exclusion>
<artifactId>xmlbeans</artifactId>
<groupId>org.apache.xmlbeans</groupId>
</exclusion>
</exclusions>
</dependency>
-Xverify:none