简体   繁体   English

Java NoClassDefFoundError 尽管设置了类路径

[英]Java NoClassDefFoundError despite set classpath

I have some trouble with getting a Java application to run in the console and/or with Ant.我在让 Java 应用程序在控制台和/或 Ant 中运行时遇到了一些麻烦。 I know that a lot of starting issues are related to the classpath being not set or incorrectly set, though I'm fairly sure I set it correctly, so my search only yielded results on that.我知道很多起始问题都与未设置或错误设置的类路径有关,尽管我相当确定我设置正确,所以我的搜索只产生了结果。

Here is the general setup of my application: classes are in packages model, view and controller.这是我的应用程序的一般设置:类位于包 model、视图和 controller 中。 controller.Controller is the class with the main method. controller.Controller是class的主要方法。 I am using objectdb as my JPA provider.我使用 objectdb 作为我的 JPA 提供程序。

I am using Ant to compile my application.我正在使用 Ant 来编译我的应用程序。

After compiling, I can run my application from ant with the following script:编译后,我可以使用以下脚本从 ant 运行我的应用程序:

<target name="run" description="default build process">
    <java fork="true" classname="${main-class}">
        <classpath>
            <path refid="classpath" />
        </classpath>
    </java>
</target>

where ${main-class} is controller.Controller and classpath consists of /lib and /dist folders (the application's jar file is compiled to /dist)其中 ${main-class} 是 controller.Controller 并且类路径由 /lib 和 /dist 文件夹组成(应用程序的 jar 文件编译为 /dist)

Now I tried copying all.jar files from /lib and /dist to one separate folder and run them with java -jar cooking.jar -cp.现在我尝试将 all.jar 文件从 /lib 和 /dist 复制到一个单独的文件夹并使用java -jar cooking.jar -cp. which results in这导致

Exception in thread "main" java.lang.NoClassDefFoundError: javax/persistence/Persistence
    at model.jpa.JPAModelFactory.<init>(JPAModelFactory.java:28)
    at model.jpa.JPAModelFactory.<init>(JPAModelFactory.java:24)
    at controller.Controller.<init>(Controller.java:59)
    at controller.Controller.main(Controller.java:116)
Caused by: java.lang.ClassNotFoundException: javax.persistence.Persistence
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 4 more

So I tried ant and slightly modified above build target to:所以我尝试了 ant 并将上面的构建目标稍微修改为:

<target name="run2" description="default build process">
    <java fork="true" jar="${dist.dir}/${ant.project.name}.jar">
        <classpath>
            <path refid="classpath" />
        </classpath>
    </java>
</target>

which results in the same error.这会导致相同的错误。 I don't understand why.我不明白为什么。

Just to test it, I tried running from the command line by specifying the main class directly: java -cp. controller.Controller只是为了测试它,我尝试通过直接指定主要 class 从命令行运行: java -cp. controller.Controller java -cp. controller.Controller which for some reason cannot even locate the class (it's there, I confirmed it): java -cp. controller.Controller由于某种原因甚至无法找到 class (它在那里,我确认了):

Exception in thread "main" java.lang.NoClassDefFoundError: controller/Controller
Caused by: java.lang.ClassNotFoundException: controller.Controller
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: controller.Controller.  Program will exit.

I have set JAVA_HOME to my JDK's path, and CLASSPATH to my JRE's/lib path.我已将 JAVA_HOME 设置为我的 JDK 路径,并将 CLASSPATH 设置为我的 JRE/lib 路径。 OS is Windows 7 64 bit, Java version is 1.6.0_25-b06操作系统为 Windows 7 64 位,Java 版本为 1.6.0_25-b06

I am puzzled by two things: a) Why is Java unable to locate controller.Controller, even though it is present in the.jar file and the.jar file is in the current directory? I am puzzled by two things: a) Why is Java unable to locate controller.Controller, even though it is present in the.jar file and the.jar file is in the current directory? b) What am I doing wrong that calling Java with -jar seems to mess up the lookup mechanisms. b)我做错了什么,用 -jar 调用 Java 似乎弄乱了查找机制。

Any help is highly appreciated.非常感谢任何帮助。

The class path should consist of class 路径应包括

  1. directories with class files (in their proper package directory)具有 class 文件的目录(在其正确的 package 目录中)
  2. jar files. jar 文件。

You cannot point the class path to a directory of jars.您不能将 class 路径指向 jars 目录。 Things are different when running a application server (eg Tomcat), which will load jars from a directory for you.运行应用程序服务器(例如 Tomcat)时情况有所不同,它将为您从目录加载 jars。

though I'm fairly sure I set it correctly虽然我很确定我设置正确

The evidence is against you.证据对你不利。 The JVM is telling you that you have not set it correctly. JVM 告诉您您没有正确设置它。

What do you think that ref 'classpath' pointing to?您认为 ref 'classpath' 指向什么? Where do you assume its values are coming from?你认为它的价值来自哪里? They should be defined inside the Ant build.xml, right?它们应该在 Ant build.xml 中定义,对吧? Like this:像这样:

<path id="production.class.path">
    <pathelement location="${production.classes}"/>
    <pathelement location="${production.resources}"/>
    <fileset dir="${production.lib}">
        <include name="**/*.jar"/>
        <exclude name="**/junit*.jar"/>
        <exclude name="**/*test*.jar"/>
    </fileset>
</path>

<path id="test.class.path">                            
    <path refid="production.class.path"/>
    <pathelement location="${test.classes}"/>
    <pathelement location="${test.resources}"/>
    <fileset dir="${test.lib}">
        <include name="**/junit*.jar"/>
        <include name="**/*test*.jar"/>
    </fileset>
</path>

If you're creating an executable JAR, you need to specify the main class and classpath in the manifest, as CoolBeans correctly pointed out in the comment.如果您正在创建可执行文件 JAR,则需要在清单中指定主 class 和类路径,正如 CoolBeans 在评论中正确指出的那样。 The 3rd party JAR locations have to be relative to the executable JAR.第 3 方 JAR 位置必须与可执行文件 JAR 相关。 You should package them with your executable JAR in such a way that the relative path is easy to sort out and understand.您应该将 package 与可执行文件 JAR 一起使用,以使相对路径易于整理和理解。

I've found this happens when I specify both the <classpath> and the jar="..." in the target.我发现当我在目标中同时指定<classpath>jar="..."时会发生这种情况。 I removed the jar="..." , placed that .jar into the <classpath> list and it ran after that.我删除了jar="..." ,将.jar放入<classpath>列表中,然后运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM