自从我上次完成Java以来已经太久了,我不记得为什么会发生以下情况:
鉴于此文件由标准Maven项目创建,如下所示:Maven Tutorial
package com.mycompany.app;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
编译它,即使使用Maven但使用标准的javac可执行文件,也会生成一个没有错误的类文件。尝试运行类文件,您会收到此错误:
Exception in thread "main" java.lang.NoClassDefFoundError: App (wrong name: com/mycompany/app/App)
删除package命令,再次编译,运行正常。为什么是这样?我正在运行JDK 1.6.0_21顺便提一下。
答案 0 :(得分:8)
在为类创建package之后,您必须做的一件事是创建嵌套子目录来表示类的包层次结构。在您的情况下,包名称为“com.mycompany.app”,因此App.class
(已编译的App.java文件)应驻留在“com / mycompany / app”子目录中。尽管源文件驻留在哪里并不重要。例如,我复制了您的文件并执行了以下操作:
$ ls
App.java
$ javac App.java
$ ls
App.class App.java
$ mkdir -p com/mycompany/app
$ mv App.class com/mycompany/app/
$ java com.mycompany.app.App
Hello World!
$
请阅读Wikipedia page about Java Packages了解详情。您还可以查看以下链接:
祝你好运!答案 1 :(得分:0)
这是因为在Java文件系统文件中映射到类(例如,每个公共类必须在一个单独的同名文件中),并且包映射到目录。
因此,如果您有一个com.mycompany.app包中的类,那么它必须位于相对于类路径的com / mycompany / app目录中。
在你的情况下你应该有一个输出目录,比如你应该在/com/mycompany/app/App.java中有这个类。然后构建它,运行javac并将com / mycompany / app / App.java作为参数,而不是com / mycompany / app / App.java。
运行类以类似的方式工作,但是您给出了类的完全限定名,而不是目录路径。
答案 2 :(得分:0)
当您尝试执行程序时,它将使用程序包中指定的路径查找类文件。因此,当您在文件中包含package语句时,您的类文件必须位于com/mycompany/app/
目录中(相对于您尝试从中运行它的目录);如果它找不到它,你会得到那个例外。
因此,当您删除该package语句时,JVM将在当前目录中查找它,这就是它工作的原因(因为您在java App
所在的同一目录中执行App.java
并且存在App.class
个文件。)
答案 3 :(得分:0)
您需要将com / mycompany / app文件夹添加到Java CLASSPATH。如果我记得很清楚,你也可以使用参数“-cp”从cmdline中完成。