【问题标题】:How can I set javaOptions in a custom sbt command如何在自定义 sbt 命令中设置 javaOptions
【发布时间】:2019-06-27 10:44:48
【问题描述】:

我正在尝试向 SBT 添加自定义命令(目前使用版本 1.2.8)以使用不同的 javaOptions 启动我的应用程序。我设法为三种启动可能性创建了 3 个单独的任务来完成此任务,但现在我想将其概括为允许任何启动参数。 到目前为止,我设法创建了以下 build.sbt,但控制台输出显示 sbt runNode node3 仍然使用第 13 行设置的原始类路径 (run / javaOptions ++= Seq(...)。 第 46 行的 run / javaOptions += s"-Djava.library.path=./target/native/$arg" 显然被忽略了。

import com.typesafe.sbt.SbtMultiJvm.multiJvmSettings
import com.typesafe.sbt.SbtMultiJvm.MultiJvmKeys.MultiJvm
import Dependencies._

lazy val `akka-crdt-features` = project
  .in(file("."))
  .settings(multiJvmSettings: _*)
  .settings(
    organization := "nl.about42.akkamavericks",
    scalaVersion := "2.12.8",
    Compile / scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked", "-Xlog-reflective-calls", "-Xlint"),
    Compile / javacOptions ++= Seq("-Xlint:unchecked", "-Xlint:deprecation"),
    run / javaOptions ++= Seq("-Xms128m", "-Xmx1024m", "-Djava.library.path=./target/native"),
    //run / javaOptions ++= Seq("-agentlib:hprof=heap=dump,format=b"),
    libraryDependencies ++= akkaDependencies ++ otherDependencies,
    run / fork := true,
    Compile / run / mainClass := Some("nl.about42.akkamavericks.cluster.ClusterCrdtApp"),
    // disable parallel tests
    Test / parallelExecution := false,
    licenses := Seq(("CC BY 4.0", url("https://creativecommons.org/licenses/by/4.0/"))),
    commands ++= Seq(runNodeCommand),
    Global / cancelable := true
  )
  .configs (MultiJvm)

// setup commands to run each individual node, using a separate folder for the extracted libsigar
lazy val runNode1 = taskKey[Unit]("Run node 1")
lazy val runNode2 = taskKey[Unit]("Run node 2")
lazy val runNode3 = taskKey[Unit]("Run node 3")

runNode1 / fork := true
runNode2 / fork := true
runNode3 / fork := true

runNode1 / javaOptions += "-Djava.library.path=./target/native/node1"
runNode2 / javaOptions += "-Djava.library.path=./target/native/node2"
runNode3 / javaOptions += "-Djava.library.path=./target/native/node3"

fullRunTask(runNode1, Compile, "nl.about42.akkamavericks.cluster.ClusterCrdtApp", "node1")
fullRunTask(runNode2, Compile, "nl.about42.akkamavericks.cluster.ClusterCrdtApp", "node2")
fullRunTask(runNode3, Compile, "nl.about42.akkamavericks.cluster.ClusterCrdtApp", "node3")

// setup command to start a single node, using separate folder for the extracted libsigar
// assumes sane node names that can be used as folder names
val runNodeAction: (State, String) => State = { (state, arg) =>
  run / javaOptions += s"-Djava.library.path=./target/native/$arg"
  val runCommand: Exec = Exec.apply(s"run $arg", state.source)
  state.copy(
    remainingCommands = runCommand +: state.remainingCommands
  )
}

val runNodeCommand: Command = Command.single("runNode")(runNodeAction)

sbt runNode node3 的输出显示(相关行):

[error] no libsigar-amd64-linux.so in java.library.path: [./target/native]
[error] org.hyperic.sigar.SigarException: no libsigar-amd64-linux.so in java.library.path: [./target/native]

我希望它提到./target/native/node3

我的目标是只定义 sbt 命令,因此我可以调用 runNode [anyNodeName] 并让 SBT 使用适当的类路径设置和启动参数启动我的应用程序。

更新: 我在以下方面取得了部分成功:

val runNodeAction: (State, String) => State = { (state, arg) =>
  val stateWithNewOptions = Project.extract(state).appendWithSession(
    Seq(
      run / javaOptions += s"-Djava.library.path=./target/native/$arg"
    ),
    state
  )
  val runCommand: Exec = Exec.apply(s"run $arg", stateWithNewOptions.source)
  stateWithNewOptions.copy(
    remainingCommands = runCommand +: state.remainingCommands
  )
}

但这会将类路径设置为最新运行(不会恢复为默认值)。

【问题讨论】:

    标签: scala sbt


    【解决方案1】:

    在回答 Conditional scalacSettings / settingKey 的 Mario Galic (https://stackoverflow.com/a/54488121/2037054) 的帮助下,我设法让它工作了:

    // setup command to start a single node, using separate folder for the extracted libsigar
    // assumes sane node names that can be used as folder names
    val runNodeAction: (State, String) => State = { (state, arg) =>
      val stateWithNewOptions = Project.extract(state).appendWithSession(
        Seq(
          run / javaOptions += s"-Djava.library.path=./target/native/$arg"
        ),
        state
      )
      val (s, _) = Project.extract(stateWithNewOptions).runInputTask(Compile / run, s" $arg", stateWithNewOptions)
      s
    }
    
    val runNodeCommand: Command = Command.single("runNode")(runNodeAction)
    
    

    【讨论】:

      猜你喜欢
      • 2016-01-28
      • 1970-01-01
      • 2013-11-09
      • 2018-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      相关资源
      最近更新 更多