【问题标题】:Scala SBT build multi module project to runnable jarsScala SBT 将多模块项目构建为可运行的 jar
【发布时间】:2012-03-21 22:46:15
【问题描述】:

我在构建和运行 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)

【问题讨论】:

    标签: scala sbt


    【解决方案1】:

    正确的方法是使用 sbt 插件之一来生成 jars。我已经测试了 one-jar 和 assembly 并且都支持从你的 jar 中排除库。您可以将设置添加到单个项目,以便只有其中一些项目会生成 jar。

    我个人使用的是汇编,但正如this post 指出的那样,如果文件名重叠,就会遇到问题。

    编辑:

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

    import sbtassembly.Plugin._ 
    import AssemblyKeys._
    

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

    lazy val daemon = Project(
      id = "Daemon",
      base = file("Daemon"),
      dependencies = Seq(protocol),
      settings = assemblySettings
    )
    

    您还需要将以下内容添加到您的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)
    

    如果您决定使用 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
        })
      }
    }
    

    【讨论】:

    • 谢谢,效果很好。还必须在我的 plugins.sbt 中添加插件 - 您也可以在答案中添加它以帮助其他人。明天我会结束这个问题。看来我唯一真正需要的是将设置 mainClass := Some("com.example.Main") 添加到我的项目中,只要我自己管理依赖项/类路径。 -- 这在文档中非常隐蔽,或者我只是瞎了 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    • 2023-04-10
    • 2014-01-15
    • 2016-04-13
    • 2021-01-22
    • 2016-10-01
    • 1970-01-01
    相关资源
    最近更新 更多