java 如何解决运行时的 jar 冲突?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29554225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to resolve jar conflicts in runtime?
提问by Xianyi Ye
I have two jars are conflicted. Both of them contain a class with the same package name and class name. Due to same reasons, I cannot remove either of them.
我有两个罐子是冲突的。它们都包含一个具有相同包名和类名的类。由于同样的原因,我无法删除它们中的任何一个。
So, is there any way to resolve this issue? Ideally, I hope there is a way can let me decide the class in which jars should be invoked during runtime.
那么,有没有办法解决这个问题呢?理想情况下,我希望有一种方法可以让我决定在运行时应在哪个类中调用 jar。
I do appreciate anyone's help.
我很感激任何人的帮助。
回答by Alekhya Vemavarapu
You can create a package structure (same as the one in your conflicting jars) in your project folder with a different name& copy respective contents from any of the jars. Use one package from the jar and the other from your project (the new package which you just created) I have done this very recently and it worked.
您可以在项目文件夹中使用不同的名称创建包结构(与冲突 jar 中的包结构相同)并从任何 jar 复制相应的内容。使用 jar 中的一个包和您的项目中的另一个包(您刚刚创建的新包)我最近完成了这个并且它有效。
Good Luck!
祝你好运!
回答by Raj
Your options in this case are.
在这种情况下,您的选择是。
1.(Best way) Modify app code to use latest version of jar. If your program depends on another pluggin which depends on the outdated jar file check for latest version of the pluggin.
1.(最佳方式)修改应用程序代码以使用最新版本的jar。如果您的程序依赖于另一个依赖于过时 jar 文件的插件,请检查该插件的最新版本。
Use OSGi
Use two classloaders. Need to study a little bit of theory and can sometimes lead to unexpected errors.
使用 OSGi
使用两个类加载器。需要研究一点点理论,有时会导致意想不到的错误。
Now I am not going to put examples as there is plenty of info and examples in the links below to assist you
现在我不打算放例子,因为下面的链接中有很多信息和例子可以帮助你
Java, Classpath, Classloading => Multiple Versions of the same jar/project
Java、类路径、类加载 => 同一个 jar/项目的多个版本
Jar hell: how to use a classloader to replace one jar library version with another at runtime
Jar 地狱:如何使用类加载器在运行时将一个 jar 库版本替换为另一个
http://java.dzone.com/articles/java-classloader-handling
http://java.dzone.com/articles/java-classloader-handling
http://javarevisited.blogspot.in/2012/12/how-classloader-works-in-java.html
http://javarevisited.blogspot.in/2012/12/how-classloader-works-in-java.html
回答by gobbly
Anything that is dynamically linked will have to have some way to distinguish what to link with at run time. That's the whole point of having package hierarchy, to compartmentalize the code. You can get around the issue of identical class names but once the packages are the same I don't know of a way to force the JVM to link against one over another.
任何动态链接的内容都必须有某种方式来区分在运行时链接的内容。这就是使用包层次结构来划分代码的全部意义所在。您可以解决相同类名的问题,但是一旦包相同,我不知道有什么方法可以强制 JVM 相互链接。
回答by gaborsch
You can use different classloaders and run conflicting components in different sandboxes.
您可以使用不同的类加载器并在不同的沙箱中运行冲突的组件。
There is no way to dynamically pick which jar to use if both jars are on the classpath, and you are using the system classloading mechanism. Java classloading picks you the first class file.
如果两个 jar 都在类路径上,并且您使用的是系统类加载机制,则无法动态选择要使用的 jar。Java 类加载为您选择第一个类文件。
回答by ph4
This is old topic, but there was a solution for JAR conflicts, but it works only till JAVA 8. You could move your conflicting JARs into two separate folders, and then mention them in the correct order in "java.endorsed.dirs" property. This will force your app to pre-load the endorsed JARs and its classes in the specified order, forcing desired classes to be used later when called. I did it for my app which ran on JBoss and had 2 JARs with exactly same class and package. The complexity was that I ended up endorsing 23 JARs instead of 2, as there were dependencies, but finally the workaround worked - real issue was fixed. Unfortunately support of java.endorsed.dirs was removed starting from Java8. If anyone have an idea how to do similar trick for latest Java, please, share.
这是一个老话题,但有一个解决 JAR 冲突的方法,但它只适用于 JAVA 8。您可以将冲突的 JAR 移动到两个单独的文件夹中,然后在“java.endorsed.dirs”属性中以正确的顺序提及它们. 这将强制您的应用程序以指定的顺序预加载认可的 JAR 及其类,从而强制稍后在调用时使用所需的类。我为我在 JBoss 上运行的应用程序做了它,并且有 2 个具有完全相同的类和包的 JAR。复杂的是我最终支持 23 个 JAR 而不是 2 个,因为存在依赖关系,但最终解决方法奏效了 - 真正的问题得到了解决。不幸的是,从 Java8 开始取消了对 java.endorsed.dirs 的支持。如果有人知道如何为最新的 Java 做类似的技巧,请分享。