我将 Java 库打包为 JAR,当我尝试从中调用方法时,它会抛出许多 java.lang.IncompatibleClassChangeError
s。这些错误似乎是随机出现的。什么样的问题可能导致此错误?
原文由 Zombies 发布,翻译遵循 CC BY-SA 4.0 许可协议
我将 Java 库打包为 JAR,当我尝试从中调用方法时,它会抛出许多 java.lang.IncompatibleClassChangeError
s。这些错误似乎是随机出现的。什么样的问题可能导致此错误?
原文由 Zombies 发布,翻译遵循 CC BY-SA 4.0 许可协议
您新打包的库与旧版本 不向后二进制兼容(BC)。由于这个原因,一些没有重新编译的库客户端可能会抛出异常。
这是 Java 库 API 中更改的 完整 列表,这些更改可能会导致使用旧版本库构建的客户端抛出 java.lang。 IncompatibleClassChangeError 如果他们在一个新的上运行(即打破 BC):
注意:还有许多 其他不兼容的更改引起的异常: NoSuchFieldError 、 NoSuchMethodError 、 IllegalAccessError 、 InstantiationError 、 VerifyError 、 NoClassDefFoundError 和 AbstractMethodError 。
关于 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 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
3 回答1.7k 阅读✓ 已解决
这意味着您在没有重新编译客户端代码的情况下对库进行了一些不兼容的二进制更改。 Java Language Specification §13 详细说明了所有此类更改,最突出的是,将非
static
非私有字段/方法更改为static
,反之亦然。针对新库重新编译客户端代码,您应该可以开始了。
更新:如果您发布公共图书馆,您应该尽可能避免进行不兼容的二进制更改,以保持所谓的“二进制向后兼容性”。理想情况下,单独更新依赖项 jar 不应破坏应用程序或构建。如果您确实必须打破二进制向后兼容性, 建议 在发布更改之前增加主版本号(例如从 1.xy 到 2.0.0)。