猿问

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

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

我正在将Java库打包成一个JAR,它正在抛出许多java.lang.IncompatibleClassChangeError当我尝试从它调用方法时。这些错误似乎是随机出现的。什么类型的问题会导致这个错误?



喵喔喔
浏览 976回答 3
3回答

Cats萌萌

这意味着您在没有重新编译客户端代码的情况下对库进行了一些不兼容的二进制更改。Java语言规范§13详细说明所有这些变化,最突出的是,不-static非私有字段/方法static反之亦然。根据新的库重新编译客户端代码,您应该会做得很好。更新:如果发布公共库,则应尽可能避免进行不兼容的二进制更改,以保留所谓的“二进制向后兼容性”。理想情况下,只更新依赖JAR不应该破坏应用程序或构建。如果您必须破坏二进制向后兼容性,那么推荐在发布更改之前增加主版本号(例如,从1.x.y增加到2.0.0)。

噜噜哒

你的新包装库不是向后二进制兼容。(BC)旧版本。因此,一些未重新编译的库客户端可能引发异常。这是一个完全Java库API中可能导致用旧版本的库构建的客户端抛出java.lang的更改列表。不兼容ClassChangeError如果它们运行在新的(即破坏BC)上:非终场变成静态的,非恒定场变成非静态的,类成为接口,界面变成了类,如果将新字段添加到类/接口(或添加新的超类/超级接口),则客户端类C的超级接口中的静态字段可能隐藏从C的超类继承的添加字段(同名)(非常罕见)。注*有许多其他例外由其他不兼容的更改引起的:NoSuchFieldError, NoSuchMethodError, IllegalAccessError, InstantiationError, VerifyError, NoClassDefoundError和抽象方法.关于不列颠哥伦比亚省的更好的论文是发展中的基于Java的API 2:实现api二进制兼容性作者:Jim des Rivières。还有一些自动工具为了发现这种变化:日本-合规检查器克里尔日本醇乙氏试验日检对您的图书馆使用japi遵从性检查器:japi-compliance-checker OLD.jar NEW.jarClirr工具的使用:java -jar clirr-core-0.6-uber.jar -o OLD.jar -n NEW.jar祝好运!

元芳怎么了

虽然这些答案都是正确的,但解决问题往往更加困难。这通常是两个不同版本的类路径依赖关系的结果,并且几乎总是由与原来编译的类路径不同的超类造成的。或传递闭包的某些导入是不同的,但通常在类实例化和构造函数调用时。(在成功加载类和调用ctor之后,您将获得NoSuchMethodException或诸如此类的东西。)如果行为看起来是随机的,那么很可能是多线程程序类加载不同传递依赖项的结果。要解决这些问题,请尝试使用-verbose作为参数,然后查看异常发生时加载的类。你应该看到一些令人惊讶的信息。例如,有多个相同的依赖项和版本的副本,如果您知道它们被包含了,那么您从来没有想过或者会接受它们。使用Maven解析重复的JAR最好使用maven-依赖-插件和maven-forcer-plugin在Maven(或SBT)下依赖图插件,然后将这些JAR添加到顶级POM的一部分或作为SBT中导入的依赖项(以消除这些依赖项)。祝好运!
随时随地看视频慕课网APP

相关分类

Java
我要回答