Java NoClassDefFoundError尽管设置了classpath

时间:2011-05-28 20:35:48

标签: java classpath noclassdeffounderror

我在使用控制台和/或Ant运行Java应用程序时遇到了一些麻烦。 我知道很多启动问题与类路径没有设置或设置不正确有关,虽然我很确定我设置正确,所以我的搜索只产生了结果。

以下是我的应用程序的一般设置: 类在包模型,视图和控制器中。 controller.Controller是主方法的类。我使用objectdb作为我的JPA提供程序。

我正在使用Ant来编译我的应用程序。

编译完成后,我可以使用以下脚本从ant运行我的应用程序:

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

其中$ {main-class}是controller.Controller和classpath由/ lib和/ dist文件夹组成(应用程序的jar文件被编译为/ dist)

现在我尝试将/ lib和/ dist中的所有.jar文件复制到一个单独的文件夹中并使用java -jar cooking.jar -cp .运行它们,结果

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

所以我尝试了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>

导致相同的错误。我不明白为什么。

为了测试它,我尝试直接指定主类从命令行运行:java -cp . controller.Controller由于某种原因甚至找不到类(它在那里,我确认了):

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.

我已将JAVA_HOME设置为JDK的路径,将CLASSPATH设置为JRE的/ lib路径。 操作系统是Windows 7 64位,Java版本是1.6.0_25-b06

我对两件事情感到困惑: a)为什么Java无法找到controller.Controller,即使它存在于.jar文件中,而.jar文件也在当前目录中? b)使用-jar调用Java似乎搞乱了查找机制,我做错了什么。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:2)

类路径应包含

  1. 具有类文件的目录(在其正确的包目录中)
  2. jar文件。
  3. 您无法将类路径指向jar目录。运行应用程序服务器(例如Tomcat)时会有所不同,它会从目录中为您加载jar。

答案 1 :(得分:1)

  

虽然我很确定我设置正确

证据不利于你。 JVM告诉您没有正确设置它。

你认为ref'classpath'指向什么?你认为它的价值来自哪里?它们应该在Ant build.xml中定义,对吧?像这样:

<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>

如果您正在创建可执行JAR,则需要在清单中指定主类和类路径,正如CoolBeans在注释中正确指出的那样。第三方JAR位置必须与可执行JAR相关。您应该将它们与可执行JAR打包在一起,使得相对路径易于理清和理解。

答案 2 :(得分:0)

当我在目标中指定两者 <classpath>jar="..."时,我发现会发生这种情况。我删除了jar="...",将.jar放入<classpath>列表,之后就运行了。