我正在尝试向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
)
}
但是,这会将类路径设置为最新运行(不会恢复为默认值)。
答案 0 :(得分:2)
在回答https://stackoverflow.com/a/54488121/2037054的马里奥·加里奇(Conditional scalacSettings / settingKey)的帮助下,我设法使它工作:
// 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)