是什么原因导致java.lang.incompatibleClassChangeError?

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


答案 1

这意味着您已经对库进行了一些不兼容的二进制更改,而无需重新编译客户端代码。Java语言规范§13详细描述了所有此类更改,最突出的是将非非私有字段/方法更改为或反之亦然。staticstatic

针对新库重新编译客户端代码,您应该可以放心。

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


答案 2

新打包的库与旧版本不向后兼容二进制 (BC)。因此,某些未重新编译的库客户端可能会引发异常。

这是 Java 库 API 中更改的完整列表,这些更改可能会导致使用旧版库构建的客户端抛出 java.lang。不兼容的类更改错误,如果它们在新的上运行(即中断BC):

  1. 非最终字段变为静态,
  2. 非恒定场变为非静态,
  3. 类变成接口,
  4. 接口变成类,
  5. 如果向类/接口添加新字段(或添加新的超类/超级接口),则来自客户端类 C 的超接口的静态字段可能会隐藏从 C 的超类继承的添加字段(同名)(非常罕见)。

注意:由其他不兼容的更改导致许多其他异常NoSuchFieldErrorNoSuchMethodErrorIllegalAccessErrorInstantiationErrorVerifyErrorNoClassDefFoundErrorAbstractMethodError

关于BC的更好的论文是由Jim des Rivières撰写的“Evolutioning Java-based API 2: Achieveing 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

祝你好运!


推荐