我的代码在 Jetty
中工作正常,但一旦在 WebSphere
中部署,我就会收到 java.lang.VerifyError
异常,根本没有任何额外信息(甚至没有消息)。
代码:
Class c = Class.forName("javax.xml.xpath.XPathConstants"); // This works
System.out.println(c.getDeclaredFields()); // This works
System.out.println(c.getDeclaredField("NODESET")); // This works (public static final javax.xml.namespace.QName javax.xml.xpath.XPathConstants.NODESET)
System.out.println(XPathConstants.NODESET); // This fails with an empty java.lang.VeryfyError
XPathConstants
是随 JRE
附带的 xml.jar
的一部分。 Jetty
和 WebSphere
都使用 IBM SDK 7
运行,并且代码使用相同版本进行编译。
我不知道它从哪里来。谢谢您的帮助。
这是 StackTrace,尽管它什么也没说,因为 VerifyError
为空
[9/17/15 4:56:01:730 CDT] 000001c0 SystemOut O java.lang.VerifyError
[9/17/15 4:56:01:731 CDT] 000001c0 SystemOut O at com.ibm.idwb.common.filenet.linker.LinkerDocumentLevel.findRelationships(LinkerDocumentLevel.java:1352)
[9/17/15 4:56:01:731 CDT] 000001c0 SystemOut O at com.ibm.idwb.common.filenet.linker.LinkerDocumentLevel.buildKeyDefCache(LinkerDocumentLevel.java:1119)
[9/17/15 4:56:01:731 CDT] 000001c0 SystemOut O at com.ibm.idwb.common.filenet.linker.LinkerDocumentLevel.checkForKeys(LinkerDocumentLevel.java:748)
[9/17/15 4:56:01:731 CDT] 000001c0 SystemOut O at com.ibm.idwb.common.filenet.parallel.cmd.LinkRefreshCommand.refreshLinks(LinkRefreshCommand.java:224)
[9/17/15 4:56:01:732 CDT] 000001c0 SystemOut O at com.ibm.idwb.common.filenet.parallel.cmd.LinkRefreshCommand.access$1(LinkRefreshCommand.java:197)
[9/17/15 4:56:01:732 CDT] 000001c0 SystemOut O at com.ibm.idwb.common.filenet.parallel.cmd.LinkRefreshCommand$1.call(LinkRefreshCommand.java:161)
[9/17/15 4:56:01:732 CDT] 000001c0 SystemOut O at com.ibm.idwb.common.filenet.parallel.cmd.LinkRefreshCommand$1.call(LinkRefreshCommand.java:1)
[9/17/15 4:56:01:732 CDT] 000001c0 SystemOut O at com.ibm.idwb.common.parallel.executor.CountableTask.call(Unknown Source)
[9/17/15 4:56:01:733 CDT] 000001c0 SystemOut O at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:345)
[9/17/15 4:56:01:733 CDT] 000001c0 SystemOut O at java.util.concurrent.FutureTask.run(FutureTask.java:177)
[9/17/15 4:56:01:733 CDT] 000001c0 SystemOut O at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1121)
[9/17/15 4:56:01:733 CDT] 000001c0 SystemOut O at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
[9/17/15 4:56:01:734 CDT] 000001c0 SystemOut O at java.lang.Thread.run(Thread.java:777)
最佳答案
缺少VerifyError消息是JVM缺陷,您应该将其报告给Java团队。
这很可能是一个类链接错误。您的类路径中很可能有一个包含 javax.xml.namespace.QName 的 JAR,并且它比来自 Liberty 的副本更受青睐(例如,您可以使用 <classloader delegation="parentLast"/>
)。情况是这样的:
应用程序类:
- com.ibm.idwb.common.filenet.linker.LinkerDocumentLevel
- javax.xml.namespace.QName
自由/JDK
- javax.xml.xpath.XPathConstants
- javax.xml.namespace.QName
有两个 QName 类,但类加载器只能链接到其中之一;如果您尝试链接到两者,您将收到错误。当您使用反射访问 NODESET 字段时,您仅要求 Liberty/JDK 类加载器代表 XPathConstants 解析 QName 字段。当您使用直接字段引用时,您还要求应用程序类加载器解析 XPathConstants 类(它从 Liberty/JDK 中找到)以及 QName 类(它在与 Liberty/JDK 类加载器在将 QName 链接到 XPathConstants 时找到它的位置不同的位置找到它)。
您需要:
- 删除parentLast(或任何导致重复QName类加载的内容)
- 从应用程序类路径中删除包含重复的 javax.xml.namespace.QName 类的 JAR
- 将包含重复 javax.xml.xpath.XPathConstants 类的 JAR 添加到应用程序类路径,以便完全(而不是部分)复制类层次结构
(如果这个分析是正确的,那么不幸的是 JVM 抛出的是VerifyError,而不是更具体的LinkageError。)
关于WebSphere 中的 XPAthConstants.NODESET 出现 java.lang.VerifyError,但 Jetty 中没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32649840/