我正在使用sbt打包我的项目。但是,基于相同的源,我的项目中有两个主要类。我想为这两个主要类创建两个具有不同分类器的罐子。由于这两个主要类共享项目中的大多数源代码,因此我无法将它们分成两个项目。因此,任何人都可以帮我修改build.sbt来实现这样的目标吗?
提前致谢!
答案 0 :(得分:0)
TL; DR:您需要做的就是在mainClass
中定义sbt
。
现在让我们来描述如何做。
从根本上讲,我们需要创建sbt.build
。它的内容将是:
lazy val root = project.settings(
version := "0.0.1-SNAPSHOT",
scalaVersion := "2.12.12"
).aggregate(moduleA, moduleB)
lazy val commons = project
lazy val moduleA = project.settings(mainClass in (Compile, packageBin) := Some("MainClassA")).dependsOn(commons)
lazy val moduleB = project.settings(mainClass in (Compile, packageBin) := Some("MainClassB")).dependsOn(commons)
您可以阅读有关sbt aggregation和How to specify a main method/class to run的更多信息。 该项目的结构如下:
/
|-build.sbt
|-project
|-plugins.sbt
|-commons
|-src
|-main
|scala
|-SomeClass.scala
|-moduleA
|-src
|-main
|-scala
|-MainClassA.scala
|-moduleB
|-src
|-main
|-scala
|-MainClassB.scala
SomeClass.scala
的内容是:
object SomeClass {
def doPrint() = {
println("I am in commons")
}
}
MainClassA.scala
的内容为(假设scala版本最高为2.12。在scala 2.13中,您无需扩展App annymore。):
object MainClassA extends App {
override def main(args: Array[String]): Unit = {
SomeClass.doPrint()
println("Hello MainClassA")
}
}
MainClassB.scala
的内容是(在此处相同的注释):
object MainClassB extends App {
override def main(args: Array[String]): Unit = {
SomeClass.doPrint()
println("Hello MainClassB")
}
}
plugins.sbt
的内容将是:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0")
现在,我们已经准备就绪,需要执行。我们安装了sbt-assembly
插件,因此可以运行:sbt assembly.
这将创建一些文件,但是我们会对2:
感兴趣./moduleA/target/scala-2.12/moduleA-assembly-0.1.0-SNAPSHOT.jar
./moduleB/target/scala-2.12/moduleB-assembly-0.1.0-SNAPSHOT.jar
然后,当运行java -jar ./moduleA/target/scala-2.12/moduleA-assembly-0.1.0-SNAPSHOT.jar
时,我们得到:
I am in commons
Hello MainClassA
而且,当运行java -jar ./moduleB/target/scala-2.12/moduleB-assembly-0.1.0-SNAPSHOT.jar
时,我们得到:
I am in commons
Hello MainClassB
P.S。确实不建议从同一内部版本创建多个jar。这样做会带来巨大的风险,即缺少依赖项并导致运行时异常(缺少方法/类)。