sbt-assembly - 在 jar 中找不到主要 class

sbt-assembly - can not find main class in jar

我有一个项目,我正在尝试使用 sbt-assembly 插件创建一个 fat jar。当我尝试使用 java -jar 命令从 jar 中 运行 我的主要 class 时,我收到错误消息:Error: Could not find or load main class com.gordon.timeshare.apps.TimeShareLauncher.

我的项目中只有一个main class(我使用extends App语法来实现),所以我没有明确指定main class的路径,虽然我已经尝试过了,但没有帮助。

以下是我 build.sbt 文件中的所有设置。

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"
  )

assemblyMergeStrategy in assembly := {
  case PathList("META-INF", xs @ _*) => MergeStrategy.discard
  case x => MergeStrategy.first
}

我也尝试过其他策略,例如 deduplicate,但是在尝试制作 .jar 时会出现错误。

此外,在制作 .jar 时,我收到警告:

[warn] Could not create directory C:\Users\dgord\workspace\new-timeshare\timeshare\target\streams\_global\assembly\_global\streams\assemblyfbe735ce5abc6987fbc59b072404628cdc94b4_a99f2fe2a42747ed9809d4f62f51a9e1b336dde8_da39a3ee5e6b4b0d3255bfef95601890afd80709\META-INF\versions: java.nio.file.FileAlreadyExistsException: C:\Users\dgord\workspace\new-timeshare\timeshare\target\streams\_global\assembly\_global\streams\assemblyfbe735ce5abc6987fbc59b072404628cdc94b4_a99f2fe2a42747ed9809d4f62f51a9e1b336dde8_da39a3ee5e6b4b0d3255bfef95601890afd80709\META-INF\versions

如果您想知道我的主要 class 长什么样:

package com.gordon.timeshare.apps

object TimeShareLauncher extends App

我也在 WSL 上试过,结果一样。

问题出在 lazy val app = (project in file("app"))。假设一个没有名为 app 的模块的单个模块项目,sbt-assembly 将创建一个名为 app 的目录并尝试将构建内容填充到其中。但是,由于主要 class 不在 app 包中,因此 class 不会添加到 jar 文件中。

正确的做法是:

lazy val app = (project in file(".")),指定当前目录为查找主目录class。所以这并不是真正了解如何使用 sbt-assembly 插件的问题,而是在 sbt 构建中指定项目的更普遍的问题。