【问题标题】:Java Jar and Classpath problemsJava Jar 和 Classpath 问题
【发布时间】:2011-12-07 03:49:39
【问题描述】:

我遇到了一个我无法理解的奇怪问题...我有一个简单的 HelloWorld jar,它是在 Eclipse 中构建的,它的类路径上有 Apache Loggings jar。我已经编写了一个脚本来运行 jar:

#!/bin/sh
export CLASSPATH=lib/*:$CLASSPATH
java -jar HelloWorld.jar 

这里的目录结构是一个带有HelloWorld.jar 的主目录和一个带有commons-logging-1.1.1.jarlib 子目录。

运行此脚本工作正常。但是,当我将HelloWorld.jar 放入lib 目录(即在一个地方包含所有JAR)并执行java -jar lib/HelloWorld.jar 时,我得到:

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory

错误。为什么?!?!?!?!

我问这个是因为我在 OSX 上使用 JarBundler 为 HelloWorld 应用程序创建了一个应用程序包,并将修改后的脚本放在 MacOS 目录中,而所有库都放在 Resources/Java 目录中。修改后的脚本版本为:

#!/bin/sh
RESOURCE_DIR=$(cd "../Resources"; pwd)
export CLASSPATH=$RESOURCE_DIR/Java/*:$CLASSPATH
java -jar $RESOURCE_DIR/Java/HelloWorld.jar 

我遇到了与上述相同的错误,非常感谢任何帮助理解为什么我不能这样做和/或如何解决它?

【问题讨论】:

    标签: java macos scripting jar


    【解决方案1】:

    使用 MANIFEST 文件(META-INF 文件夹)来处理 Classpath 条目。使用库的相对路径。

    欲了解更多信息,请查看here

    基本上,对于在 lib 文件夹中使用 commons-logging 的情况:

    Class-Path: lib/commons-logging-1.1.1.jar
    

    对于同一文件夹中的两个罐子:

    Class-Path: commons-logging-1.1.1.jar
    

    【讨论】:

      【解决方案2】:

      您是否已将 log4j.jar 设置到您的班级中。我认为您没有将 log4j.jar 添加到其类路径中。

      【讨论】:

        【解决方案3】:

        尝试将commons-logging-1.1.1.jar直接添加到CLASSPATH中

        【讨论】:

        • 我已经尝试过了,(请参阅我对@Sarel Botha 的评论)但它仍然没有奏效。
        • 是的,我想是 -jar 造成的......我认为@Jagat 解决方案应该可以工作。
        【解决方案4】:

        Java 不能与 lib/* 一起使用,但 shell 可能会为您扩展它。仔细检查一下。导出后放这样一行:

        echo $CLASSPATH
        

        另外,我建议将它放在前面提到的 MANIFEST 文件中。

        编辑: 是权限问题吗?如果您以 root/admin 身份运行应用程序或将文件放在其他位置并使用完全限定的路径,它可以工作吗?

        【讨论】:

        • echo $CLASSPATH 产生 /Users/sonogenics/Documents/workspace/HelloWorld/lib/commons-logging-1.1.1.jar: 这是我期望的位置,但我仍然收到错误...
        • 以 sudo 身份运行脚本仍然不能解决问题。我要疯了!但感谢您的意见!
        • 我认为 Jagat 有正确的答案。当您使用 -jar 时,我知道它会忽略 -classpath。它可能也忽略了 $CLASSPATH。
        【解决方案5】:

        类路径不适用于通配符。每个 jar 都必须明确指定,或者作为 CLASSPATH 变量的一部分,或者在包含在类路径中的另一个 jar 的清单中。

        此外,IIRC java -jar 会忽略类路径中存在的所有第三方 jar。为什么不这样做呢?

        java -cp yourJar:logJars <mainClass>
        

        【讨论】:

          【解决方案6】:

          感谢大家帮助解决这个问题。基本上,在我不知情的情况下,正在创建一个清单文件并将其捆绑到 jar 中,因此任何 $CLASSPATH-cp 标志都被忽略了。在我的 Eclipse 项目中,我将类路径设置为 $(projectRoot)/lib,这恰好与我的 dist 目录相同。但是,当它们被 OSX 的 JarBundler 捆绑到一个目录中时,该目录不再存在,因此类路径错误!

          我尝试从 Eclispe 创建的 MANIFEST.MF 中删除 Class-Path 属性,但命令行 $CLASSPATH 和/或 -cp 条目似乎仍然没有区别...清单文件否定所有命令行类路径条目?

          【讨论】:

          • 我不是在问题中提问的好习惯。请从现在开始提出新问题或使用相关信息更新您的问题。至于你的回答java -jar 将忽略外部类路径设置(它与 MANIFEST 类路径的存在无关)。您可以使用@Jagat -cp 解决方案自己管理类路径......但是,我不能强调没有理由重新发明井,只需在您的 MANIFEST 文件中正确设置您的类路径或让 JarBundler 为你。 Ant task.
          • 更具体地说,我说的是jarfilesetjarfileset 选项。不要使用 extraclasspath* 选项来包含 commons-logging。
          猜你喜欢
          • 2018-03-25
          • 2015-07-24
          • 2016-06-26
          • 1970-01-01
          • 2018-01-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-11
          相关资源
          最近更新 更多