【问题标题】:Refer a class from specific jar file从特定的 jar 文件中引用一个类
【发布时间】:2012-01-24 05:39:36
【问题描述】:

我在我的程序中陷入了相当尴尬的境地。 情况是......我的项目在类路径中有一些 A.jar 文件,其中包含许多重要的实用程序类..但是这个 A.jar 是相当旧的文件,我们无法替换它,因为我们不确定它的重要性和重要性持有…… 现在,我需要来自 ServletResponse I/F 的方法 request.setCharacterencoding()response.setCharacterEncoding,但是这个 A.jar 包含旧版本的 ServletResponse,因此我没有得到上述两种方法。现在我介绍了新的servlet-api.jar 在类路径中,但我的项目仍然从 A.jar 引用 servletResponse 类,而不是从新的 servlet-api.jar 引用。

你们能否建议我从servlet-api.jar 而不是A.jar 中获取新servletResponse 的引用的方法

(P.s.:我无法删除/修改 A.jar)

谢谢...

【问题讨论】:

  • 您可以使用自定义类加载器并使用该类加载器从 servlet-api 加载类,然后从那里获取它。不过,这可能很难靠您自己完成。如果您在应用程序服务器(例如 JBoss、Websphere、Glassfish 等)上运行,您可以查看其类加载策略如何支持您。
  • 这个问题可能对你有帮助:stackoverflow.com/q/252893/644766

标签: java jar conflict


【解决方案1】:

如果不做任何特别的事情,你会被搞砸的:类是按照它们在类路径中的顺序加载的。

但是,您可以编写一个自定义的ClassLoader,它可以对您需要的类执行特殊操作,特别是在这种情况下从servlet-api.jar 加载ServletResponse,否则在类路径中具有A.jar 之前 servlet-api.jar

附言找出谁创建了一个与 ServletRequest 具有相同包和名称的类并杀死他们。

【讨论】:

    【解决方案2】:

    实际上,JVM 会按顺序查找类,尝试从列表中的资源中加载它们。例如,如果您的类路径看起来像 new.jar;old.jar 并且两个 jar 具有同一类的不同版本,则将使用来自 new.jar 的版本。

    请注意,如果您使用的是 Unix,请使用 : 而不是 ;

    但请允许我表达我的怀疑。你的项目听起来有问题。为什么您的自定义 jar 中有ServletRequest?我应该使用标准j2ee.jar 或类似的东西来获取这种标准类。据我所知,在过去的 12 年中,只有一种方法从 servlet API 中删除:执行 servlet 到 servlet 通信的能力。这发生在大约 10 年前。因此,如果您使用的是最新版本的标准 servlet API,包括旧代码在内的所有内容都应该可以正常工作。

    【讨论】:

    • 嗨,亚历克斯,由于该项目相当古老,并且其中包含许多其他小模块,因此他们可能为此创建了包含所有实用程序类的 A.jar。(我仍然是不确定)
    • 感谢大家的快速建议。最后我通过将 servlet-api.jar 首先放在类路径中,然后是其他文件来解决它...
    【解决方案3】:

    让 servlet-api.jar 在您的类路径中位于 A.jar 之前。

    但是,您的问题并没有全部解决!如果 A.jar 中的某些内容需要 Servlet API 的旧实现,但新的实现已经加载,它会做什么?或者当其他人没有相同顺序的类路径时会发生什么?

    解压 A.jar 并将其重新打包为 A-modified.jar 可能会更好

    【讨论】:

    • 感谢 Flwyd,但正如我之前提到的 .. 我无法修改 A.jar
    【解决方案4】:

    我看到的唯一方法是获取或创建ClassLoader,然后将您的类内容作为字节数组获取,然后加载您的类。

    【讨论】:

      【解决方案5】:

      简单的解决方案,如果这两个 ServletRqquest 在不同的包中,不要导入旧的,而是使用完整的包名访问它。 或者您必须编写自己的类加载来加载该 jar。

      【讨论】:

        【解决方案6】:

        当您运行 jar 文件时,使类路径反映您要加载的 jar 的顺序。让我知道您是否需要精确的语法,但一般来说,如果您有 CLASSPATH=patch16.jar:patch15.jar:patch14.jar:... 等,它将加载该类的第一个匹配副本,从 patch16 开始.jar 然后 patch15.jar 等。

        有关确切语法的更多信息: http://javarevisited.blogspot.com/2011/01/how-classpath-work-in-java.html

        【讨论】:

        • -1 这不能回答问题:重新排列类路径没有帮助,因为存在交叉依赖项
        • 那么你无论如何都必须重新编译代码。 (或者确保用新 jar 中的新类覆盖所有旧类以避免任何依赖问题)。此外,可以在启动脚本中设置类路径以保持可移植性。
        • 你严重忽略了重点。设置类路径永远不会解决这个问题,因为他想要来自 A.jar 和一些来自 B.jar 的两个 jar 共有的一些类。逻辑告诉你,无论你如何设置类路径,你永远无法满足这个要求。您实际上也不必重新编译(java 链接动态...这就是他 这个问题的原因),但您必须为 JVM 提供自定义类加载器 - 这将涉及重新编译,但仅限于自定义类加载器。
        猜你喜欢
        • 2019-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-01
        • 1970-01-01
        • 2015-02-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多