在多项目SBT构建中,如何在SBT-assembly中明确地压缩mainClass属性?
我进行了广泛的搜索,但似乎无法找到如何防止在多项目构建中由sbt-assembly构建的jar中设置主类。
在单项目构建中,只要至少有两个类可能被命令行调用,这似乎就可以工作:
import sbt._
import Keys._
import sbtassembly.Plugin._
import sbtassembly.AssemblyUtils._
import AssemblyKeys._
object TestBuild extends Build {
lazy val buildSettings = Defaults.defaultSettings ++ assemblySettings ++ Seq(
version := "0.1-SNAPSHOT",
organization := "com.organization",
scalaVersion := "2.10.2",
mergeStrategy in assembly := mergeFirst
)
lazy val root = Project(id = "test-assembly",
base = file("."),
settings = buildSettings) settings(
mainClass in assembly := None
)
lazy val mergeFirst: String => MergeStrategy = {
case "reference.conf" | "rootdoc.txt" => MergeStrategy.concat
case PathList("META-INF", xs @ _*) =>
(xs map {_.toLowerCase}) match {
case ("manifest.mf" :: Nil) | ("index.list" :: Nil) | ("dependencies" :: Nil) =>
MergeStrategy.discard
case ps @ (x :: xs) if ps.last.endsWith(".sf") || ps.last.endsWith(".dsa") =>
MergeStrategy.discard
case "plexus" :: xs =>
MergeStrategy.discard
case "services" :: xs =>
MergeStrategy.filterDistinctLines
case ("spring.schemas" :: Nil) | ("spring.handlers" :: Nil) =>
MergeStrategy.filterDistinctLines
case _ => MergeStrategy.first
}
case _ => MergeStrategy.first
}
}
但是,似乎甚至不需要mainClass := None
。事实上,即使它留在那里,如果只有一个候选类,仍然会在清单中设置一个主类。
不幸的是,在多项目构建中,即使将其他类作为虚拟入口点,也无法阻止设置主类。
经过大量的摆弄后,我发现通过在多个范围内独立设置mainClass
到None
,我可以阻止设置主类。特别是,这可以解决问题:
mainClass in assembly := None
mainClass in packageBin := None
nainClass in Compile := None
mainClass in run := None
我无法在文档中找到此要求,也无法弄清楚为什么这是必要的。设置mainClass in (Compile, run) := None
不起作用。他们确实需要单独确定范围。
这是手动压制主类的正确方法还是我错过了什么?如果不是错误,我认为应该在某处记录,特别是考虑到单项目和多项目构建之间的行为不一致。
答案 0 :(得分:4)
Main-Class
以及jar中的所有其他属性最终由packageOptions in assembly
确定,因此您可以从中删除Package.MainClass
,如下所示:
lazy val root = Project(id = "test-assembly",
base = file("."),
settings = buildSettings) settings(
packageOptions in assembly ~= { os => os filterNot {_.isInstanceOf[Package.MainClass]} }
)
这也适用于多项目构建。
注意:sbt-assembly根据源输入的元数据缓存输出jar,因此测试assembly
周围的设置需要通过调用clean
来清除缓存。