You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SBT可运行Scala项目,但直接调用Jar报ClassNotFoundException

问题根源 & 解决方案

嗨,这个问题我之前也碰到过,本质就是SBT默认打包的Jar和scala命令的类路径逻辑不匹配:

为什么sbt run能正常工作?

当你执行sbt run时,SBT在背后悄悄做了很多事:它会自动收集项目的所有依赖(比如你用到的scala-graph库),把这些依赖的Jar都加入到运行时的类路径里,所以JVM能找到scalax.collection.GraphBase$InnerNode这个依赖类,程序自然能顺利跑起来。

为什么直接用scala命令跑Jar会报错?

SBT默认用sbt package生成的Jar是个瘦Jar(thin jar)——它只包含你自己写的代码,完全不打包任何第三方依赖的代码。当你直接用scala target/scala-2.12/coloring_2.12-0.1.jar运行时,JVM的类路径里只有你自己的Jar,找不到scala-graph库的类,所以就抛出ClassNotFoundException了。

关于你提到的“过去类似项目能直接运行”

大概率是这两种情况之一:

  • 过去的项目没有用到任何第三方依赖,或者依赖刚好在你的系统全局类路径里;
  • 过去的项目可能无意中配置了能生成包含依赖的“胖Jar”的插件,或者你手动指定了依赖的类路径。

除了sbt-assembly,你还有这些解决方案:

1. 手动指定类路径运行

你可以用scala命令的-cp参数,把你的Jar和依赖Jar都加到类路径里。依赖Jar可以在~/.ivy2/cache/org.scala-graph/graph-core_2.12目录下找到,然后运行:

scala -cp "target/scala-2.12/coloring_2.12-0.1.jar:/path/to/graph-core_2.12-1.12.5.jar" Main

不过这种方式在依赖多的时候会很繁琐。

2. 用SBT生成带依赖的可执行包

你可以用sbt-native-packager插件来生成包含所有依赖的可执行包,修改build.sbt:

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.9.16")
enablePlugins(JavaAppPackaging)

然后执行sbt universal:packageZipTarball,会在target/universal目录下生成一个压缩包,解压后里面有现成的运行脚本,直接就能跑。

3. 直接用SBT的runMain命令

如果你不需要分发Jar,只是本地运行,完全可以跳过打包,直接用:

sbt "runMain Main"

效果和sbt run一样,SBT会自动处理依赖类路径。


内容的提问来源于stack exchange,提问作者Logister

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:02:36