scala “sbt运行”时抛出sbt.TrapExitSecurityException异常

8nuwlpux  于 2023-01-17  发布在  Scala
关注(0)|答案(6)|浏览(228)

我创建了一个简单的Scala控制台应用程序,使用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

在那之后,我的控制台输出就变得不可见了,我可以输入和运行应用程序,但是我看不到我输入的内容。
这个异常是什么意思?我做错了什么?

bnl4lu3b

bnl4lu3b1#

// build.sbt
trapExit := false

为我工作

dffbzjpn

dffbzjpn2#

当在SBT会话中运行控制台应用程序时,您可以派生JVM。这样,当您的控制台应用程序退出时,它不会杀死托管的sbt JVM。我在集成测试配置中为main类这样做。
build.sbt(或等效的sbt项目配置文件)中:

fork in (IntegrationTest, run) := true

(you可能只需要fork in run := true来覆盖控制台main)。然后在扩展App的任何类中:

package com.example

object StuffMain extends App {
  println("stuff")

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

(You如果您的应用程序不保持派生的JVM处于活动状态,则可能根本不需要sys.exit调用。)
在我的例子中,我可以通过运行以下命令来执行这个集成测试StuffMain

sbt> it:runMain com.example.StuffMain
70gysomp

70gysomp3#

不清楚您使用的是什么SBT版本,但使用SBT0.13.2-M1时,它可以很容易地用以下类重现:
"你好,斯卡拉"

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来调用。
你到底为什么要用它?

b4wnujal

b4wnujal4#

此异常不是错误。
SBT只是简单地警告您正在运行的应用程序调用了sys.exit(0),而不是终止JVM(并在同一情况下终止SBT),SBT拦截该调用并保持JVM运行,这样您就可以继续与SBT交互。
我通过检查SBT的源代码找到了这个解释:

/** SecurityManager hook to trap calls to `System.exit` to avoid shutting down the whole JVM.*/
  override def checkExit(status: Int): Unit = if (active) {
    val t = currentThread
    val stack = t.getStackTrace
    if (stack == null || stack.exists(isRealExit)) {
      exitApp(t, status)
      throw new TrapExitSecurityException(status)
    }
  }
bmp9r5qi

bmp9r5qi5#

我不知道这是否是OP的错误信息,但我遇到了相同的错误信息,我想分享我的解决方案,让其他人找到。我正在使用Guice进行依赖注入,发现自己处于循环依赖的情况下。这导致我的应用程序在尝试设置一切并创建所有要注入的单例时呕吐。
再多一点以防你说得不够清楚。

  • SingletonA注入SingletonB
  • SingletonB注入SingletonC
  • SingletonC注入SingletonA〈-- barf,因为SingletonA还没有完成示例化。

我希望这能帮助人们更快地找到解决方案。我的圈子里有3个单体,如上所示,所以我花了更长的时间才意识到。

x7rlezfr

x7rlezfr6#

当端口已经被占用时,我收到了这个消息。在不同的端口上启动应用程序解决了问题。error screenshot

相关问题