为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

喵喔喔 2019-06-10 16:33:09
是什么原因导致java.lang.inpatibleClassChangeError?我正在将Java库打包成一个JAR,它正在抛出许多java.lang.IncompatibleClassChangeError当我尝试从它调用方法时。这些错误似乎是随机出现的。什么类型的问题会导致这个错误?
查看完整描述

3 回答

?
Cats萌萌

TA贡献1805条经验 获得超9个赞

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

根据新的库重新编译客户端代码,您应该会做得很好。

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


查看完整回答
反对 回复 2019-06-10
?
噜噜哒

TA贡献1784条经验 获得超7个赞

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

这是一个完全Java库API中可能导致用旧版本的库构建的客户端抛出java.lang的更改列表。不兼容ClassChangeError如果它们运行在新的(即破坏BC)上:

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

*有许多其他例外由其他不兼容的更改引起的:NoSuchFieldErrorNoSuchMethodErrorIllegalAccessErrorInstantiationErrorVerifyErrorNoClassDefoundError抽象方法.

关于不列颠哥伦比亚省的更好的论文是发展中的基于Java的API 2:实现api二进制兼容性作者:Jim des Rivières。

还有一些自动工具为了发现这种变化:

对您的图书馆使用japi遵从性检查器:

japi-compliance-checker OLD.jar NEW.jar

Clirr工具的使用:

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

祝好运!


查看完整回答
反对 回复 2019-06-10
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

虽然这些答案都是正确的,但解决问题往往更加困难。这通常是两个不同版本的类路径依赖关系的结果,并且几乎总是由与原来编译的类路径不同的超类造成的。传递闭包的某些导入是不同的,但通常在类实例化和构造函数调用时。(在成功加载类和调用ctor之后,您将获得NoSuchMethodException或诸如此类的东西。)

如果行为看起来是随机的,那么很可能是多线程程序类加载不同传递依赖项的结果。

要解决这些问题,请尝试使用-verbose作为参数,然后查看异常发生时加载的类。你应该看到一些令人惊讶的信息。例如,有多个相同的依赖项和版本的副本,如果您知道它们被包含了,那么您从来没有想过或者会接受它们。

使用Maven解析重复的JAR最好使用maven-依赖-插件maven-forcer-plugin在Maven(或SBT)下依赖图插件,然后将这些JAR添加到顶级POM的一部分或作为SBT中导入的依赖项(以消除这些依赖项)。

祝好运!


查看完整回答
反对 回复 2019-06-10
  • 3 回答
  • 0 关注
  • 975 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号