【问题标题】:Why is Java not finding classes that are in the CLASSPATH?为什么 Java 找不到 CLASSPATH 中的类?
【发布时间】:2020-01-12 01:09:56
【问题描述】:

我正在尝试安装作为 .jar 安装程序分发的 Mooshak。当我运行该文件时,它给了我以下关于缺少类的错误:

ifinlay@mooshak:~$ sudo java -jar MooshakInstaller.jar -cui
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/compress/archivers/ArchiveException
    at pt.up.fc.dcc.mooshak.installer.Installer.<init>(Installer.java:26)
    at pt.up.fc.dcc.mooshak.installer.Installer.main(Installer.java:52)
    ... 5 more
Caused by: java.lang.ClassNotFoundException: org.apache.commons.compress.archivers.ArchiveException
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:436)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 7 more

所以它找不到 org/apache/commons/compress/archives/ArchiveException 类。但是我已经安装了这个库,并且在我的 CLASSPATH 中有以下内容:

ifinlay@mooshak:~$ echo $CLASSPATH
.:/usr/share/maven-repo/org/apache/commons/commons-compress/1.18/commons-compress-1.18.jar

CLASSPATH 中的这个 .jar 文件似乎确实包含有问题的类:

ifinlay@mooshak:~$ jar tvf /usr/share/maven-repo/org/apache/commons/commons-compress/1.18/commons-compress-1.18.jar

# ... other classes edited out
   722 Fri Mar 01 16:57:28 UTC 2019 org/apache/commons/compress/archivers/ArchiveException.class
# ... other classes edit out

那么,当它确实 似乎在路径中时,为什么Java 找不到这个类呢?任何帮助都会太棒了,我真的为此摸不着头脑。

感谢阅读!

编辑:.jar 的清单文件如下所示:

Manifest-Version: 1.0
Rsrc-Class-Path: ./ junit.jar org.hamcrest.core_1.3.0.v201303031735.ja
 r commons-compress-1.12.jar BrowserLauncher2-all-1_3.jar
Class-Path: .
Rsrc-Main-Class: pt.up.fc.dcc.mooshak.installer.Installer
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader

所以这似乎意味着 commons-compress-1.12.jar 文件应该放在与安装程序相同的目录中。但这似乎不起作用...

【问题讨论】:

标签: java classpath apache-commons


【解决方案1】:

为什么 Java 找不到 CLASSPATH 中的类?

简短的回答:因为它们不在实际的类路径中。

长答案:

安装程序有问题,或者您没有正确运行它/因为它被设计为运行。

当您使用-jar 选项运行这样的java 时:

java -jar MooshakInstaller.jar -cui

它将忽略 CLASSPATH 变量,您添加的任何 -cp 参数。这就解释了为什么 Java 没有在您(假定的)类路径上的 commons-compress-1.18.jar JAR 文件中找到类。

这意味着以下之一:

  1. MooshakInstaller.jar 安装程序缺少依赖项;即它坏了。 (我怀疑情况是否如此。他们会发现这一点。)
  2. MooshakInstaller.jar 安装程序并非设计为作为可执行 JAR 运行。

  3. MooshakInstaller.jar 安装程序期望在相对于 JAR 文件位置的某个位置找到依赖项。 (查看 JAR 的清单文件中是否有“类路径”属性。)

我还要注意,当你运行这个时:

sudo java -jar MooshakInstaller.jar -cui

CLASSPATH 环境变量的值可能不会传递给根进程。检查sudo 的手动条目。这不是这里的实际问题...因为CLASSPATH 变量无论如何都会被忽略,因为-jar 选项。


更新

看来您根本没有关注installation instructions

要安装 Mooshak,您必须执行以下命令。确保您的系统满足所有要求。注意你必须有root权限

% tar xzf mooshak-version.tgz     
% cd mooshak-version
% su      
# ./install

那不是你做的,我强烈怀疑你实际做的不等同于上面的。

(我不打算对此进行进一步调查,因为下载过程需要我向他们提供各种个人详细信息。绝不是何塞!)

【讨论】:

  • 非常感谢您的回复非常!我实际上正在安装具有不同安装说明的 Mooshak 版本 2。感谢 Manifest 文件的提示,我将其文本添加到原始帖子中。我似乎仍然无法让它工作......
【解决方案2】:

此答案基于您提供的新信息。它改变了一切。

首先,我所说的CLASSPATH-jar 仍然正确。

然而,事实证明 Mooshak 2 安装程序是一个使用“jar in jar”加载器的可执行 JAR。

  • 主类是org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
  • 清单指定安装程序的类路径应包含这些嵌套 JAR,它们是安装程序 JAR 的一部分:

     junit.jar 
     org.hamcrest.core_1.3.0.v201303031735.jar 
     commons-compress-1.12.jar 
     BrowserLauncher2-all-1_3.jar
    
  • JarRsrcLoader 入口点类应为上述 JAR 设置类加载器,然后启动安装程序。

而且它应该都可以正常工作。

我确实看到了一件奇怪的事情。清单中有commons-compress-1.12.jar,但您似乎正在尝试使用commons-compress-1.18.jar

你说:

所以这似乎意味着 commons-compress-1.12.jar 文件应该与安装程序放在同一目录中。

我不是这样读的,但我会看看能不能找到文档。

更新:不。我找不到文档,但从JarRsrcLoader 源代码看来,它不是那样工作的。

但我确实找到了线索。在JarRsrcLoader 的当前版本中,Java 8 和 Java 9+ 有单独的代码。因此,如果 Mooshak 2.0 安装程序使用旧版本的 JarRsrcLoader,并且您尝试使用 Java 9 或更高版本进行安装,那么它可能无法正常工作。

所以,请确保您使用 Java 8 ... 就像要求所说的那样。


但是,您显然在这里尝试做的是使用不同版本的压缩库。更好的方法是为 Mooshak 设置自己的构建树:

...查看完整源代码svn checkout https://svn.dcc.fc.up.pt/projects/Mooshak/Mooshak/

然后根据我认为树中的说明修改依赖项并构建/安装。

【讨论】:

  • 非常感谢您的帮助!切换到 Java 8 成功了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2014-06-26
  • 1970-01-01
相关资源
最近更新 更多