【问题标题】:How to resolve jar conflicts in runtime?如何解决运行时的 jar 冲突?
【发布时间】:2015-06-15 17:55:55
【问题描述】:

我有两个罐子有冲突。它们都包含一个具有相同包名和类名的类。由于同样的原因,我无法删除它们中的任何一个。

那么,有什么办法可以解决这个问题吗?理想情况下,我希望有一种方法可以让我决定在运行时应该在哪个类中调用 jar。

感谢任何人的帮助。

【问题讨论】:

  • 您是否使用 maven 或 gradle 之类的构建系统来管理您的依赖项?
  • 很遗憾,不,我的应用正在使用 ANT。

标签: java jar jvm


【解决方案1】:

任何动态链接的东西都必须有某种方法来区分在运行时链接的内容。这就是使用包层次结构来划分代码的全部意义所在。您可以解决相同类名的问题,但是一旦包相同,我不知道有一种方法可以强制 JVM 相互链接。

【讨论】:

    【解决方案2】:

    您可以使用不同的类加载器并在不同的沙箱中运行相互冲突的组件。

    如果两个 jar 都在类路径上,并且您正在使用系统类加载机制,则无法动态选择要使用的 jar。 Java 类加载会为您挑选第一个类文件。

    【讨论】:

      【解决方案3】:

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

      祝你好运!

      【讨论】:

      【解决方案4】:

      在这种情况下,您的选择是。

      1.(最佳方式)修改应用程序代码以使用最新版本的 jar。如果您的程序依赖于另一个插件,该插件依赖于过时的 jar 文件,请检查插件的最新版本。

      1. 使用 OSGi

      2. 使用两个类加载器。需要学习一点理论,有时会导致意想不到的错误。

      现在我不打算放例子了,因为下面的链接中有很多信息和例子可以帮助你

      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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-11-20
          • 1970-01-01
          • 2016-12-27
          • 2014-01-29
          • 2012-01-09
          • 2016-02-22
          • 2013-11-09
          • 1970-01-01
          相关资源
          最近更新 更多