我将一个Java库打包为JAR,当我试图从它调用方法时,它抛出许多Java .lang. incompatibleclasschangeerror。这些错误似乎是随机出现的。什么样的问题会导致这个错误?
当前回答
我在与玻璃鱼的战争中反复部署时遇到过这个问题。我的班级结构是这样的,
public interface A{
}
public class AImpl implements A{
}
它被改成了
public abstract class A{
}
public class AImpl extends A{
}
在停止并重新启动域之后,结果很好。 我用的是glassfish 3.1.43
其他回答
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的最终项目时。
如果你使用scala和sbt和scala-logging作为依赖项,那么这可能会发生,因为scala-logging的早期版本的名称是scala-logging-api.因此,本质上依赖项解析不会发生,因为不同的名称会导致启动scala应用程序时的运行时错误。
这意味着您已经对库进行了一些不兼容的二进制更改,而无需重新编译客户端代码。Java语言规范§13详细描述了所有这些更改,最突出的是将非静态的非私有字段/方法更改为静态或反之亦然。
根据新的库重新编译客户端代码,应该就可以开始了。
更新:如果你发布了一个公共库,你应该尽可能避免做出不兼容的二进制更改,以保持所谓的“二进制向后兼容性”。单独更新依赖jar在理想情况下不会破坏应用程序或构建。如果你不得不打破二进制向后兼容性,建议增加主版本号(例如从1.x。Y到2.0.0),然后发布更改。
我遇到了同样的问题,后来我发现我是在Java版本1.4上运行应用程序,而应用程序是在版本6上编译的。
实际上,这是因为有一个重复的库,一个位于类路径中,另一个包含在位于类路径中的jar文件中。
在我的例子中,当我添加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>
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap