2014-12-04 103 views
2

我有一個項目,建立與sbt和使用akka演員。我用「sbt'run $ args'」命令運行它,我希望這個程序根據某些條件返回不同的退出代碼。我使用System.exit(代碼)從我的主要角色出於此目的。
問題,我不能老是解決的是SBT退出代碼依賴於程序的參數:有時,錯誤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退出代碼和[成功]消息退出。
有沒有辦法強制sbt退出時使用與我的程序相同的代碼?
P.S.我不確定,但看起來主要區別是第一種情況下,程序在一個線程中執行,而在第二種情況下,它在多於一個線程中執行

回答

0

System.exit(或更好:sys.exit)退出當前運行。如果運行時,然後調用sys.exit不會退出sbt本身,而只是分叉進程。例如,如果你有fork in Run := true,那麼調用sbt run會使sbt產生第二個獨立的JVM(目的是你不想在同一個JVM中搞亂)。

在這種情況下,您可以爲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

+0

謝謝你的回答,但我得到一個錯誤與此解決方案: 錯誤:符號值的ExitCode不存在於$ b001ceba8a6ab7cd4585 $ sbtdef scala.reflect.internal.FatalError: – 2014-12-05 07:58:21

+0

我使用2.10.4階 – 2014-12-05 08:00:19

+0

sbt使用獨立於您的項目的獨立Scala版本,因此無關緊要。可能你沒有使用sbt 0.13。你有沒有看到在'project/build.properties'中指定sbt版本的前幾行?我認爲舊的sbt版本使用Scala 2.9,它沒有我用於'ExitCode'的正則表達式方法。 – 2014-12-05 09:32:16