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
- sbt:1.4.7(也试过 1.5.5)
- sbt-assembly: 1.1.0
- scala 2.13.5
我也在 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 构建中指定项目的更普遍的问题。
我有一个项目,我正在尝试使用 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
- sbt:1.4.7(也试过 1.5.5)
- sbt-assembly: 1.1.0
- scala 2.13.5
我也在 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 构建中指定项目的更普遍的问题。