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


当前回答

我的答案,我相信,将是Intellij具体。

我重新构建干净,甚至手动删除“out”和“target”dirs。Intellij有一个“无效缓存并重新启动”,它有时会清除奇怪的错误。这次没有成功。依赖版本在项目设置->模块菜单中看起来都是正确的。

最后的答案是从本地maven repo中手动删除我的问题依赖项。旧版本的bouncycastle是罪魁祸首(我知道我只是改变了版本,这就是问题所在),尽管旧版本没有出现在正在建造的东西中,但它解决了我的问题。我使用的是intellij版本14,然后在此过程中升级到15。

其他回答

在我的例子中:

我有一个项目包含几个模块,包括应用程序,测试,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)的命名冲突。在测试中更改文件名就可以了。

我的答案,我相信,将是Intellij具体。

我重新构建干净,甚至手动删除“out”和“target”dirs。Intellij有一个“无效缓存并重新启动”,它有时会清除奇怪的错误。这次没有成功。依赖版本在项目设置->模块菜单中看起来都是正确的。

最后的答案是从本地maven repo中手动删除我的问题依赖项。旧版本的bouncycastle是罪魁祸首(我知道我只是改变了版本,这就是问题所在),尽管旧版本没有出现在正在建造的东西中,但它解决了我的问题。我使用的是intellij版本14,然后在此过程中升级到15。

我在与玻璃鱼的战争中反复部署时遇到过这个问题。我的班级结构是这样的,

public interface A{
}

public class AImpl implements A{
}

它被改成了

public abstract class A{
}

public class AImpl extends A{
}

在停止并重新启动域之后,结果很好。 我用的是glassfish 3.1.43

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

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

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

这个问题的另一个原因是,如果你为Android Studio启用了即时运行。

修复

如果发现开始出现此错误,请关闭“立即运行”。

Android Studio主要设置 构建、执行、部署 即时运行 取消勾选“启用即时运行…”

Why

即时运行在开发过程中修改了大量的东西,以使它更快地提供更新到您的运行应用程序。因此,即时运行。当它起作用时,它真的很有用。然而,当出现这样的问题时,最好的办法是关闭即时运行,直到Android Studio发布下一个版本。