【问题标题】:Control the classpath ordering of jars in WEB-INF/lib on Tomcat 5?控制 Tomcat 5 上 WEB-INF/lib 中 jar 的类路径顺序?
【发布时间】:2011-01-02 12:51:06
【问题描述】:

我有一个在 Tomcat 5.0 中运行的旧版 Web 应用程序。

这个网络应用在 WEB-INF/lib 中有两个 jar,比如说 Foo-2.0.jarBar-2.0.jar . Bar-2.0.jar 实际上包含一个 Foo-1.0.jar 在里面。 Bar 也是一个死项目,意味着没有升级,没有源,但对应用程序仍然很重要。

此应用程序的最新版本需要 Foo-2.0.jar 来处理其他一些内容。在类路径中同时包含 Foo-1.0.jarFoo-2.0.jar 会产生冲突,特别是 ClassDefNotFound 类型的错误,其中后来在 2.0 中添加的类在 1.0 中找不到,等等。

在 Eclipse 中,简单的解决方案是右键单击您的 Project,单击 Properties > Java Built Path > Order 和导出 并将 Foo-2.0.jar 移到 Bar-2.0.jar 上方,以便首先解决。

如何在 Tomcat 的 WEB-INF/lib 中完成这种类型的 jar 类路径排序?

【问题讨论】:

    标签: java tomcat jar classpath


    【解决方案1】:

    Tomcat 5's classloading precedence for webapps 大致如下:首先是引导程序/系统(JRE/lib,然后是 Tomcat 的内部类),然后是 webapp 库(首先是 WEB-INF/classes,然后是 WEB-INF/lib),然后是公共库(首先是 Tomcat/common,然后是 Tomcat/lib),最后是 webapp 共享库 (Tomcat/shared)。

    所以要让Foo-2.0.jar 加载之前 Bar-2.0.jar,最好将Bar-2.0.jarWEB-INF/lib 移动到Tomcat/commonTomcat/shared

    JAR 不是按其名称的字母顺序加载的。至少,没有规范说明这一点。重命名它们以更改文件名的字母顺序是没有意义的。

    【讨论】:

    • Georgy 先回答,所以我接受了他的提交,但你所描述的正是我为解决问题所做的。您的链接特别有用。 我鼓励大家投票赞成这个答案
    • 不客气。虽然我会指出这里的答案默认情况下按答案日期排序 not。在撰写本文时,您可以在用户头像的右上角看到我在 23 分钟前回答了这个问题,在 15 分钟前回答了 Georgy。您可以通过答案右上方的oldestnewestvotes 三个选项卡之一更改排序。默认为votes
    • 而且,在工具提示中您可以看到准确的时间。所以我实际上是第一个:o
    【解决方案2】:

    Bar-2.0.jar 中剥离 Foo-1.0.jar。事实上,等待开发(需要捏造开发环境)和部署都是很麻烦的。

    【讨论】:

    • 我真的认为这是最好的建议。重新打包你的 bar-2.0.jar,否则你只是在找麻烦。
    【解决方案3】:

    将 Foo-1.0.jar 放到 $CATALINE_HOME/common/endorsed(或在 Foo-2.0.jar 之后加载它的任何其他位置)。

    【讨论】:

      【解决方案4】:

      您不需要,因为此功能在 Tomcat 中不可用。如果类路径中同时需要 Foo-1.0.jar 和 Foo-2.0.jar,则需要对类路径进行一些重大的重组。

      如果 Bar-2.0 可以与 Foo-2.0 一起使用,那么最好的办法是自己重建 Bar-2.0,而不在其中包含 Foo-1.0.jar。

      【讨论】:

      • 没有办法知道 Bar-2.0 是否与 Foo-2.0 一起工作,它是一个庞大的、只有二进制的库,没有测试用例。
      • 我相信您使用的解决方案是 Bar-2.0 与 Foo-2.0 一起运行,只是以一种迂回的方式。
      【解决方案5】:

      可以在 jar 的 mainfest 中设置 Class-Path。 http://java.sun.com/developer/Books/javaprogramming/JAR/basics/manifest.html 我不能保证它会解决问题,但值得一试。

      【讨论】:

        【解决方案6】:

        要在 Bar-2.0.jar 之前拥有 Foo-2.0.jar,请使用 Foo-2.0.jar 的内容更新 Bar-2.0.jar(覆盖已包含的 .class)并从战争中删除 Foo-2.0.jar .

        -cp A.jar:B.jar 有效果,A.jar 的内容就像是在B.jar 之上的一层。所以用 A.jar 的内容覆盖 B.jar 的内容会得到同样的效果。

        【讨论】:

          【解决方案7】:

          这有点老套,但可能会奏效。将 Foo-2.0.jar 的名称更改为按字母顺序排列在 Bar-2.0.jar 之前,例如 AFoo-2.0.jar。

          【讨论】:

            猜你喜欢
            • 2012-01-11
            • 1970-01-01
            • 2012-07-03
            • 2015-09-17
            • 2011-03-31
            • 2021-08-15
            • 2010-11-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多