Answers:
java <class-name>
命令语法首先,您需要了解使用java
(或javaw
)命令启动程序的正确方法。
常规语法1是这样的:
java [ <options> ] <class-name> [<arg> ...]
where <option>
是命令行选项(以“-”字符开头),<class-name>
是标准Java类名称,并且<arg>
是传递给应用程序的任意命令行参数。
1-在此答案的结尾附近描述了一些其他语法。
按照惯例,该类的全限定名(FQN)就像在Java源代码中一样;例如
packagename.packagename2.packagename3.ClassName
但是,该java
命令的某些版本允许您使用斜杠代替句号。例如
packagename/packagename2/packagename3/ClassName
哪个(令人困惑)看起来像文件路径名,但不是一个。请注意,术语“ 完全限定名”是标准的Java术语……不是我刚刚编造出来的,以使您感到困惑:-)
这是java
命令应显示的示例:
java -Xmx100m com.acme.example.ListUsers fred joe bert
以上将导致java
命令执行以下操作:
com.acme.example.ListUsers
该类的编译版本。main
带有签名,返回类型和修饰符的方法public static void main(String[])
。(请注意,方法参数的名称不是签名的一部分。)String[]
。当您收到消息“找不到或加载主类...”时,表明第一步已失败。该java
命令无法找到该类。事实上,在“...”的消息将是完全合格的类名是java
所期待的。
那么为什么找不到课程呢?
第一个可能的原因是您可能提供了错误的类名。(或者...正确的类名,但格式错误。)考虑以上示例,这里有多种错误的方法来指定类名:
Example#1-一个简单的类名:
java ListUser
当在诸如之类的包中声明该类时com.acme.example
,则必须在命令中使用完整的类名,包括包名java
;例如
java com.acme.example.ListUser
Example#2-文件名或路径名而不是类名:
java ListUser.class
java com/acme/example/ListUser.class
Example#3-类名的大小写不正确:
java com.acme.example.listuser
Example#4-错字
java com.acme.example.mistuser
Example#5-源文件名(Java 11或更高版本除外;请参见下文)
java ListUser.java
Example#6-您完全忘记了类名
java lots of arguments
第二个可能的原因是类名正确,但是java
命令找不到该类。要了解这一点,您需要了解“类路径”的概念。Oracle文档对此作了很好的解释:
java
命令的文档所以...如果您正确指定了类名,那么接下来要检查的是您正确指定了类路径:
java
命令时有效的CLASSPATH环境变量。检查目录名和JAR文件名是否正确。java
命令时生效的当前目录中检查它们是否正确解析...。;
在Windows和:
其他操作系统上都使用。如果为平台使用了错误的分隔符,则不会收到明确的错误消息。相反,您将在路径上获得不存在的文件或目录,而该文件或目录将被静默忽略)将目录放在类路径上时,它在概念上对应于限定名称空间的根。通过将完全限定的名称映射到pathname,类位于该根目录下的目录结构中。因此,例如,如果“ / usr / local / acme / classes”位于类路径上,则当JVM查找名为的类时com.acme.example.Foon
,它将查找具有以下路径名的“ .class”文件:
/usr/local/acme/classes/com/acme/example/Foon.class
如果您已将“ / usr / local / acme / classes / com / acme / example”放在类路径中,那么JVM将无法找到该类。
如果您的类FQN为com.acme.example.Foon
,那么JVM将在目录“ com / acme / example”中查找“ Foon.class”:
如果您的目录结构与上述模式的包命名不匹配,则JVM将找不到您的类。
如果您尝试通过移动某个类来重命名该类,则该操作也会失败...但是异常stacktrace会有所不同。可能会这样说:
Caused by: java.lang.NoClassDefFoundError: <path> (wrong name: <name>)
因为类文件中的FQN与类加载器期望找到的内容不匹配。
举一个具体的例子,假设:
com.acme.example.Foon
上课,/usr/local/acme/classes/com/acme/example/Foon.class
,/usr/local/acme/classes/com/acme/example/
,然后:
# wrong, FQN is needed
java Foon
# wrong, there is no `com/acme/example` folder in the current working directory
java com.acme.example.Foon
# wrong, similar to above
java -classpath . com.acme.example.Foon
# fine; relative classpath set
java -classpath ../../.. com.acme.example.Foon
# fine; absolute classpath set
java -classpath /usr/local/acme/classes com.acme.example.Foon
笔记:
-classpath
选项可以缩短为-cp
。检查相应的手册条目java
,javac
以此类推。类路径需要包括应用程序依赖的所有其他(非系统)类。(系统类是自动定位的,您几乎不必为此担心。)为了正确加载主类,JVM需要查找:
(注意:JLS和JVM规范允许JVM在某种程度上“延迟”加载类,这可能会在引发类加载器异常时产生影响。)
有时会发生某人将源代码文件放入其源代码树中错误的文件夹中的情况,或者他们忽略了package
声明。如果您在IDE中执行此操作,则IDE的编译器会立即告诉您有关此信息。同样,如果您使用不错的Java构建工具,则该工具javac
将以检测到问题的方式运行。但是,如果您手动构建Java代码,则可以通过这种方式进行处理,以使编译器不会注意到问题,并且生成的“ .class”文件不在您期望的位置。
有很多东西要检查,很容易错过一些东西。尝试将-Xdiag
选项添加到java
命令行(作为之后的第一件事java
)。它将输出有关类加载的各种信息,这可能会为您提供真正问题所在的线索。
另外,请考虑由网站,文档等复制和粘贴不可见或非ASCII字符引起的可能问题。考虑“象形文字”,如果两个字母或符号看起来相同……却不相同。
最后,如果您尝试从中使用不正确签名的JAR文件启动,显然可以遇到此问题(META-INF/*.SF)
。
java
使用.NET启动Java程序的语法有3种java command
。
1)用于启动“可执行” JAR文件的语法如下:
java [ <options> ] -jar <jar-file-name> [<arg> ...]
例如
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
入口点类的名称(即com.acme.example.ListUser
)和类路径在JAR文件的MANIFEST中指定。
2)从模块(Java 9和更高版本)启动应用程序的语法如下:
java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]
入口点类的名称由其<module>
自身定义,或由optional给出<mainclass>
。
3)从Java 11开始,您可以编译并运行一个源代码文件,并使用以下语法运行它:
java [ <options> ] <sourcefile> [<arg> ...]
在哪里(通常)是带有后缀“ .java”的文件。
有关更多详细信息,请参阅java
所用Java版本的命令的官方文档。
典型的Java IDE支持在IDE JVM本身或子JVM中运行Java应用程序。这些通常不受此特定异常的影响,因为IDE使用其自身的机制来构造运行时类路径,标识主类并创建java
命令行。
但是,如果您在IDE背后进行操作,则仍然有可能发生此异常。例如,如果您先前已在Eclipse中为Java应用程序设置了Application Launcher,然后在不通知Eclipse的情况下将包含“ main”类的JAR文件移动到了文件系统中的其他位置,则Eclipse会无意间启动JVM。具有不正确的类路径。
简而言之,如果您在IDE中遇到此问题,请检查IDE的状态是否过旧,项目引用损坏或启动器配置损坏。
IDE可能也很容易混淆。IDE是非常复杂的软件,包含许多交互部分。这些部分中的许多部分都采用了各种缓存策略,以使IDE整体具有响应能力。这些有时可能会出错,并且一种可能的症状是启动应用程序时出现问题。如果您怀疑这可能发生,那么值得尝试其他事情,例如重新启动IDE,重建项目等等。
java -cp ../third-party-library.jar com.my.package.MyClass
; 这不起作用,而是有必要将本地文件夹也添加到类路径中(由分隔:
,例如:java -cp ../third-party-library.jar:. com.my.package.MyClass
,那么它应该起作用
java
并不表示它没有找到一个导入的类,而是主类你想运行。尽管我确信这是有原因的,但这会产生误导。我遇到的情况java
是确切知道我的课在哪里,但是找不到导入的课之一。它没有这么说,而是抱怨找不到我的主要班级。真的很烦
如果您的源代码名称是HelloWorld.java,则编译后的代码将是HelloWorld.class
。
如果使用以下命令调用它将收到该错误:
java HelloWorld.class
而是使用以下命令:
java HelloWorld
javac TestCode.java
随后java TestCode
java -classpath . HelloWorld
如果您的类在软件包中,则必须转到cd
项目的根目录并使用该类的完全限定名称(packageName.MainClassName)运行。
例:
我的课在这里:
D:\project\com\cse\
我的主要班级的全名是:
com.cse.Main
所以我cd
回到根项目目录:
D:\project
然后发出java
命令:
java com.cse.Main
该答案是为了挽救新手Java程序员,避免他们因常见错误而感到沮丧,建议您阅读已接受的答案,以获取有关Java类路径的更深入的知识。
如果您在中定义了主类和主方法package
,则应使用类的全名(packageName.MainClassName
)在层次目录上运行它。
假设有一个源代码文件(Main.java):
package com.test;
public class Main {
public static void main(String[] args) {
System.out.println("salam 2nya\n");
}
}
要运行此代码,您应该将其放置Main.Class
在目录目录中./com/test/Main.Java
。并在根目录中使用java com.test.Main
。
当相同的代码在一台PC上运行但在另一台PC上显示错误时,我发现的最佳解决方案是按以下方式进行编译:
javac HelloWorld.java
java -cp . HelloWorld
javac -classpath . HelloWorld.java
会奏效的!在您的情况下,这是一个更好的解决方案。
帮助我的是在命令行上指定类路径,例如:
新建一个文件夹, C:\temp
在中创建文件Temp.java C:\temp
,其中包含以下类:
public class Temp {
public static void main(String args[]) {
System.out.println(args[0]);
}
}
在folder中打开命令行C:\temp
,并编写以下命令来编译Temp类:
javac Temp.java
运行已编译的Java类,添加-classpath
选项以让JRE知道在哪里可以找到该类:
java -classpath C:\temp Temp Hello!
java
不看$ CLASSPATH(因为你用-classpath或罐子)或2)类路径的设置并没有在这方面并非环境设置生效,该情况下java
是跑; 例如,因为您没有“提供”在正确的shell中添加setenv命令的文件。
根据错误消息(“找不到或加载主类”),问题分为两类:
主类不能被发现时有错字或错误的语法完全限定类名,或者没有在所提供的类路径中存在。
当无法启动类时,无法加载主类,通常,主类扩展了另一个类,并且该类在提供的类路径中不存在。
例如:
public class YourMain extends org.apache.camel.spring.Main
如果不包括骆驼弹簧,将报告此错误。
extends
)。我刚刚了解到硬盘的方式,当主类无法加载,因为它扩展了另一个不能被发现,JAVA 不报告其实际的类未找到(不同NoClassDefFoundError
)。所以是的,的确发生了,当您不知道这一点时,这就是令人毛骨悚然的情况。
使用以下命令:
java -cp . [PACKAGE.]CLASSNAME
示例:如果您的类名是从Hello.java创建的Hello.class,则使用以下命令:
java -cp . Hello
如果您的文件Hello.java位于com.demo软件包中,请使用以下命令
java -cp . com.demo.Hello
在JDK 8中,很多情况下都发生了类文件存在于同一文件夹中的情况,但是java
命令期望使用类路径,因此,我们添加-cp .
了当前文件夹作为类路径的引用。
-cp .
则没有必要,因为如果$CLASSPATH
未设置,.
则为默认类路径。
echo %CLASSPATH%
输出什么?)不,因为我没有Windows PC,所以无法检查。
有时,可能导致问题的原因与主类无关,而我不得不艰难地找到答案。这是我搬迁的参考图书馆,它给了我:
找不到或加载主类xxx Linux
我只是删除了该引用,将其再次添加,然后再次正常工作。
我遇到了同样的问题,最后发现了我的错误:)我使用了此命令进行编译,并且可以正常工作:
javac -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode.java
但是此命令对我不起作用(我找不到或加载主类qrcode
):
java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode
最后,我只是在类路径的末尾添加了':'字符,问题得以解决:
java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar:" qrcode
这里的所有答案似乎都是针对Windows用户的。对于Mac,classpath分隔符是:
,不是;
。由于设置类路径使用时;
未引发设置错误,因此如果从Windows到Mac,则很难发现。
这是相应的Mac命令:
java -classpath ".:./lib/*" com.test.MyClass
在此示例中,程序包所在的位置com.test
以及lib
类路径中还将包含一个文件夹。
/*
有必要?
我花了很多时间来解决这个问题。我以为我在某种程度上错误地设置了我的类路径,但是问题是我输入了:
java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool
代替:
java -cp C:/java/MyClasses utilities/myapp/Cool
我认为完全限定的含义是包括完整的路径名而不是完整的包名。
utilities.myapp.Cool
或其包名(如果有)的形式给出。
首先使用此命令设置路径;
set path="paste the set path address"
然后,您需要加载程序。在存储的驱动器中键入“ cd(文件夹名称)”并进行编译。例如,如果我的程序存储在D驱动器上,则键入“ D:”,然后按Enter键并键入“ cd(文件夹名称)”。
if "cd" helps then it by luck rather than by judgement
。这是错误的(我相信),因为java .
默认使用当前目录作为类路径的一部分。
在Windows上.;
,将CLASSPATH值放在开头。
的。(点)表示“在当前目录中查找”。这是一个永久的解决方案。
您也可以使用set将它设置为“一次” CLASSPATH=%CLASSPATH%;.
。只要您的cmd窗口处于打开状态,此操作就会持续。
您确实需要从src
文件夹中执行此操作。在此处键入以下命令行:
[name of the package].[Class Name] [arguments]
假设您的类称为CommandLine.class
,代码如下所示:
package com.tutorialspoint.java;
/**
* Created by mda21185 on 15-6-2016.
*/
public class CommandLine {
public static void main(String args[]){
for(int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " + args[i]);
}
}
}
然后,您应该cd
转到src文件夹,并且需要运行的命令如下所示:
java com.tutorialspoint.java.CommandLine this is a command line 200 -100
命令行上的输出将是:
args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100
cd
进入src
然后运行java ../bin com.blah.blah.MyClass
对我有用的命令。因此,感谢您的提示!
在Java中,当您有时使用java可执行文件从命令行运行JVM并尝试从具有公共静态void main(PSVM)的类文件启动程序时,即使将classpath参数设置为JVM是准确的,并且类文件位于类路径中:
Error: main class not found or loaded
如果无法加载带有PSVM的类文件,则会发生这种情况。一个可能的原因是该类可能正在实现接口或扩展不在类路径上的另一个类。通常,如果某个类不在类路径中,则抛出的错误将指示错误。但是,如果扩展或实现了正在使用的类,则java无法加载该类本身。
参考:https : //www.computingnotes.net/java/error-main-class-not-found-or-loaded/
在测试Java MongoDB JDBC连接时,我也遇到类似的错误。我认为最好总结一下我的最终解决方案,这样将来任何人都可以直接查看这两个命令,并且可以继续进行下去。
假设您位于Java文件和外部依赖项(JAR文件)所在的目录中。
编译:
javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
跑:
java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
JavaMongoDBConnection
没有包,并且2)您不更改目录。至少可以说,它是脆弱的。通过不解释问题,它将导致新手在这种方法行不通的情况下尝试这种方法。简而言之,它鼓励“伏都教编程技术”:en.wikipedia.org/wiki/Voodoo_programming
好的,已经有很多答案了,但是没有人提到文件权限可能是罪魁祸首的情况。
运行时,用户可能无权访问JAR文件或路径的目录之一。例如,考虑:
Jar文件中 /dir1/dir2/dir3/myjar.jar
拥有JAR文件的User1可以执行以下操作:
# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar
但这仍然行不通:
# Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs" MyProgram
Error: Could not find or load main class MyProgram
这是因为正在运行的用户(User2)无权访问dir1,dir2或javalibs或dir3。当User1可以看到文件并可以访问文件时,这可能会使某人发疯,但是User2仍然会发生错误。
执行mvn eclipse:eclipse
此操作后出现此错误,这使我的.classpath
文件有些混乱。
不得不改变线路.classpath
从
<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
至
<classpathentry kind="src" path="src/main/java" output="target/classes" />
<classpathentry kind="src" path="src/main/resources" excluding="**" output="target/classes" />