【问题标题】:Ignoring subproject while building fat JAR of root project在构建根项目的胖 JAR 时忽略子项目
【发布时间】:2016-11-30 01:31:36
【问题描述】:

我有一个根项目,我想用 sbt-assembly 构建一个胖 JAR。它确实有一个子项目,它取决于我想要忽略胖 JAR 的根(好像它不存在一样)。我该怎么做?

基本上我想要根项目包,就好像 Try 1 中的 build.sbt 没有 localMode 子项目一样。

试试 1

我的build.sbt

import sbt.Keys._

name := "myprojectname"
version := "0.0.1-SNAPSHOT"
scalaVersion in ThisBuild := "2.11.8"

mainClass in(Compile, run) := Some("com.mywebsite.MyExample")
mainClass in(Compile, packageBin) := Some("com.mywebsite.MyExample")
mainClass in assembly := Some("com.mywebsite.MyExample")

libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.0" % Provided
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.0" % Test

lazy val localMode = project.
  in(file("localMode")).
  dependsOn(RootProject(file("."))).
  settings(
    name := "myprojectname_local",
    libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.0" % Compile,
    mainClass in(Compile, run) := Some("com.mywebsite.MyExample"),
    mainClass in(Compile, packageBin) := Some("com.mywebsite.MyExample")
  )

fullClasspath in assembly := { 
  (fullClasspath in assembly).value diff 
  (fullClasspath in assembly in localMode).value 
}

目前我收到错误消息:

[error] (localMode/*:assembly) deduplicate: different file contents found in the following:
[error] ~/.ivy2/cache/org.sonatype.sisu/sisu-guice/jars/sisu-guice-2.1.7-noaop.jar:com/google/inject/AbstractModule.class
[error] ~/.ivy2/cache/com.google.inject/guice/jars/guice-3.0.jar:com/google/inject/AbstractModule.class
[error] deduplicate: different file contents found in the following:
[error] ~/.ivy2/cache/org.sonatype.sisu/sisu-guice/jars/sisu-guice-2.1.7-noaop.jar:com/google/inject/Binder.class
[error] ~/.ivy2/cache/com.google.inject/guice/jars/guice-3.0.jar:com/google/inject/Binder.class
[error] deduplicate: different file contents found in the following:
[error] ~/.ivy2/cache/org.sonatype.sisu/sisu-guice/jars/sisu-guice-2.1.7-noaop.jar:com/google/inject/ConfigurationException.class
[error] ~/.ivy2/cache/com.google.inject/guice/jars/guice-3.0.jar:com/google/inject/ConfigurationException.class

and so on...

如果我命令sbt root/assembly 我得到

[error] Expected ID character
[error] Not a valid command: root (similar: reboot, boot, project)
[error] Expected project ID
[error] Expected configuration
[error] Expected ':' (if selecting a configuration)
[error] Expected key
[error] Not a valid key: root (similar: products)
[error] root/assembly
[error]     ^

试试 2

我的第二个build.sbt 无法构建:

import sbt.Keys._

lazy val commonSettings = Seq(
  version := "0.0.1-SNAPSHOT",
  scalaVersion in ThisBuild := "2.11.8",
  mainClass in(Compile, run) := Some("com.mywebsite.MyExample"),
  mainClass in(Compile, packageBin) := Some("com.mywebsite.MyExample"),
  libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.0" % Test
)

lazy val root = project.
  in(file("root")).
  dependsOn(RootProject(file("."))).
  settings(
    name := "myprojectname",
    libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.0" % Provided,
    mainClass in assembly := Some("com.mywebsite.MyExample")
  )

lazy val localMode = project.
  in(file("localMode")).
  dependsOn(RootProject(file("."))).
  settings(
    name := "myprojectname_local",
    libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.0" % Compile
  )

【问题讨论】:

    标签: sbt sbt-assembly


    【解决方案1】:

    我认为您可以使用 assembly::fullClasspath 设置来实现。 default 设置为 fullClasspath or (fullClasspath in Runtime)。所以也许你可以这样做:

    fullClasspath in assembly := { 
      (fullClasspath in assembly).value diff 
      (fullClasspath in assembly in localMode).value 
    }
    

    在没有关于您特定项目配置的详细信息的情况下,我猜localMode 是您要排除的子项目的名称。

    更新

    Try 2 中的 build.sbt 存在一些问题: - 您不会在项目中添加常用设置 - “root”是项目目录的根目录(即in file(".")) - 如果你显式定义root项目,另一个应该依赖它,而不是RootProject,这只是一种引用“隐式”定义的根项目的方式

    import sbt.Keys._
    
    lazy val commonSettings = Seq(
      version := "0.0.1-SNAPSHOT",
      scalaVersion in ThisBuild := "2.11.8",
      mainClass in(Compile, run) := Some("com.mywebsite.MyExample"),
      mainClass in(Compile, packageBin) := Some("com.mywebsite.MyExample"),
      libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.0" % Test
    )
    
    lazy val root = project.in(file(".")).
      settings(commonSettings: _*).
      settings(
        name := "myprojectname",
        libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.0" % Provided,
        mainClass in assembly := Some("com.mywebsite.MyExample")
      )
    
    lazy val localMode = project. // by default the name of the project val is the name of its base directory
      dependsOn(root).
      settings(commonSettings: _*).
      settings(
        name := "myprojectname_local",
        libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.0" % Compile
      )
    

    Multi-project builds 上查看 sbt 文档。关于root 项目的问题,有一章叫做Default root project。现在有了这些修复,root/assembly 是否按预期工作?

    【讨论】:

    • 这没有帮助。我在错误消息中添加了信息。
    • @Make42 你也应该发布你的build.sbt。只需正确配置您的子项目,这个问题可能就可以解决。
    • 你试过用项目范围来调用它吗?喜欢root/assembly
    • 如果我写sbt root/assembly,我会收到您现在可以在问题中阅读的错误。如果我写sbt myprojectname/assembly,我会得到已知错误。我不确定RootProject(file(".")) 指的是什么。
    • 我尝试将所有内容(libraryDependencies ++= sparkDependencies.map(_ % Provided) 除外)放在lazy val commonSettings 中,并将其添加到localMode 作为设置,并创建了一个lazy val root 项目,该项目也使用了commonSettings 并添加了@ 987654345@。我希望你能明白。但是我现在无法编译任何东西(root 和顶级项目都没有)。原因:现在找不到Spark依赖,所以找不到类。
    【解决方案2】:

    试试看

    aggregate in (Compile, assembly) := false
    

    【讨论】:

    • 这似乎不起作用。我收到通常的“重复数据删除”错误。
    猜你喜欢
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 2016-01-12
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多