Java:简单 JAR 项目在运行时无法在第二个简单 JAR 项目中找到导入的类,即使第二个 JAR 通过 -classpath 传递

发布于 2024-11-13 15:49:03 字数 1611 浏览 1 评论 0原文

我编写了两个简单的 Java 类(其中一个包含“main()”,另一个由“main()”调用)。

类#1(包含“main()”):

package daniel347x.outerjar;
import daniel347x.innerjar.Funky;
public class App 
{
    public static void main( String[] args )
    {
        Funky.foo();
    }
}

类#2(由“main()”调用):

package daniel347x.innerjar;
public class Funky 
{
    public static void foo()
    {
        System.out.println( "Funky!" );
    }
}

以上类出现在不同的项目根文件夹中,并使用Maven作为构建系统(每个项目都有自己的POM) 。主项目的 pom.xml 文件包含将 daniel347x.outerjar.App 添加为主类的正确条目,并且它正确包含对 daniel347x.innerjar 的依赖项。这两个项目都成功构建为 JAR 文件。

我使用 NetBeans 将它们包装为 Maven 项目(事实上,我使用 NetBeans 创建这两个项目)。当我从 NetBeans 中运行主项目时,它成功运行,并且我看到 Funky! 作为输出。

但是,当我尝试直接从 Windows 命令行 (cmd.exe) 运行主类时,在命令行的类路径上传递包含 Funky 的 JAR 文件,如下所示:

java -classpath “P:\_Dan\work\JavaProjects\JarFuckup\innerjar\target\innerjar-1.0-SNAPSHOT.jar”-jar “P:\_Dan\work\JavaProjects\JarFuckup\outerjar\target\outerjar-1.0-SNAPSHOT.jar”

...我收到可怕的 NoClassDefFoundError

Exception in thread "main" java.lang.NoClassDefFoundError: daniel347x/innerjar/Funky
    at daniel347x.outerjar.App.main(App.java:7)

我已经仔细确认,在上面提到的包含 Funky 的 innerjar JAR 文件中,路径结构为daniel347x\innerjar 并且 innerjar 文件夹内的是 Funky.class 文件 - 该文件在十六进制编辑器中看起来是正确的,我可以在其中看到代表类名称的 ASCII 字符串。

找不到类的事实违背了我对 Java 的理解,我认为 Java 允许您将 JAR 文件作为 -classpath 参数传递,并且它将能够在这些 JAR 文件中找到类。

这个非常基本的观点让我感到困惑 - 如果答案能解释我做错了什么,我将不胜感激。

I have written two simple Java classes (one of them containing "main()", and the other called by "main()").

Class #1 (containing "main()"):

package daniel347x.outerjar;
import daniel347x.innerjar.Funky;
public class App 
{
    public static void main( String[] args )
    {
        Funky.foo();
    }
}

Class #2 (called by "main()"):

package daniel347x.innerjar;
public class Funky 
{
    public static void foo()
    {
        System.out.println( "Funky!" );
    }
}

The above classes appear in different project root folders, and use Maven as the build system (each project has its own POM). The pom.xml file for the main project includes the proper entry to add daniel347x.outerjar.App as the main class, and it properly includes the dependency on daniel347x.innerjar. Both projects build successfully into JAR files.

I use NetBeans to wrap these as Maven projects (in fact, I used NetBeans to create both projects). When I run the main project from within NetBeans, it runs successfully and I see Funky! as the output.

However, when I attempt to run the main class straight from the Windows command line (cmd.exe), passing the JAR file containing Funky on the command line's classpath, as such:

java -classpath "P:\_Dan\work\JavaProjects\JarFuckup\innerjar\target\innerjar-1.0-SNAPSHOT.jar" -jar "P:\_Dan\work\JavaProjects\JarFuckup\outerjar\target\outerjar-1.0-SNAPSHOT.jar"

... I receive the dreaded NoClassDefFoundError:

Exception in thread "main" java.lang.NoClassDefFoundError: daniel347x/innerjar/Funky
    at daniel347x.outerjar.App.main(App.java:7)

I have carefully confirmed that, inside the innerjar JAR file noted above containing Funky, that the path structure is daniel347x\innerjar and that inside the innerjar folder is the Funky.class file - and this file looks correct within a HEX editor where I can see the ASCII strings representing the name of the class.

The fact that the class can't be found defies my understanding of Java, which I thought allows you to pass JAR files as a -classpath parameter and it will be able to find classes inside those JAR files.

This very basic point has me flummoxed - an answer that explains what I am doing wrong would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

水水月牙 2024-11-20 15:49:03

使用 -jar 选项时,类路径将被忽略。运行应用程序的一种方法是 java -classpath "P:\_Dan\work\JavaProjects\JarFuckup\innerjar\target\innerjar-1.0-SNAPSHOT.jar";"P:\_Dan\work\JavaProjects\JarFuckup \outerjar\target\outerjar-1.0-SNAPSHOT.jar" daniel347x.outerjar.App

The classpath is ignored when using the -jar option. A way to run your app would be java -classpath "P:\_Dan\work\JavaProjects\JarFuckup\innerjar\target\innerjar-1.0-SNAPSHOT.jar";"P:\_Dan\work\JavaProjects\JarFuckup\outerjar\target\outerjar-1.0-SNAPSHOT.jar" daniel347x.outerjar.App

眼睛会笑 2024-11-20 15:49:03

也许更好的方法是将 manifest 文件添加到通过相对路径指定依赖 Jars 的 类路径 的 Jar 。那么..

java -jar "P:\_Dan\...\outerjar-1.0-SNAPSHOT.jar"

..应该这样做。

双击主 Jar 也会启动它。这对于 GUI 最有用。

Perhaps a better approach would be to add a manifest file to the Jar that specifies the class path of the dependent Jars by relative paths. Then..

java -jar "P:\_Dan\...\outerjar-1.0-SNAPSHOT.jar"

..should do it.

Double clicking the main Jar will also launch it. That is mostly useful for GUIs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文