2014-01-30 32 views
10

我创建了一个简单的Scala控制台应用程序。我通过sbt run运行它,总是收到退出以下异常:sbt.TrapExitSecurityException抛出“sbt run”

Exception: sbt.TrapExitSecurityException thrown from the UncaughtExceptionHandler in thread "run-main-0" 
[success] Total time: 17 s, completed 30.01.2014 22:19:37 

之后,我所有的控制台输出变得不可见。我可以键入并运行应用程序,但是看不到我正在输入的内容。

这个异常是什么意思?我究竟做错了什么?

+0

你使用什么版本的sbt?什么是终端? –

回答

5

目前还不清楚你用的什么版本SBT,但SBT 0.13.2-M1它与下面的类很容易复制:

Hello.scala

object ExitApp extends App { 
    exit(0) 
} 

的类会正确显示异常sbt.TrapExitSecurityException何时被抛出 - 每当调用方法java.lang.Runtime.exit(int)时。

$ sbt run 
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins 
[info] Loading project definition from /Users/jacek/sandbox/so/TrapExitSecurityException/project 
[info] Set current project to trapexitsecurityexception (in build file:/Users/jacek/sandbox/so/TrapExitSecurityException/) 
[warn] there were 1 deprecation warning(s); re-run with -deprecation for details 
[warn] one warning found 
[info] Running ExitApp 

Exception: sbt.TrapExitSecurityException thrown from the UncaughtExceptionHandler in thread "run-main-0" 
[success] Total time: 6 s, completed Jan 30, 2014 9:05:24 PM 

从应用程序中删除调用,异常消失。根据sbt.TrapExit scaladoc:

这类代码只能通过派生一个新的JVM来调用。

你为什么要用它?

+0

我的sbt版本是13.0。当我执行'sys.exit(0)'时发生错误。什么是终止程序的正确方法? –

+1

只需让它在没有'sys.exit(0)'的情况下完成。如果应用程序没有非deamon线程并且主线程终止,那么应用程序也是如此。 –

+0

sys.exit会杀死运行的jvm。 Sbt实施一个安全经理来避免这种情况。 http://www.scala-sbt.org/0.13/docs/Running-Project-Code.html#System.exit –

9

在SBT会话中运行控制台应用程序时,您可以分叉您的JVM。这样,当你的控制台应用程序退出时,它不会杀死托管sbt JVM。我在集成测试配置中为main类执行此操作。

build.sbt(或您的等效SBT项目配置文件):

fork in (IntegrationTest, run) := true 

(你可能想简单地fork in run := true覆盖控制台主)。然后在扩展App任何类:(你可能不需要sys.exit呼吁所有,如果您的应用程序不守分叉JVM活着)

package com.example 

object StuffMain extends App { 
    println("stuff") 

    sys.exit(0) // 0 is a successful Unix exit code 
} 

在我来说,我就可以执行通过运行这个集成测试StuffMain

sbt> it:runMain com.example.StuffMain 
5
// build.sbt 
trapExit := false 

工作对我来说

+1

这也有一个好处,即“运行”用正确的状态码退出! – Douglas

+0

由于我正在构建需要返回退出代码的程序,因此这是最佳选择。而且由于OP正在构建一个控制台/外壳应用程序,这也可能是最好的解决方案。 – ChuckCottrill

相关问题