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


当前回答

I have a web application that deploys perfectly fine on my local machine's tomcat(8.0.20). However, when I put it into the qa environment (tomcat - 8.0.20), it kept on giving me the IncompatibleClassChangeError and it was complaining that I was extending on an interface. This interface was changed to an abstract class. And I compiled the parent and child classes and still I kept on getting the same issue. Finally, I wanted to debug, so, I changed the version on the parent to x.0.1-SNAPSHOT and then compiled everything and now it is working. If someone is still hitting the problem after following the answers given here, please make sure the versions in your pom.xml are also correct. Change the versions to see if that works. If so, then fix the version problem.

其他回答

在浪费了太多时间后记录下另一个场景。

确保您的依赖jar中没有包含带有EJB注释的类。

我们有一个普通的jar文件,它有一个@local注释。这个类后来从这个公共项目移到我们的主ejb jar项目中。ejb jar和公共jar都捆绑在ear中。我们的公共jar依赖项的版本没有更新。因此,两个类试图成为具有不兼容的更改的东西。

In my case, I ran into this error this way. pom.xml of my project defined two dependencies A and B. And both A and B defined dependency on same artifact (call it C) but different versions of it (C.1 and C.2). When this happens, for each class in C maven can only select one version of the class from the two versions (while building an uber-jar). It will select the "nearest" version based on its dependency mediation rules and will output a warning "We have a duplicate class..." If a method/class signature changes between the versions, it can cause a java.lang.IncompatibleClassChangeError exception if the incorrect version is used at runtime.

高级:如果A必须使用C的v1, B必须使用C的v2,那么我们必须在A和B的poms中重新定位C,以避免类冲突(我们有一个重复类警告),当构建依赖于A和B的最终项目时。

由于某种原因,当使用JNI并在调用Call*Method()时传递jclass参数而不是jobject时,也会抛出相同的异常。

这与《食人魔诗篇》第33篇中的回答相似。

void example(JNIEnv *env, jobject inJavaList) {
    jclass class_List = env->FindClass("java/util/List");

    jmethodID method_size = env->GetMethodID(class_List, "size", "()I");
    long size = env->CallIntMethod(class_List, method_size); // should be passing 'inJavaList' instead of 'class_List'

    std::cout << "LIST SIZE " << size << std::endl;
}

我知道在被问到这个问题5年后再回答这个问题有点晚了,但这是搜索java.lang.IncompatibleClassChangeError时最热门的问题之一,所以我想记录这个特殊情况。

请检查你的代码是否由两个具有相同类名和包定义的模块项目组成。例如,如果有人使用复制粘贴来创建基于先前实现的接口的新实现,就会发生这种情况。

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