Scala SBT为可运行的jar构建多模块项目

Arv*_*rve 6 scala sbt

我在构建和运行SBT项目时遇到了问题.

  • "协议"项目由几个模块使用,包括"守护进程".

  • "守护进程"项目应打包为可执行jar.

这样做的"正确"方法是什么?

这是我的Build.scala:

object MyBuild extends Build {
lazy val buildSettings = Seq(
    organization := "com.example",
    version      := "1.0-SNAPSHOT",
    scalaVersion := "2.9.1"
    )

lazy val root = Project(
    id = "MyProject",
    base = file("."),
    aggregate = Seq(protocol, daemon)
    )

lazy val protocol = Project(
    id = "Protocol",
    base = file("Protocol")
    )

lazy val daemon = Project(
    id = "Daemon",
    base = file("Daemon"),
    dependencies = Seq(protocol)
    )
// (plus more projects)
Run Code Online (Sandbox Code Playgroud)

col*_*red 7

正确的方法是使用其中一个sbt插件来生成jar.我已经测试了一个jar程序集,并且都支持从jar中排除库.您可以将设置添加到单个项目中,以便只有部分项目可以生成jar.

我个人正在使用汇编,但正如这篇文章指出的那样,如果你有重叠的文件名,你会遇到问题.

编辑:

对于上面的示例,您可以在顶部添加以下导入:

import sbtassembly.Plugin._ 
import AssemblyKeys._
Run Code Online (Sandbox Code Playgroud)

您将项目修改为如下所示:

lazy val daemon = Project(
  id = "Daemon",
  base = file("Daemon"),
  dependencies = Seq(protocol),
  settings = assemblySettings
)
Run Code Online (Sandbox Code Playgroud)

您还需要将以下内容添加到您的project/plugins.sbt(对于sbt .11):

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.7.3")

resolvers += Resolver.url("sbt-plugin-releases",
  new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns)
Run Code Online (Sandbox Code Playgroud)

如果您决定使用Assembly,则可能需要删除重复的文件.下面是用于在名为"projectName"的项目中排除重复的log4j.properties文件的汇编代码示例.这应该作为项目"设置"序列的一部分添加.请注意,第二个collect语句是基本实现,是必需的.

excludedFiles in assembly := { (bases: Seq[File]) =>
  bases.filterNot(_.getAbsolutePath.contains("projectName")) flatMap { base => 
    //Exclude all log4j.properties from other peoples jars
    ((base * "*").get collect {
      case f if f.getName.toLowerCase == "log4j.properties" => f
    }) ++ 
    //Exclude the license and manifest from the exploded jars
    ((base / "META-INF" * "*").get collect {
      case f if f.getName.toLowerCase == "license" => f
      case f if f.getName.toLowerCase == "manifest.mf" => f
    })
  }
}
Run Code Online (Sandbox Code Playgroud)