如何用java -jar或java -cp运行SBT打包Jar?遇NoClassDefFoundError求助
解决Scala程序执行时的NoClassDefFoundError问题
针对你遇到的问题,我来一步步拆解原因并给出解决方案:
常见原因及排查步骤
1. Scala库版本不匹配
你的项目是基于Scala 2.11编译的,所以你使用的scala-library.jar必须是2.11.x系列的版本(比如scala-library-2.11.12.jar)。如果用了2.12或其他版本的scala-library,版本不兼容会直接导致找不到类。
你可以通过以下方式确认:
- 查看项目
build.sbt里的scalaVersion配置,确保和你使用的scala-library版本一致; - 用
jar xf scala-library.jar解压后,查看META-INF/MANIFEST.MF里的Specification-Version字段,确认版本是否匹配。
2. 类路径配置错误
- 系统分隔符差异:如果是Windows系统,类路径的分隔符是
;而不是:,你需要把命令改成:
Linux/macOS则用java -cp "scala-library.jar;myproject_2.11-0.1.jar" Main 3/4:,但要确保两个jar文件都在当前执行命令的目录下,或者用绝对路径指定它们的位置(比如/home/user/libs/scala-library.jar)。 - 检查jar内的Main类:用
jar tf myproject_2.11-0.1.jar命令查看jar包内容,确认根目录下存在Main.class文件(因为你没有包结构,类应该直接在根目录)。如果找不到这个文件,说明编译或打包过程有问题,需要重新用SBT编译打包。
3. Main方法签名错误
确保你的Main对象的main方法签名完全正确,必须是:
object Main { def main(args: Array[String]): Unit = { // 你的业务逻辑 } }
如果参数类型不对(比如写成List[String])或者返回值不是Unit,JVM会识别不到主类,也会抛出类似的错误。
更省心的解决方案:打包成Fat Jar
手动维护类路径很容易出错,推荐用SBT的assembly插件打包成包含所有依赖的Fat Jar,这样执行时不用指定类路径:
- 在项目的
project/plugins.sbt文件中添加插件依赖:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0") // 适配SBT 1.x和Scala 2.11
- 回到项目根目录,执行命令:
sbt assembly
- 打包完成后,在
target/scala-2.11目录下会生成一个类似myproject-assembly-0.1.jar的文件,直接执行即可:
java -jar target/scala-2.11/myproject-assembly-0.1.jar 3/4
内容的提问来源于stack exchange,提问作者Geo84
相关产品推荐
相关产品推荐

