是什么导致了 java.lang.IncompatibleClassChangeError?

新手上路,请多包涵

我将 Java 库打包为 JAR,当我尝试从中调用方法时,它会抛出许多 java.lang.IncompatibleClassChangeError s。这些错误似乎是随机出现的。什么样的问题可能导致此错误?

原文由 Zombies 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 675
2 个回答

这意味着您在没有重新编译客户端代码的情况下对库进行了一些不兼容的二进制更改。 Java Language Specification §13 详细说明了所有此类更改,最突出的是,将非 static 非私有字段/方法更改为 static ,反之亦然。

针对新库重新编译客户端代码,您应该可以开始了。

更新:如果您发布公共图书馆,您应该尽可能避免进行不兼容的二进制更改,以保持所谓的“二进制向后兼容性”。理想情况下,单独更新依赖项 jar 不应破坏应用程序或构建。如果您确实必须打破二进制向后兼容性, 建议 在发布更改之前增加主版本号(例如从 1.xy 到 2.0.0)。

原文由 notnoop 发布,翻译遵循 CC BY-SA 3.0 许可协议

您新打包的库与旧版本 不向后二进制兼容(BC)。由于这个原因,一些没有重新编译的库客户端可能会抛出异常。

这是 Java 库 API 中更改的 完整 列表,这些更改可能会导致使用旧版本库构建的客户端抛出 java.lang。 IncompatibleClassChangeError 如果他们在一个新的上运行(即打破 BC):

  1. 非最终字段变为静态,
  2. 非常量场变成非静态的,
  3. 类成为接口,
  4. 接口成为类,
  5. 如果您向类/接口添加一个新字段(或添加新的超类/超接口),那么来自客户端类 C 的超接口的静态字段可能会隐藏从继承的添加字段(具有相同的名称) C 的超类(非常罕见的情况)。

注意:还有许多 其他不兼容的更改引起的异常NoSuchFieldErrorNoSuchMethodErrorIllegalAccessErrorInstantiationErrorVerifyErrorNoClassDefFoundErrorAbstractMethodError

关于 BC 的更好的论文是由 Jim des Rivières 撰写的 “Evolving Java-based APIs 2: Achieving API Binary Compatibility”

还有一些 自动工具 可以检测此类更改:

为您的图书馆使用 japi-compliance-checker:

 japi-compliance-checker OLD.jar NEW.jar

clirr工具的使用:

 java -jar clirr-core-0.6-uber.jar -o OLD.jar -n NEW.jar

祝你好运!

原文由 linuxbuild 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题