根据这个主题: Reasons of getting a java.lang.VerifyError
java.lang.VerifyError
获取执行jvm的版本是否比用于编译的jvm更新。
我们始终可以使用以下jvm选项解决此问题:-XX:-UseSplitVerifier
。
据此:
https://stackoverflow.com/a/16467026/2674303
使用此选项是“非常安全”。
因此我不明白为什么java.lang.VerifyError是阻止成功编译的问题。请澄清。也许对于检测字节码的库来说是不安全的?
答案 0 :(得分:5)
您链接的Q& A是指使用替代验证程序可以安全解决的特定类型的验证错误。但是,还有其他类型的验证错误,你不应该忽略......并且你不能以这种方式处理。
简而言之,关联问题中的建议一般不适用。一般来说:
切换到替代验证程序可能不会有帮助。
如果完全禁用验证程序,则可能会运行可能违反JVM运行时类型安全(等)约束的代码。这可能导致安全问题和/或堆损坏以及硬JVM崩溃。
如果您有需要建议的特定VerifyError,请包含完整的异常消息和堆栈跟踪,并描述它发生的情况。请注意,安德烈的答案是正确的,验证错误的常见原因是正在执行"字节码工程的代码中的错误。出于各种目的。通常,修复方法是更改为相应依赖项的不同版本。
答案 1 :(得分:1)
VerifyError
。例如,当它尝试从未初始化的变量读取或将原始值分配给类型Object
的字段时。检测库可能存在导致生成这种格式错误的字节码的错误。如果您可以分享错误的确切详细信息,我们可能会更准确地说明确切原因。
答案 2 :(得分:1)
目标是强制工具和库在操作Java字节码时生成正确的StackMapTable属性,这样JVM就不必进行缓慢而复杂的type inferencing
验证阶段,而只需要快速执行和简单的type checking
阶段。
-XX:-UseSplitVerifier
已在Java 8中弃用,它将不再有用。
答案 3 :(得分:1)
在JVM类加载期间抛出VerifyError,因此它出现在运行时级别,而不是编译级别。
我们并不总是可以使用旧的验证程序修复probem。有一个特殊情况,这有助于。它只有在类更老的验证程序时才有用,并且缺少在JVM 1.6中引入的StackMapTable,并且在JVM 1.7中是强制性的
如果你想摆脱VerifyError和UseSplitVerifier没有帮助,这意味着你的类从JVM的角度来看是不正确的。您仍然可以关闭整个验证,但这可能会导致问题。
当您不知道自己在做什么时,字节码操纵总是危险的。现在,主字节码操作库支持StackMapFrames计算,因此它们可以生成每个VM的字节码。但是,用户仍然可以生成在类文件级别上不正确的字节码,在这种情况下,JVM仍然会在加载时抛出VerifyError,SplitVerifier不会提供帮助。只有禁用验证才会强制VM加载该类,但在执行时可能会出现错误。
答案 4 :(得分:0)
你碰巧使用Java 7u65或8u11吗?如果是这样,那么本文可能与您的问题相关:http://www.takipiblog.com/oracles-latest-java-8-update-broke-your-tools-how-did-it-happen/
如果你最近一直在关注Java世界的新闻, 您可能听说过Oracle发布的最新Java 8版本, Java 8u11(和Java 7u65),引入了错误并打破了一些流行 ZeroTurnaround的JRebel,Javassist,Google等第三方工具 Guice,甚至是Groovy本身。
这些错误突然出现的原因源于这一事实 最新更新中的字节码验证器有点严格 比以前的版本。与以前的版本不同,它没有 允许从分支代码中调用超级构造函数。