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

sbt-assembly构建fat jar运行提示找不到主类该如何解决?

问题解决步骤

核心根因:当前合并策略将所有META-INF目录下的文件全部丢弃,其中包含了记录主类信息的MANIFEST.MF文件,导致java -jar命令无法识别jar包的主类配置,这是报错的核心原因。

步骤1:修正assembly合并策略

替换当前的全局assemblyMergeStrategy配置,不要全量丢弃META-INF下的所有文件,仅过滤冲突的签名、索引文件即可,同时建议将合并策略放到子项目的settings配置中,避免作用范围错误:

ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / organization := "com.gordon.timeshare.apps"
ThisBuild / scalaVersion := "2.13.5"

lazy val app = (project in file("app"))
  .settings(
    assembly / mainClass := Some("com.gordon.timeshare.apps.TimeShareLauncher"),
    assembly / assemblyJarName := "TimeShareLauncher.jar",
    assembly / assemblyMergeStrategy := {
      // 保留sbt自动生成的MANIFEST.MF,仅丢弃META-INF下冲突的签名、校验文件
      case PathList("META-INF", xs @ _*) if xs.exists(f => f.endsWith(".SF") || f.endsWith(".DSA") || f.endsWith(".RSA") || f == "INDEX.LIST") => MergeStrategy.discard
      case x => MergeStrategy.first
    }
  )

步骤2:清理缓存重新构建

执行sbt clean assembly命令重新构建,构建前关闭占用项目target目录的进程(如IDE、文件资源管理器),解决构建时的目录已存在警告。

步骤3:验证jar包内容

构建完成后执行以下命令验证主类是否存在:
jar tf TimeShareLauncher.jar | grep TimeShareLauncher
如果输出com/gordon/timeshare/apps/TimeShareLauncher.class则说明主类已正常打入jar包。

再执行命令验证MANIFEST.MF是否包含主类配置:
jar xf TimeShareLauncher.jar META-INF/MANIFEST.MF && cat META-INF/MANIFEST.MF
确认文件中存在Main-Class: com.gordon.timeshare.apps.TimeShareLauncher配置项。

步骤4(可选):替换主类实现方式

如果上述操作后仍存在问题,可将extends App的实现替换为显式声明main方法,避免App trait的延迟加载特性导致类加载异常:

package com.gordon.timeshare.apps

object TimeShareLauncher {
  def main(args: Array[String]): Unit = {
    // 原启动逻辑写在这里
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:45:10