java - 是 6.1 java.lang.VerifyError : class loading constraint violated

标签 java websphere classloader 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 仍然得到相同的错误(不是 类未发现异常)。因此 WAS 似乎正在解析引用 使用与我们的引用文献不兼容的自己的副本 编译的类文件。但是,“xercesImpl.jar”的唯一其他实例 我可以找到(除了我们的应用程序部署的副本)在目录中 deploytool,似乎在应用服务器之外。

我扫描了 WAS 中的所有 jar (全部 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),那么 Unmarshaller 将从 JDK 加载,并且 Unmarshaller 类仅对 JDK InputSource 可见。当您的应用程序创建其 InputSource 时,它​​将从 WAR 加载该类(因为“应用程序优先”策略),然后您的应用程序将尝试将 WAR InputSource 的实例传递给 JDK Unmarshaller,它只能接受一个实例JDK 输入源。

有两种解决方法:

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

根据我的经验,链接错误很难追踪,因为 JVM 提供了有关导致添加链接的原因的糟糕信息。我通常启用类加载器跟踪,重现问题,然后向后走,直到我找到从应用程序外部加载的类,“听起来”它可能引用已知存在于应用程序内部的类。

关于java - 是 6.1 java.lang.VerifyError : class loading constraint violated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2861807/

相关文章:

java - java模块的springframework ldap核心问题

java - 我的 BluetoothCommandService 中的 NullPointerException

servlets - Websphere 中的 Log4j

scala - 动态加载后,A 类无法转换为 A 类

java - 方法与 ? extends Collections<String> 不适用于 Set<String>

java - JSF 部署错误 "at javax.faces.context.FacesContext.isProcessingEvents(FacesContext.java:300)"

python - 解析 Jython 2.1 中的命令行选项

java - InstanceAlreadyExistsException 如何卸载/销毁实例

java - 从 Java 中的类路径加载资源的 URL

java - 如何在页面加载时打开模态对话框