【问题标题】:Why does java.lang.VerifyError prevent successful compilation?为什么 java.lang.VerifyError 会阻止成功编译?
【发布时间】:2014-09-28 12:23:52
【问题描述】:

根据这个话题: Reasons of getting a java.lang.VerifyError

java.lang.VerifyError 获取执行 jvm 的版本是否比用于编译的 jvm 更新。

我们总是可以使用以下 jvm 选项来解决这个问题:-XX:-UseSplitVerifier

据此:

https://stackoverflow.com/a/16467026/2674303

使用此选项“非常安全”。

因此我不明白为什么 java.lang.VerifyError 是阻止成功编译的问题。请澄清。也许对于检测字节码的库来说不安全?

【问题讨论】:

  • 它不会“阻止”成功编译。相反,编译在某种程度上不成功/错误,导致了 VerifyError。从本质上讲,.class 文件似乎已损坏。
  • (但是引用的线程谈到使用一个选项导致 JVM 使用旧验证器而不是“改进”的验证器。目前尚不清楚被规避的问题是否在类文件中(在StackMapTable 构造)或在新的验证器中(使用该表),但在任何一种情况下,规避都应该是完全安全的。)

标签: java jvm compatibility bytecode bytecode-manipulation


【解决方案1】:

您链接的问答是指特定类型的验证错误,可以通过使用替代验证程序安全地解决这些错误。但是,还有其他类型的验证错误,您不应该忽略......而且您无法以这种方式处理。

简而言之,链接问题中的建议并不普遍适用。一般来说:

  • 切换到备用验证器可能无济于事。

  • 如果您完全禁用验证程序,您可能会运行可能违反 JVM 运行时类型安全 (etc) 约束的代码。这可能导致安全问题和/或堆损坏和 JVM 硬崩溃。


如果您有需要建议的特定 VerifyError,请包括完整的异常消息和堆栈跟踪,并描述它发生的情况。请注意,安德烈的回答是正确的,验证错误的常见原因是出于各种目的进行“字节码工程”的代码中的错误。通常,解决方法是更改​​相应依赖项的不同版本。

【讨论】:

  • 理想情况下,也发布有问题的类文件。
  • 因此这个选项不是那么安全。即使你在相应的情况下使用它也可以隐藏未来的错误。
  • 值得注意的是,-XX:-UseSplitVerifier 选项在 Java 8 中不再支持,将被完全忽略。所以它不能解决任何问题。
【解决方案2】:

VerifyError 发生在您的字节码在某些方面不正确时。例如,当它尝试从未初始化的变量中读取数据或将原始值分配给Object 类型的字段时。检测库可能存在导致生成此类格式错误的字节码的错误。如果您可以分享错误的确切细节,我们可能会更具体地说明确切原因。

【讨论】:

    【解决方案3】:

    目标是强制工具和库在操作 Java 字节码时生成正确的StackMapTable 属性,这样 JVM 就不必进行缓慢而复杂的type inferencing 阶段验证,而只需快速简单的@987654323 @阶段。

    -XX:-UseSplitVerifier 在 Java 8 中已被弃用,它不再有任何帮助。

    【讨论】:

    • -XX:-UseSplitVerifier 在 Java 8 中并未被弃用,它已被完全删除。
    【解决方案4】:

    在JVM加载类的过程中会抛出VerifyError,所以它出现在运行时级别,而不是编译级别。

    1. 并非总是可以通过使用旧验证程序来修复问题。当这有帮助时,有一个特殊情况。仅当类适用于较旧的验证程序并且缺少在 JVM 1.6 中引入并且在 JVM 1.7 中是强制性的时,它才会有所帮助

    2. 如果你想摆脱 VerifyError 和 UseSplitVerifier 没有帮助,这意味着从 JVM 的角度来看你的类是不正确的。您仍然可以关闭整个验证,但这可能会导致问题。

    3. 当您不知道自己在做什么时,字节码操作总是很危险。现在主要的字节码操作库支持 StackMapFrames 计算,因此它们可以生成适用于每个 VM 的字节码。但是,用户仍然可以在类文件级别生成不正确的字节码,在这种情况下,JVM 仍然会在加载时抛出 VerifyError,SplitVerifier 将无济于事。只有禁用验证才会强制 VM 加载该类,但在执行时可能会出现一些错误。

    【讨论】:

      猜你喜欢
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多