【问题标题】:How does java choose a .JAR library versionjava如何选择.JAR库版本
【发布时间】:2023-03-08 11:48:01
【问题描述】:

由于各种历史原因,我有一个旧的 java 应用程序,它与其他一些应用程序共享库 .JAR 的本地 lib/ 目录。在这个目录中是同一个库的多个版本副本,例如:

... log4j-1.2.16.jar log4j-1.2.17.jar slf4j-api-1.7.5.jar slf4j-api-1.7.21.jar slf4j-log4j12-1.7.5.jar slf4j-log4j12-1.7.9.jar ...

当我的 java 应用程序启动时,它如何决定加载哪个 .jar 文件?据我所知,CLASSPATH 只是设置为./lib/。但它使用 Tanuki 服务包装器启动,所以我不能 100% 确定这一点。

我无法删除这些现有 .JAR 中的任何一个,有没有办法准确指定我的应用将使用哪些 .JAR?

修补这个旧应用程序后,现在我收到 NoClassDefFoundError,我怀疑该应用程序正在加载与另一个库(BoneCP 和 slf4j)冲突的旧(或新)版本的 .JAR。

【问题讨论】:

  • 在类路径中有不同版本的相同库总是不好的。要么只使用一个版本,然后您可以轻松删除另一个版本,或者同时使用两者(因为它们不包含完全相同的类),但您几乎肯定会遇到冲突,因为一个版本使用另一个库中的公共类。跨度>

标签: java


【解决方案1】:

当 JVM 类加载器正在寻找一个类时,哪个 jar 在类路径中首先被拾取。因此,您可以尝试以不同的顺序添加这些 jar,以检查哪个 jar 破坏了您的应用程序

【讨论】:

    【解决方案2】:

    如果您要像这样共享 lib 目录,那么每个应用程序都需要在类路径中列出它显式使用的 JAR 文件。如果您使用通配符类路径条目(例如“lib/*”),则未指定将使用哪些版本的 JAR。 manual entry 声明:

    类路径通配符

    类路径条目可以包含基本名称通配符 (),这被认为等同于指定目录中所有文件的列表,扩展名为 .jar 或 .JAR。例如,类路径条目 mydir/ 指定名为 mydir 的目录中的所有 JAR 文件。由 * 组成的类路径条目展开为当前目录中所有 jar 文件的列表。无论文件是否隐藏(名称以“.”开头)都会被考虑。

    ....

    目录中 JAR 文件的枚举顺序 未指定扩展的类路径,并且可能因平台而异 平台,甚至时不时地在同一台机器上。一个 结构良好的应用程序不应依赖于任何特定的 命令。 如果需要特定的订单,那么 JAR 文件可以 在类路径中显式枚举。

    【讨论】:

    • 感谢 Stephen,这正是解决方案 - java -cp lib/jarfile1.jar;lib/jarfile2.jar; 等等。我必须为 11 个 jar 库执行此操作。
    • 我猜....你也可以用符号链接来做。为每个应用程序创建一个“lib”目录,并使用指向相应 JAR 版本的符号链接填充它。但是通过包装脚本显式命名类路径中的 JAR 更加健壮,
    猜你喜欢
    • 2015-09-25
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 2018-08-07
    相关资源
    最近更新 更多