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

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

环境是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 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的实例

有两种解决方案:

  • 从应用程序中删除所有API JAR,并使用JDK中的API JAR。例如,删除包含org.xml.sax或org.w3c.dom的jar
  • 在WAR中包括引用要引用的类的所有库。例如,在WAR中包含JAXB库的副本
  • 根据我的经验,链接错误很难追踪,因为JVM提供了导致添加链接的糟糕信息。我通常启用类加载器跟踪,重现问题,然后向后走,直到发现从应用程序外部加载的类“听起来像”它可能引用应用程序内部已知的类

    如果我们改为“父类加载器” 首先,“我们没有看到例外。 这与预期相反 行为

    是的,这是正确的,这是你看到这种行为的唯一途径。我可以建议你看一看“你真的有加载器吗?”的谈话,因为你的问题没有单一或简短的答案


    我们的问题是部署在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