我有一个项目,使用sbt构建并使用akka actor。我用" sbt'运行$ args'"命令,我希望该程序根据某些条件返回不同的退出代码。为此,我使用主要actor的System.exit(代码)。
问题,我无法解决的是sbt退出代码依赖于程序参数:有时它会以错误退出
java.lang.RuntimeException: Nonzero exit code returned from runner: 3 at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:runMain for the full output.
[error] (compile:runMain) Nonzero exit code returned from runner: 3
[error] Total time: 5 s, completed Dec 4, 2014 6:50:50 PM
这不是美,但那没关系
但在某些情况下我运行System.exit(3),但sbt以0退出代码和[success]消息退出。
有没有办法强制sbt退出使用与我的程序相同的代码?
附:我不确定,但看起来参数之间的主要区别在于,在第一种情况下,程序在一个线程中执行,在第二种情况下,它在多于一个线程中执行
答案 0 :(得分:0)
System.exit
(或更好:sys.exit
)退出当前运行时。如果sbt 分叉运行时,则调用sys.exit
不会退出sbt本身,而只是退出分叉进程。例如,如果你有fork in Run := true
,那么调用sbt run
将使sbt产生第二个独立的JVM(目的是你不想在同一个JVM中混乱)。< / p>
在这种情况下,您可以define a custom run task为实际的sbt实例重复sys.exit
。
修改:这是一个最小的例子:
// project/build.properties
sbt.version = 0.13.6
// build.sbt
scalaVersion := "2.11.4"
lazy val myRun = taskKey[Unit]("A custom run task.")
fork in myRun := true
myRun := {
val r = (runner in Compile).value
val cp = (fullClasspath in Compile).value
val res = r.run("foo.Bar", cp.map(_.data), Nil, streams.value.log)
val ExitCode = "Nonzero exit code: (-?\\d+)".r
val code = res match {
case Some(ExitCode(c)) => c.toInt
case _ => 0
}
println(s"myRun returned with $code")
if (code != 0) sys.exit(code)
}
// src/main/scala/foo/Bar.scala
package foo
object Bar extends App {
println("Hello.")
sys.exit(3)
}
测试:sbt myRun
。不要问我为什么run
会返回Option[String]
而不是直的Int
。