2014-01-30 2 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. Чтобы избежать этого, Sbt реализует диспетчер безопасности. http://www.scala-sbt.org/0.13/docs/Running-Project-Code.html#System.exit –

9

Вы можете разветвить вашу JVM при запуске консольного приложения в сеансе SBT. Таким образом, когда ваше консольное приложение выйдет, он не убьет хостинг 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

Это также имеет то преимущество, что «sbt run» выходит с правильным кодом состояния! – Douglas

+0

Поскольку я создаю программу, которая должна вернуть код выхода, это лучший выбор. И поскольку OP создавал консольное приложение, это также может быть лучшим решением. – ChuckCottrill

Смежные вопросы