前言
一些从事java开发的开发人员,从一开始就用集成开发环境,像eclipse
、IDEA
等优秀的IDE,很少再用java
、javac
这样的命令了,但是有时候就需要我们直接用JDK提供的java
命令来运行class文件,但是最常遇到的一个问题就是**“错误: 找不到或无法加载主类 XXXXX”**,但是用IDE却没有任何问题。
百度上一查,太多的文章提供解决方案了,无外乎都是环境变量的配置,尤其是CLASSPATH
,这是当然,但是还是不能解决该怎么办?
网上有许多的解决方案,也都是轻描淡写,泛泛而谈
我们来分析下可能会出现的问题:
分析
- 首先检查环境变量,尤其是
CLASSPATH
的配置是否正确,如下图:
java命令是通过CLASSPATH
来寻找编译后的class文件的,这个问题很好解决,基本上网上的每篇文章都有说到,但是需要注意的是,记得在CLASSPATH
环境变量中加上.
,即指支持在当前目录寻找class文件,例如:
1 | JAVA_HOME=/Users/Steven/Library/Java/JavaVirtualMachines/azul-1.8.0_252/Contents/Home |
-
理解
CLASSPATH
是怎么寻找class文件的举一个目录结构略微复杂的例子看一下 ⬇️(该例子是使用
FileInputStream
读取文件中的字节并打印出来)1、上面的例子是直接在idea中创建了一个类文件
TestFileInputStream
,网上许多人都说是package
包的问题,那我们先把这个package
删除了试试(即类文件不指定package
)使用命令行进入到该类文件所在的目录,然后编译、运行
是没有任何问题,难道说就是包名的问题?但是编译的时候带着
package
太正常了,总不能把package
删除了编译运行吧,先试试加上package
运行的结果吧1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30package com.shifpeng.scaffold.test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestFileInputStream {
public static void main(String[] args) {
int b = 0;
FileInputStream in = null;
try {
in = new FileInputStream("/Users/Steven/GitRepositories/scaffold/src/main/java/com/shifpeng/scaffold/test/TestFileInputStream.java");
} catch (FileNotFoundException e) {
System.out.printf("找不到指定文件");
}
try {
long num = 0;
while ((b = in.read()) != -1) {
System.out.printf((char) b + "");
num++;
}
in.close();
System.out.printf("一共读到了" + num + "个字节");
} catch (IOException e) {
e.printStackTrace();
System.out.printf("文件读取失败");
}
}
}然后编译运行,发现报错:
错误: 找不到或无法加载主类 TestFileInputStream
1
2
3
4➜ test git:(develop) ✗ javac TestFileInputStream.java
➜ test git:(develop) ✗ java TestFileInputStream
错误: 找不到或无法加载主类 TestFileInputStream
➜ test git:(develop) ✗按照java规定,我们应该按照
package
定义的路径来存放源文件,该类应该放在src/main/java/com/shifpeng/scaffold/test/
,而我们刚刚就是在这个路径下执行的,有问题再来~
一个类的完整的包名应该是什么呢,包名+类名,那是不是在编译的时候指定一下包名就可以了,试试
1
2
3➜ test git:(develop) ✗ javac TestFileInputStream.java
➜ test git:(develop) ✗ java com.shifpeng.scaffold.test.TestFileInputStream
错误: 找不到或无法加载主类 com.shifpeng.scaffold.test.TestFileInputStream还是不对,猜想会不会还是路径的问题,因为我们是在
/Users/Steven/GitRepositories/scaffold/src/main/java/com/shifpeng/scaffold/test
下执行的,再加上com.shifpeng.scaffold.test.TestFileInputStream
,是不是路径重复了呀再来~
按照上面的猜想,我们移步
/Users/Steven/GitRepositories/scaffold/src/main/java/
果然成功了:
1 | ➜ test git:(develop) ✗ cd /Users/Steven/GitRepositories/scaffold/src/main/java/ |
结论
java
命令在执行class文件的时候是根据CLASSPATH
指定的目录寻找的,不是一般理解的当前目录,如果需要支持在当前目录中寻找,需要在CLASSPATH
环境变量的配置中加入.;
;- java执行class文件对package的路径是强依赖的,它在执行的时候会严格以当前用户路径为基础,按照package指定的包路径转化为文件路径去搜索class文件
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !