Scala打包Jar用java -jar运行失败:主类找不到的排查咨询
排查Scala Assembly Jar主类找不到问题(java -jar失败但解压后运行正常)
可能的根因
- Manifest文件格式异常:Main-Class行存在多余空格、制表符,或行尾缺少换行符,导致JVM无法正确解析主类名。
- Jar包内主类路径与Manifest类名不匹配:虽然解压后运行正常,但Jar打包时可能存在大小写不一致(Java类名大小写敏感)或目录结构异常。
- sbt-assembly插件配置错误:合并策略不当导致主类文件被覆盖、遗漏,或插件版本与Scala版本不兼容。
- Jar包完整性问题:打包过程中Jar文件损坏,导致JVM无法读取主类。
排查步骤
1. 验证Jar内主类路径正确性
执行命令查看Jar内的文件结构:
jar tf TSUOrchestrationLogic-assembly.jar
确认输出中存在com/mycompany/tsu/orchestration/WeeklyTSUOrchestrator.class,且路径、类名大小写与Manifest中的Main-Class完全一致。
2. 检查Manifest文件格式
提取Manifest内容并检查格式:
unzip -p TSUOrchestrationLogic-assembly.jar META-INF/MANIFEST.MF
- 确认
Main-Class: com.mycompany.tsu.orchestration.WeeklyTSUOrchestrator行无多余空格、制表符或特殊字符。 - 确保Manifest的每一行(包括最后一行)都以换行符结尾,否则JVM会截断该行内容。
3. 检查sbt-assembly配置
打开build.sbt,确认以下内容:
- 正确引入sbt-assembly插件,版本与Scala版本兼容(比如Scala 2.13对应sbt-assembly 0.15.0+)。
- 检查
assemblyMergeStrategy配置,确保主类的.class文件未被排除或错误合并。例如:
assemblyMergeStrategy in assembly := { case PathList("com", "mycompany", "tsu", "orchestration", "WeeklyTSUOrchestrator.class") => MergeStrategy.first case x => val oldStrategy = (assemblyMergeStrategy in assembly).value oldStrategy(x) }
- 确认
mainClass设置正确(如果显式配置的话):
mainClass in assembly := Some("com.mycompany.tsu.orchestration.WeeklyTSUOrchestrator")
4. 验证Jar包完整性
执行命令检查Jar文件是否损坏:
jar -tvf TSUOrchestrationLogic-assembly.jar
如果命令执行报错或输出异常,说明Jar文件损坏,需重新打包。
5. 测试手动指定主类运行Jar
尝试跳过Manifest,直接在命令行指定主类运行Jar:
java -cp ./TSUOrchestrationLogic-assembly.jar com.mycompany.tsu.orchestration.WeeklyTSUOrchestrator
如果该命令能正常运行,说明问题确实出在Manifest文件的格式或配置上;如果同样报错,说明Jar内的主类存在依赖缺失(但解压后运行正常的话,这种情况概率较低)。
内容的提问来源于stack exchange,提问作者Happy
相关产品推荐
相关产品推荐

