我将一个Java库打包为JAR,当我试图从它调用方法时,它抛出许多Java .lang. incompatibleclasschangeerror。这些错误似乎是随机出现的。什么样的问题会导致这个错误?


当前回答

另一种可能出现此错误的情况是Emma Code Coverage。

这发生在将Object分配给接口时。我猜这与对象被检测和不再二进制兼容有关。

http://sourceforge.net/tracker/?func=detail&aid=3178921&group_id=177969&atid=883351

幸运的是,这个问题在Cobertura中没有发生,所以我在pom.xml的报告插件中添加了Cobertura -maven-plugin

其他回答

我遇到了同样的问题,后来我发现我是在Java版本1.4上运行应用程序,而应用程序是在版本6上编译的。

实际上,这是因为有一个重复的库,一个位于类路径中,另一个包含在位于类路径中的jar文件中。

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

根据新的库重新编译客户端代码,应该就可以开始了。

更新:如果你发布了一个公共库,你应该尽可能避免做出不兼容的二进制更改,以保持所谓的“二进制向后兼容性”。单独更新依赖jar在理想情况下不会破坏应用程序或构建。如果你不得不打破二进制向后兼容性,建议增加主版本号(例如从1.x。Y到2.0.0),然后发布更改。

如果你使用scala和sbt和scala-logging作为依赖项,那么这可能会发生,因为scala-logging的早期版本的名称是scala-logging-api.因此,本质上依赖项解析不会发生,因为不同的名称会导致启动scala应用程序时的运行时错误。

在我的例子中:

我有一个项目包含几个模块,包括应用程序,测试,integrationTest 我在app模块中创建了OneElementCache。 然后,我在测试模块中创建了一个文件Cache,该文件包含了一些用于在测试中创建OneElementCache的帮助。 到目前为止,一切都很完美(测试和集成测试都通过了)。 之后,我在app模块中创建了一个文件缓存。 在运行integrationTest时得到:

Caused by: java.lang.IncompatibleClassChangeError: 
    class app.cache.CacheImpl can not implement app.cache.Cache, because it is not an interface (app.cache.Cache is in unnamed module of loader 'app')

原因是不同模块(app/test)的命名冲突。在测试中更改文件名就可以了。

所有以上-无论出于什么原因,我做了一些大的重构,开始得到这个。我重命名了我的接口所在的包,这就清除了它。希望这能有所帮助。