新 Java 开发人员遇到的一个常见问题是他们的程序无法运行并显示错误消息: Could not find or load main class ...
这是什么意思,是什么原因造成的,你应该如何解决它?
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
那么为什么它可能找不到类呢?
第一个可能的原因是您可能提供了错误的类名。(或者......正确的类名,但格式错误。)考虑到上面的例子,这里有多种错误的方式来指定类名:
示例 #1 - 一个简单的类名:
java ListUser
当类在包中声明时,例如com.acme.example
,您必须使用完整的类名,包括命令中的包名java
;例如
java com.acme.example.ListUser
示例 #2 - 文件名或路径名而不是类名:
java ListUser.class
java com/acme/example/ListUser.class
Example #3 - 一个大小写不正确的类名:
java com.acme.example.listuser
示例 #4 - 一个错字
java com.acme.example.mistuser
示例 #5 - 源文件名(Java 11 或更高版本除外;见下文)
java ListUser.java
Example #6 - 你完全忘记了类名
java lots of arguments
第二个可能的原因是类名正确,但是java
命令找不到类。要理解这一点,您需要了解“类路径”的概念。Oracle 文档很好地解释了这一点:
java
文档所以......如果您正确指定了类名,接下来要检查的是您是否正确指定了类路径:
java
命令时生效的 CLASSPATH 环境变量。检查目录名和 JAR 文件名是否正确。java
命令时有效的当前目录。;
在 Windows 和:
其他平台上。如果您为您的平台使用了错误的分隔符,您将不会收到明确的错误消息。相反,您将在路径上获得一个不存在的文件或目录,该文件或目录将被静默忽略.)当您将目录放在类路径上时,它理论上对应于限定名称空间的根目录。通过将完全限定名映射到路径名,类位于该根目录下的目录结构中。例如,如果“/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 将找不到您的类。
如果您尝试通过移动它来重命名一个类,那也会失败......但异常堆栈跟踪会有所不同。很容易说这样的话:
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 字符可能导致的问题。并考虑“同形文字”,其中两个字母或符号看起来相同......但不是。
如果您的签名无效或不正确,您可能会遇到此问题META-INF/*.SF
。您可以尝试在您最喜欢的 ZIP 编辑器中打开 .jar,然后从中删除文件,META-INF
直到您拥有.jar 文件为止MANIFEST.MF
。但是,一般不建议这样做。(无效签名可能是由于有人将恶意软件注入到原始签名的 JAR 文件中。如果您删除了无效签名,您就是在用恶意软件感染您的应用程序!)推荐的方法是获取具有有效的 JAR 文件签名,或从(真实的)原始源代码重建它们。
最后,如果MANIFEST.MF
文件中存在语法错误,您显然会遇到此问题(请参阅https://stackoverflow.com/a/67145190/139985)。
java
使用java command
.
用于启动“可执行”JAR 文件的语法如下:
java [ <options> ] -jar <jar-file-name> [<arg> ...]
例如
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
入口点类的名称(即com.acme.example.ListUser
)和类路径在 JAR 文件的 MANIFEST 中指定。
从模块(Java 9 及更高版本)启动应用程序的语法如下:
java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]
入口点类的名称要么由它<module>
自己定义,要么由可选的 给定<mainclass>
。
从 Java 11 开始,您可以使用该java
命令使用以下语法编译和运行单个源代码文件:
java [ <options> ] <sourcefile> [<arg> ...]
where<sourcefile>
是(通常)带有后缀“.java”的文件。
有关更多详细信息,请参阅java
您正在使用的 Java 版本的命令的官方文档。
典型的 Java IDE 支持在 IDE JVM 本身或子 JVM 中运行 Java 应用程序。这些通常不受此特定异常的影响,因为 IDE 使用自己的机制来构建运行时类路径、识别主类并创建java
命令行。
但是,如果您在 IDE 后面执行操作,则仍有可能发生此异常。例如,如果您之前在 Eclipse 中为您的 Java 应用程序设置了一个 Application Launcher,然后您将包含“main”类的 JAR 文件移动到文件系统中的不同位置而没有告诉 Eclipse,Eclipse 会在不知不觉中启动 JVM使用不正确的类路径。
简而言之,如果您在 IDE 中遇到此问题,请检查过时的 IDE 状态、损坏的项目引用或损坏的启动器配置等。
IDE 也可能会简单地感到困惑。IDE 是非常复杂的软件,包含许多交互部分。其中许多部分采用各种缓存策略,以使 IDE 作为一个整体响应。这些有时会出错,一个可能的症状是启动应用程序时出现问题。如果您怀疑这可能会发生,那么值得尝试其他方法,例如重新启动 IDE、重建项目等等。
如果您的源代码名称是 HelloWorld.java,那么您的编译代码将为HelloWorld.class
.
如果您使用以下方法调用它,您将收到该错误:
java HelloWorld.class
相反,使用这个:
java 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
其放在类似目录的包中:
C:\Users\workspace\testapp\com\test\Main.Java
然后将终端的当前目录更改为项目的根目录:
cd C:\Users\workspace\testapp
最后,运行代码:
java com.test.Main
如果您的源代码名称上没有任何包,则可能是您输入了错误的命令。假设你的 Java 文件名为Main.java
,编译后:
javac Main.java
您的编译代码将是Main.class
如果您使用以下方法调用它,您将收到该错误:
java Main.class
相反,使用这个:
java Main
当相同的代码在一台 PC 上运行,但在另一台 PC 上显示错误时,我发现的最佳解决方案是编译如下:
javac HelloWorld.java
java -cp . HelloWorld
在命令行上指定类路径对我有帮助。例如:
新建一个文件夹,C:\temp
在 中创建文件 Temp.java C:\temp
,其中包含以下类:
public class Temp {
public static void main(String args[]) {
System.out.println(args[0]);
}
}
在文件夹中打开命令行C:\temp
,编写以下命令编译 Temp 类:
javac Temp.java
运行编译后的 Java 类,添加-classpath
让 JRE 知道在哪里可以找到该类的选项:
java -classpath C:\temp Temp Hello!
根据报错信息(“Could not find or load main class”),有两类问题:
当完全限定的类名中存在拼写错误或语法错误或在提供的类路径中不存在时,找不到Main 类。
无法启动主类时无法加载主类。通常主类扩展另一个类,并且该类不存在于提供的类路径中。
例如:
public class YourMain extends org.apache.camel.spring.Main
如果不包含camel-spring,会报这个错误。
使用这个命令:
java -cp . [PACKAGE.]CLASSNAME
示例:如果您的类名是从 Hello.java 创建的 Hello.class,则使用以下命令:
java -cp . Hello
如果您的文件 Hello.java 在包 com.demo 中,则使用以下命令
java -cp . com.demo.Hello
在 JDK 8 中,类文件经常出现在同一个文件夹中,但该java
命令需要类路径,因此我们添加-cp .
以当前文件夹作为类路径的参考。
尝试-Xdiag。
Steve C 的回答很好地涵盖了可能的情况,但有时要确定是否找不到或加载类可能并不那么容易。使用java -Xdiag
(从 JDK 7 开始)。这会打印出一个很好的堆栈跟踪,它提供了消息Could not find or load main class
消息含义的提示。
例如,它可以将您指向无法找到的主类使用的其他类,并阻止加载主类。
在这种情况下,我遇到了这样的错误:
java -cp lib.jar com.mypackage.Main
它适用;
于 Windows 和:
Unix:
java -cp lib.jar; com.mypackage.Main
有时可能导致问题的原因与主要课程无关,我不得不以艰难的方式找出这一点。这是我移动的一个引用库,它给了我:
无法找到或加载主类 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
在这种情况下,您有:
无法找到或加载主类?classpath
这是因为您使用的是“-classpath”,但破折号java
与命令提示符上使用的破折号不同。我在从记事本复制和粘贴到 cmd 时遇到了这个问题。
就我而言,出现错误是因为我提供了源文件名而不是类名。
我们需要向解释器提供包含 main 方法的类名。
如果您的情况特别像我的情况,这可能会对您有所帮助:作为初学者,我在尝试运行 Java 程序时也遇到了这个问题。
我是这样编译的:
javac HelloWorld.java
我也尝试使用相同的扩展名运行:
java Helloworld.java
当我删除.java
并重写命令java HelloWorld
时,程序运行完美。:)
如果使用Maven构建 JAR 文件,请确保在 pom.xml 文件中指定主类:
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>class name us.com.test.abc.MyMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
这里的所有答案似乎都是针对 Windows 用户的。对于 Mac,类路径分隔符是:
,而不是;
。由于没有抛出设置类路径的错误,因此;
如果从 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
我认为完全限定的意思是包含完整的路径名而不是完整的包名。
在 Windows 上.;
,将 CLASSPATH 值放在开头。
这 。(点)表示“查看当前目录”。这是一个永久的解决方案。
您也可以使用 set 将其设置为“一次” CLASSPATH=%CLASSPATH%;.
。只要您的 cmd 窗口打开,这将持续。
在我的情况下解决问题的是:
右键单击要运行的项目/类,然后Run As → Run Configurations。然后,您应该通过以下方式修复现有配置或添加新配置:
打开Classpath选项卡,单击Advanced...按钮,然后添加项目的bin
文件夹。
首先使用该命令设置路径;
set path="paste the set path address"
然后你需要加载程序。在存储的驱动器中键入“cd(文件夹名称)”并编译它。例如,如果我的程序存储在 D 盘,输入“D:”按回车并输入“cd(文件夹名称)”。
在 Java 中,当您有时使用 Java 解释器可执行文件从命令行运行 JVM 并尝试使用public static void main
(PSVM) 从类文件启动程序时,即使 JVM 的类路径参数是,您也可能会遇到以下错误准确并且类文件存在于类路径中:
错误:找不到或未加载主类
如果无法加载带有 PSVM 的类文件,则会发生这种情况。一个可能的原因是该类可能正在实现一个接口或扩展另一个不在类路径上的类。通常,如果一个类不在类路径上,则抛出的错误表明如此。但是,如果正在使用的类被扩展或实现,Java 就无法加载该类本身。
参考:https ://www.computingnotes.net/java/error-main-class-not-found-or-loaded/
您确实需要从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
java
使用 Windows PowerShell 中宣传的选项运行时,-cp
您可能会收到类似于以下内容的错误:
The term `ClassName` is not recognized as the name of a cmdlet, function, script ...
为了让 PowerShell 接受命令,-cp
选项的参数必须包含在引号中,如下所示:
java -cp 'someDependency.jar;.' ClassName
以这种方式形成命令应该允许 Java 正确处理类路径参数。
在测试 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
好吧,已经有很多答案了,但是没有人提到文件权限可能是罪魁祸首的情况。
运行时,用户可能无法访问 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。当用户 1 可以看到文件并且可以访问它们时,它可能会让某人发疯,但是用户 2 仍然会发生错误。
做完后我得到了这个错误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" />
我无法使用此处所述的解决方案解决此问题(尽管所述答案无疑清除了我的概念)。我两次遇到这个问题,每次我都尝试了不同的解决方案(在 Eclipse IDE 中)。
main
方法。main
因此,我从后续课程中删除了该方法。有时,在您可能尝试过的一些在线编译器中,如果您不编写public class [Classname]
而只是class [Classname]
.
就我而言,我收到错误是因为我在 Windows 7 系统上混合了大写和小写的包名称。将包名称更改为全部小写解决了该问题。另请注意,在这种情况下,将 .java 文件编译为 .class 文件时没有错误;它只是不会从同一个(sub-sub-sub-)目录运行。
我有一个奇怪的:
错误:无法找到或加载主类 mypackage.App
原来我在我的项目文件中编码了对POM (父级)的引用(我的项目指向一个父级)并且它是关闭/错误的。pom.xml
pom.xml
pom.xml
relativePath
以下是我项目pom.xml
文件的一部分:
<parent>
<groupId>myGroupId</groupId>
<artifactId>pom-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../badPathHere/pom.xml</relativePath>
</parent>
一旦我解决了 POM relativePath,错误就消失了。
去搞清楚。
这是另一个让我花费了一些时间的问题:命令行类路径参数的行为与您预期的不同。我在 MacOS 上直接调用 CLI,并且在调用中包含了两个 jar。
例如,这两个都使工具混淆了主类的名称:
这是因为星号导致它错误地解析 args:
java -cp path/to/jars/* com.mypackage.Main
而这个是因为——我不知道为什么:
java -cp "*.jar" com.mypackage.Main
这有效:
java -cp "path/to/jars/*" com.mypackage.Main
明确列出这两个罐子也有效:
java -cp path/to/jars/jar1.jar:path/to/jars/jar2.jar com.mypackage.Main
在搜索了 2 天后,我找到了这个解决方案并且它有效。这很奇怪,但它对我有用。
package javaapplication3;
public class JavaApplication3 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
System.out.println("Hello");
}
}
这是我要运行的程序,位于 C:\Java Projects\JavaApplication3\src\javaapplication3
现在在这个位置打开 cmd 并使用这个命令编译程序
javac JavaApplication3.java
编译后向下导航一个目录,即 C:\Java Projects\JavaApplication3\src
现在运行以下命令来执行程序
java javaapplication3.JavaApplication3
场景:使用命令提示符(Windows 中的CMD )编译和运行一个简单的 'java' 程序,它只有 ' Main.java ' 文件,并带有指定的 ' package main '。
源文件路径:
一些项目名称文件夹\src\main\Main.java
目标文件夹:
一些项目名称文件夹\dest
目标文件路径(文件夹 '\main' 和文件 '\Main.class' 将由 'javac' 生成):
一些项目名称文件夹\dest\main\Main.class
Main.java如下:
package main;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
编译:
// 'javac' compiler will produce 'Main.class' in the 'dest\main' folder.
// 'main' folder is created because in the source file(in our case: 'Main.java') is
// specified 'package main'.
javac -d ./dest ./src/main/Main.java
运行编译文件(在我们的例子中:'Main.class'):
// '-cp'(is the same as '-classpath')
// './dest'(means destination folder, where resides compiled 'Main.class').
// 'main.Main'(means 'package' 'main', which contains class 'Main'('Main.class'))
// WARNING: when run 'java' class, MUST NOT type extension '.class'
// after 'class name
// (in our case: 'main.Main'(<package>.<class-name>) WITHOUT extension
// '.class').
java -cp ./dest main.Main
// Hello world
我升了一级。所以,现在HelloWorld.class文件位于hello\HelloWorld.class中,我运行了以下命令。其中cp是类路径,.
表示仅检查当前目录。
java -cp . hello.HelloWorld
输出
Hello world!
默认情况下,Java 使用.
当前工作目录作为默认CLASSPATH
. 这意味着当您在提示符处键入命令时,例如java MyClass
,该命令被解释为好像您有 type java -cp . MyClass
。你看到-cp
和之间的那个点了MyClass
吗?(cp是较长类路径选项的缩写)
这对于大多数情况来说已经足够了,而且在您尝试将目录添加到您的CLASSPATH
. 在大多数情况下,当程序员需要这样做时,他们只需运行类似set CLASSPATH=path\to\some\dir
. 此命令创建一个名为CLASSPATH
具有值的新环境变量,path\to\some\dir
或者将其值替换为path\to\some\dir
ifCLASSPATH
之前已设置。
完成后,您现在有了一个CLASSPATH
环境变量,Java 不再使用其默认类路径 ( .
),而是使用您设置的类路径。所以第二天你打开你的编辑器,写一些java程序,cd
到你保存它的目录,编译它,然后尝试用命令运行它java MyClass
,你会看到一个很好的输出:找不到或加载主类...(如果您的命令之前运行良好,而您现在得到了此输出,那么您可能就是这种情况)。
发生的情况是,当您运行命令时java MyClass
,Java 会搜索MyClass
您在您的而不是当前工作目录中设置的一个或多个目录中命名的类文件,CLASSPATH
因此它不会在那里找到您的类文件,因此会抱怨。
您需要做的是.
再次添加到您的类路径,这可以使用命令完成set CLASSPATH=%CLASSPATH%;.
(注意分号后面的点)。CLASSPATH
用简单的英语,这个命令说“选择( )的最初值%CLASSPATH%
,添加.
到它 ( ;.
) 并将结果分配回CLASSPATH
”。
瞧,你又可以java MyClass
像往常一样使用你的命令了。
在阅读了所有答案后,我注意到大多数对我不起作用。所以我做了一些研究,这就是我得到的。仅在步骤 1 不起作用时尝试此操作。
打开转到C:\Program Files (x86)\Java或C:\Program Files\Java
jdk
文件夹,然后打开文件bin
夹。ii. 复制路径并将其添加到环境变量中。确保用分号分隔变量,;
. 例如,“ C:\Yargato\bin;C:\java\bin; ”。如果你不这样做,它会导致更多的错误。
iii. 转到jre
文件夹并打开其bin
文件夹。
iv. 在这里搜索rt.jar 文件。我的是:
C:\Program Files (x86)\Java\jre1.8.0_73\lib\rt.jar 复制并在环境变量下并搜索类路径变量并将其粘贴到那里。
我在 IntelliJ 中创建的演示程序遇到了这个问题。
有两个关键点可以解决:
我的演示程序:
package io.rlx.tij.c2;
public class Ex10 {
public static void main(String[] args) {
// do something
}
}
源码路径:
../projectRoot/src/main/java/io/rlx/tij/c2/Ex10.java
java
目录:cd ../projectRoot/src/main/java
javac ./io/rlx/tij/c2/Ex10.java
java io.rlx.tij.c2.Ex10
如果我在其中运行程序../projectRoot/src/main/java/io/rlx/tij/c2
或在没有包名的情况下运行它,我将收到此错误:Error: Could not find or load main class
.
修复它的最简单方法是在此处重新下载Maven Apache:https ://maven.apache.org/download.cgi
比你再次设置你的路径:
将路径放在您设置 Apache Maven 文件夹的位置,例如:C:\Program Files\apache-maven-3.8.4\bin
重新启动终端或 IDE,它应该可以工作。
它总是对我有用。
好像当我遇到这个问题时,它是独一无二的。
一旦我删除了文件顶部的包声明,它就完美地工作了。
除了这样做之外,似乎没有任何方法可以在我的机器上运行简单的 HelloWorld.java,无论编译发生在哪个文件夹、CLASSPATH 或 PATH、参数或从中调用的文件夹。
右键单击该项目。
src
为“来源”这对我有用。
另一个让我摸不着头脑的场景是:
package com.me
Public class Awesome extends AwesomeLibObject {
....
public static void main(String[] argv) {
System.out.println("YESS0");
}
}
AwesomeLibObject 是在外部库中定义的类。我得到了同样令人困惑的错误消息:
Error: Could not find or load main class com.Awesome
解决方法很简单:外部库也必须在类路径中!
原因 #2 - 应用程序的类路径指定不正确。阅读之前链接的三个文档。(是的......阅读它们!重要的是,Java 程序员至少了解 Java 类路径机制如何工作的基础知识。)我想将此文档添加到上面的这篇非常好的帖子中。
JDK 工具和实用程序 一般信息(文件结构、类路径、如何找到类、更改) 增强功能(JDK 7 中的增强功能) 标准 JDK 工具和实用程序
https://docs.oracle.com/javase/7/docs/technotes/tools/index.html
https://docs.oracle.com/javase/7/docs/technotes/tools/findingclasses.html
https://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html
Java Launcher 如何查找类 了解类路径和包名
https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html
Java 中的类加载器 Java 类加载器是 Java 运行时环境的一部分,它将 Java 类动态加载到 Java 虚拟机中。由于类加载器,Java 运行时系统不需要了解文件和文件系统。
Java 类不会一次全部加载到内存中,而是在应用程序需要时加载。此时,JRE 调用 Java ClassLoader,这些 ClassLoader 将类动态加载到内存中。
https://en.wikipedia.org/wiki/Java_Classloader
https://www.geeksforgeeks.org/classloader-in-java/
这就是我解决问题的方法。
我注意到如果您在编译中包含 jar 文件,将当前目录 (./) 添加到类路径会有所帮助。
javac -cp "abc.jar;efg.jar" MyClass.java
java -cp "abc.jar;efg.jar" MyClass
对比
javac -cp "**./**;abc.jar;efg.jar" MyClass.java<br>
java -cp "**./**;abc.jar;efg.jar" MyClass
这基本上意味着没有静态main(String[] args)
方法。它应该自动解决它。如果不是,则在制作程序(它没有 main 方法)或打包程序时(不正确的清单信息)时出现了问题。
这有效
public class Hello {
public static void main(String[] args) {
System.out.println("Hello");
}
}
这不起作用
public class Hello {
public Hello() {
System.out.println("Hello");
}
}
如果你的包名是javatpoint并且包名是com.javatpoint并且类名是AnotherOne,那么像这样编译你的类:
cd C:\Users\JAY GURUDEV\eclipse-workspace\javatpoint\src\com\javatpoint
javac AnotherOne.java
并使用运行这个类
cd C:\Users\JAY GURUDEV\eclipse-workspace\javatpoint\src
java com.javatpoint.AnotherOne
(这里应该排除包名。)
对于数据库连接,我得到了这个。我刚刚在类路径中添加了以下内容:
export CLASSPATH=<path>/db2jcc4.jar:**./**
在这里,我最后附加了./以便在加载时也能识别我的类。
现在只需运行:
java ConnectionExample <args>
它工作得很好。
关于外部库的回答 -
编译:
javac -cp ./<external lib jar>: <program-name>.java
执行:
java -cp ./<external lib jar>: <program-name>
上述方案在 OS X 和 Linux 系统中运行良好。注意:
类路径中的 。
排除以下文件解决了该问题。
元信息/*.SF
META-INF/*.DSA
元信息/*.RSA
在中添加以下代码build.gradle
jar {
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
{
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
manifest {
attributes(
'Main-Class': 'mainclass'
)
}
}