如何为sbt Native Packager Universal插件指定唯一主类?
问题描述
项目的build.sbt配置如下:
addCommandAlias("package", "dist") lazy val actual = (project in file(".")) .enablePlugins(UniversalPlugin, JavaServerAppPackaging) .settings( name := "DeployerPod", mainClass := Some("com.myself.executable.Runner"), Compile / mainClass := Some("com.myself.executable.Runner"), Compile / run / mainClass := Some("com.myself.utils.Pipeline"), Universal / mainClass := Some("com.myself.executable.Runner"), Universal / compile / mainClass := Some("com.myself.executable.Runner"), )
通过CI/CD执行Dockerfile时,其中一步执行sbt run调用com.myself.utils.Pipeline完成流水线前置操作;最后一步执行sbt package(实际对应sbt dist命令),但解压生成的ZIP包的bin目录中出现两个对应不同主类的BAT文件,仅需保留Runner类的BAT文件。尝试执行sbt package -main com.myself.executable.Runner失败,报错Not a valid command: -。
请问如何为Universal插件指定主类?
解决方案
1. 修改build.sbt配置
问题核心是sbt-native-packager会自动扫描项目中所有含main方法的类并生成对应启动脚本,即便指定了Universal / mainClass也会保留多份脚本。要只保留Runner类的BAT文件,需添加配置限制主类扫描范围:
addCommandAlias("package", "dist") lazy val actual = (project in file(".")) .enablePlugins(UniversalPlugin, JavaServerAppPackaging) .settings( name := "DeployerPod", mainClass := Some("com.myself.executable.Runner"), Compile / mainClass := Some("com.myself.executable.Runner"), // 保留sbt run的主类配置,不影响前置操作 Compile / run / mainClass := Some("com.myself.utils.Pipeline"), Universal / mainClass := Some("com.myself.executable.Runner"), // 关键配置:仅识别指定主类,避免生成多余脚本 Compile / discoveredMainClasses := Seq("com.myself.executable.Runner") )
2. 配置说明
Compile / discoveredMainClasses:强制指定编译阶段仅识别目标主类,让native-packager不再为Pipeline类生成额外启动脚本。- 原有
sbt run的配置不受影响,依然可以正常调用Pipeline完成前置操作。
3. 验证结果
修改配置后执行sbt package(即sbt dist),解压生成的ZIP包,bin目录下只会存在对应com.myself.executable.Runner的BAT文件。
内容的提问来源于stack exchange,提问作者Sparker0i
相关产品推荐
相关产品推荐

