Java命令行无法加载JAR指定主类,求排查解决方法
咱们一步步拆解你遇到的问题,大概率是这几个细节没处理对:
1. 类路径通配符的Shell展开问题
在Linux/macOS系统下,直接写lib/*时,Shell会先把这个通配符展开成当前lib目录下的所有文件,而非把lib/*传递给Java去解析。如果lib目录下的JAR文件名包含特殊字符(比如空格),或者Shell展开结果不符合预期,就会导致类路径不正确。
解决办法:把整个类路径用双引号括起来,让Java自己处理通配符:
java -cp "TestNGExamples-0.0.1-SNAPSHOT.jar:lib/*" com.test.integration.TestMain
2. 混淆了JAR内部的lib目录和外部lib目录
你提到“JAR中确实存在lib文件夹”——这里要注意:Java的类路径无法直接引用JAR文件内部的目录或文件!如果是把lib文件夹打包进了TestNGExamples-0.0.1-SNAPSHOT.jar里面,那lib/*这种写法完全无效,Java找不到这些内部的依赖JAR。
正确做法:把lib目录放在TestNGExamples-0.0.1-SNAPSHOT.jar的同级目录下(和JAR文件在同一个文件夹里),这样lib/*才能指向外部的依赖JAR。
3. 验证主类的全限定名是否正确
虽然你确认主类存在,但咱们可以用命令再验证一遍,避免包名或类名的大小写错误:
jar tf TestNGExamples-0.0.1-SNAPSHOT.jar | grep TestMain
如果输出里能看到com/test/integration/TestMain.class,说明全限定名是对的;如果看不到,那可能是包名写错了,或者类没被正确打包进JAR。
4. 注意系统的类路径分隔符
如果你是在Windows系统下运行,类路径的分隔符应该用分号;而不是冒号:,比如:
java -cp "TestNGExamples-0.0.1-SNAPSHOT.jar;lib/*" com.test.integration.TestMain
另外补充一点:当你使用-cp参数时,MANIFEST.MF里的Class-Path属性会被忽略,所以必须把所有依赖都包含在-cp的路径里,这也是为什么你需要显式指定lib/*的原因。
内容的提问来源于stack exchange,提问作者azhar

