我将一个Java库打包为JAR,当我试图从它调用方法时,它抛出许多Java .lang. incompatibleclasschangeerror。这些错误似乎是随机出现的。什么样的问题会导致这个错误?
当前回答
While these answers are all correct, resolving the problem is often more difficult. It's generally the result of two mildly different versions of the same dependency on the classpath, and is almost always caused by either a different superclass than was originally compiled against being on the classpath or some import of the transitive closure being different, but generally at class instantiation and constructor invocation. (After successful class loading and ctor invocation, you'll get NoSuchMethodException or whatnot.)
如果这种行为看起来是随机的,那么它很可能是多线程程序类根据最先遇到的代码加载不同的传递依赖项的结果。
要解决这些问题,请尝试使用-verbose作为参数启动VM,然后查看异常发生时正在加载的类。你应该会看到一些令人惊讶的信息。例如,拥有相同依赖项的多个副本,以及您从未预料到的版本,或者如果您知道它们被包括在内,您就不会接受这些版本。
用Maven解决重复的jar最好是结合Maven下的Maven - Dependency - Plugin和Maven -enforcer- Plugin(或SBT的Dependency Graph Plugin),然后将这些jar添加到顶级POM的一部分或作为SBT中的导入依赖元素(以删除这些依赖)。
好运!
其他回答
另一种可能出现此错误的情况是Emma Code Coverage。
这发生在将Object分配给接口时。我猜这与对象被检测和不再二进制兼容有关。
http://sourceforge.net/tracker/?func=detail&aid=3178921&group_id=177969&atid=883351
幸运的是,这个问题在Cobertura中没有发生,所以我在pom.xml的报告插件中添加了Cobertura -maven-plugin
I have also discovered that, when using JNI, invoking a Java method from C++, if you pass parameters to the invoked Java method in the wrong order, you will get this error when you attempt to use the parameters inside the called method (because they won't be the right type). I was initially taken aback that JNI does not do this checking for you as part of the class signature checking when you invoke the method, but I assume they don't do this kind of checking because you may be passing polymorphic parameters and they have to assume you know what you are doing.
示例c++ JNI代码:
void invokeFooDoSomething() {
jobject javaFred = FredFactory::getFred(); // Get a Fred jobject
jobject javaFoo = FooFactory::getFoo(); // Get a Foo jobject
jobject javaBar = FooFactory::getBar(); // Get a Bar jobject
jmethodID methodID = getDoSomethingMethodId() // Get the JNI Method ID
jniEnv->CallVoidMethod(javaFoo,
methodID,
javaFred, // Woops! I switched the Fred and Bar parameters!
javaBar);
// << Insert error handling code here to discover the JNI Exception >>
// ... This is where the IncompatibleClassChangeError will show up.
}
Java代码示例:
class Bar { ... }
class Fred {
public int size() { ... }
}
class Foo {
public void doSomething(Fred aFred, Bar anotherObject) {
if (name.size() > 0) { // Will throw a cryptic java.lang.IncompatibleClassChangeError
// Do some stuff...
}
}
}
在我的例子中,当我添加com时出现了错误。nimbusds库在我部署在Websphere 8.5的应用程序中。 发生了以下异常:
原因:java.lang.IncompatibleClassChangeError: org.objectweb.asm.AnnotationVisitor
解决方案是从库中排除asm jar:
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>5.1</version>
<exclusions>
<exclusion>
<artifactId>asm</artifactId>
<groupId>org.ow2.asm</groupId>
</exclusion>
</exclusions>
</dependency>
我得到这个错误是因为我有一个抽象基类,它承诺实现某个接口,但我忘记了添加接口方法的实现,然后我创建了一个非抽象(具体)字节码生成的类,它扩展了抽象类,也没有提供这些方法的实现。
当我尝试创建字节码生成类的实例时,JVM抱怨java.lang.IncompatibleClassChangeError。
幸运的是,该异常有一个“message”成员,它提供了关于出错原因的更详细信息。在我的例子中,消息清楚地说,特定的类应该实现特定的接口,但它实际上并没有实现它。
如果你从事android开发。然后给一个尝试重建选项可能是为你修复。
推荐文章
- 为什么“System.out。”println“工作在Android?
- 在Java中什么时候使用可变参数?
- Mockito的argumentCaptor的例子
- 我如何告诉Spring Boot哪个主类用于可执行jar?
- 如何将Java8流的元素添加到现有的列表中
- 在Java 8中是否可以转换流?
- 不区分大小写的字符串作为HashMap键
- 什么是maven中的“pom”打包?
- 在Java中创建一个自定义事件
- 创建正则表达式匹配数组
- 我如何在Java中初始化一个全零的数组列表?
- 主体、使用者和主体之间的意义和区别是什么?
- 将字节转换为十六进制
- HashSet和HashMap的区别?
- 我如何有效地解析HTML与Java?