如何在运行时解决jar包冲突?

5

我有两个冲突的JAR文件。它们都包含相同包名和类名的类。由于某些原因,我无法删除其中任何一个。

那么,有没有办法解决这个问题?理想情况下,我希望在运行时可以决定在哪个JAR文件中调用类。

非常感谢大家的帮助。


你是否正在使用像Maven或Gradle这样的构建系统来管理你的依赖关系? - Upio
很遗憾,我的应用程序正在使用ANT。 - Xianyi Ye
5个回答

8
您可以在项目文件夹中创建一个与冲突JAR包相同的包结构,但使用不同的名称,并从任意JAR包中复制相应内容。从JAR包中使用一个包,从您的项目中使用另一个包(刚刚创建的新包)。我最近刚刚这样做了,它有效了。
祝好运!

2
Maven插件https://maven.apache.org/plugins/maven-shade-plugin/可以为您完成此操作。 - Sanjeev Kumar Dangi

3
您在这种情况下的选择是:
1.(最佳方式)修改应用程序代码以使用最新版本的jar。如果您的程序依赖于另一个插件,该插件又依赖于过时的jar文件,请检查该插件的最新版本。
2.使用OSGi。
3.使用两个类加载器。需要学习一些理论,并且有时可能会导致意外错误。
现在我不会提供示例,因为下面的链接中有大量信息和示例可供您参考。 Java, Classpath, Classloading => Multiple Versions of the same jar/project Jar hell: how to use a classloader to replace one jar library version with another at runtime

http://java.dzone.com/articles/java-classloader-handling

http://javarevisited.blogspot.in/2012/12/how-classloader-works-in-java.html


1
任何动态链接的内容都必须有一种在运行时区分链接对象的方式。这正是拥有包层次结构的意义所在,以将代码隔离开来。你可以解决相同类名的问题,但一旦包名称相同,我不知道如何强制JVM链接一个而不是另一个。

1
你可以使用不同的类加载器并在不同的沙盒中运行冲突的组件。
如果两个JAR包都在类路径上,并且你正在使用系统类加载机制,那么没有办法动态选择要使用哪个JAR包。Java类加载器会选择第一个类文件。

0

这是一个旧话题,但有一个解决JAR冲突的方法,但它只适用于JAVA 8。您可以将冲突的JAR文件移动到两个单独的文件夹中,然后在“java.endorsed.dirs”属性中按正确顺序提及它们。这将强制您的应用程序预加载认可的JAR文件及其类以指定的顺序,从而在调用时强制使用所需的类。我为我的运行在JBoss上的应用程序做了这件事,并且有2个具有完全相同类和包的JAR文件。复杂性在于,最终我认可了23个JAR文件而不是2个,因为存在依赖关系,但最终解决方法奏效了-真正的问题得到了解决。不幸的是,从Java8开始,java.endorsed.dirs的支持被删除。如果有人知道如何在最新的Java中执行类似的技巧,请分享。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接