4

当尝试从 sbt 0.10.1 运行一个用 Scala 2.8.1 编写的简单 JavaFX 2.0 beta 应用程序时,应用程序窗口关闭后会引发异常:

> run
[info] Running com.tradex.priceviewer.Main
  Exception while removing reference: java.lang.InterruptedException
  java.lang.InterruptedException
  [       at java.lang.Object.wait(Native Method)success
  ]       at java.lang.ref.ReferenceQueue.remove(Unknown Source)Total time: 5 s, completed Aug 5, 2011 1:12:04 PM

  at java.lang.ref.ReferenceQueue.remove(Unknown Source)
  at com.sun.glass.utils.Disposer.run(Disposer.java:64)>
  at java.lang.Thread.run(Unknown Source)

从命令行运行应用程序时,没有抛出异常,返回状态为 0。应用程序的代码如下:

class Starter extends Application {

  def main(args: Array[String]) {
   Application.launch(args)
  } 

  override def start(s: Stage) {
   s.setVisible(true)
  }
}

object Main {

  def main(args: Array[String]) {
    val gui = new Starter
    gui.main(args)
  }
}

抛出异常后,必须退出并再次启动 sbt(重新加载不起作用)。从 Scala 2.8.1 控制台运行相同的应用程序时,第二次运行后会引发以下异常:

scala> m.main(Array(""))

scala> m.main(Array(""))
java.lang.IllegalStateException: Application launch must not be called more than once
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:41)
    at javafx.application.Application.launch(Application.java:115)
    at com.tradex.priceviewer.Starter.main(Main.scala:19)
    at .<init>(<console>:11)
    at .<clinit>(<console>)
    at RequestResult$.<init>(<console>:9)
    at RequestResult$.<clinit>(<console>)
    at RequestResult$scala_repl_result(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.appl...
scala>

有人知道如何正确退出这个 scala/javafx 应用程序吗(所以不需要重新启动 sbt 或 scala 控制台)?

4

1 回答 1

7

我能够在我的系统上重现它。我发现从 sbt 运行它会生成 InterruptedException,而从命令行运行应用程序运行良好。

我在 SBT 的项目设置中添加了以下内容:

fork in run := true

这告诉 SBT 在与 SBT 本身不同的 JVM 中运行应用程序(和测试)。之后,我可以多次运行该应用程序并且不会收到 InterruptedException。

我认为您在这里可能遇到的是 SBT 在同一 JVM 中运行应用程序时使用的 SecurityManager。它必须无法处理 JavaFX 应用程序正在执行的任何操作。通过在单独的 JVM 中运行,您可以绕过它。

于 2011-08-22T13:05:04.007 回答