线程“main”中的异常 java.lang.ExceptionInInitializerError (Clojure)

Posted

技术标签:

【中文标题】线程“main”中的异常 java.lang.ExceptionInInitializerError (Clojure)【英文标题】:Exception in thread "main" java.lang.ExceptionInInitializerError (Clojure) 【发布时间】:2013-11-26 19:25:25 【问题描述】:

我正在尝试以 .jar 和 .war 格式部署 Clojure 应用程序。到目前为止,我已经成功部署了一个 .jar;我正在研究.war。该应用程序只是一个测试应用程序,旨在展示 Clojure 和 JavaFX 的一些功能。我的意思是通过 AWS Elastic Beanstalk 将它部署到我刚刚开始设置的网站。目前,该应用程序仅显示一堆模糊的圆圈,在 600x600 的舞台上移动 40 秒。然而,即使应用程序在这 40 秒内成功运行,它总是在 40 秒的动画之后突然终止。我的 project.clj 文件如下所示:

(defproject clojurefx/arg "0.0.10-SNAPSHOT"
  :description "Helper functions and probably a wrapper to simplify usage of JavaFX in Clojure.
                This is meant to be used with Java 8.
                ..."
  :url "https://www.github.com/zilti/clojurefx" ; my project is essentially forked from this project
  :lein-release :deploy-via :clojars
  :license :name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"
  :dependencies [[org.clojure/clojure "1.5.1"]]
  :plugins [[lein-marginalia "0.7.1"]
            ...]
  :profiles :dev :dependencies [[midje "1.6-beta1"]]
  :main clojurefx.arg.splashpage
  :aot [clojurefx.arg.splashpage])

这是-main 函数所在的地方:

(ns clojurefx.arg.splashpage
  (:require
    [clojure.reflect :as clj-r]
    [clojure.stacktrace :as stacktrace]
    [clojurefx.arg.core :as core]
    [clojurefx.arg.core :refer [deffx]]
    ...)
  (:import
    (javafx.scene.text Font FontPosture FontWeight Text)
    ...)
  (:gen-class))

(defn -main [& args]
  (println "Up and running! The arguments supplied were: " args))

;=====JavaFX visual objects initialized and displayed with the code below=====
;-----Root-----
(deffx rt group)
;-----Scene/Window-----
(deffx scn scene
  :width 600
  :height 600
  :root rt
  :fill (. Color BLACK))
;-----Stage/Window-surround-----
(deffx stg stage
  :title "Colorful Circles"
...
(dofx (.show stg)) ; shows the JavaFX window with the circle animation
(dofx (.play tmln)) ; play 40s of animation

正如我所说,动画可以正常播放 40 秒,但此时出现以下异常:

-> Exception in thread "main" java.lang.ExceptionInInitializerError
->   at clojure.main.main(main.java:37)
     ... ; a long list of traced errors
-> Caused by: java.lang.IllegalStateException: Toolkit not initialized
     ... ; a long list of traced errors
-> Exception in thread "Thread-4" clojure.lang.ExceptionInfo: Subprocess failed :exit-code 1
     ... ; a long list of traced errors
->   at java.lang.Thread.run(Thread.java:724)

我认为这可能与 JavaFX 线程的工作方式有关。当动画停止运行时,可能会有某种超时。相比之下,当我在 project.clj 中注释掉 main clojurefx.arg.splashpage:aot [clojurefx.arg.splashpage]) 并手动将 splashpage.clj 文件中的代码复制、粘贴和评估到 REPL 中时,没有超时。此外,当我将 JavaFX 对象初始化和显示的代码放在一个函数中时,比如说(init-stage),这样在显式调用函数之前不会在运行时评估代码,“超时”在JVM 启动并调用(-main) 函数。

想法?我意识到知道 Clojure 的人与知道 JavaFX 8 的人的交集非常小......

附加信息:

我还有另一个相关的问题。现在,当我尝试部署 .jar 文件时,该文件已成功创建,如下所示:

Alexanders-MacBook-Pro:cljfx-arg alexandergunnarson$ lein uberjar
Compiling clojurefx.arg.splashpage
Created /Users/alexandergunnarson/.lein/cljfx-arg/target/arg-0.0.10-SNAPSHOT.jar
Created /Users/alexandergunnarson/.lein/cljfx-arg/target/arg-0.0.10-SNAPSHOT-standalone.jar

但是当我在我的 Mac(无论是否独立)上运行 .jar 时,OS X 显示“无法启动该文件”。此外,实际创建 .jar 的点是动画停止或我退出显示动画(JVM)的main 应用程序的点。

【问题讨论】:

ExceptionInInitializerError 在静态块失败时发生。你可以打开主Closure jar,反编译主类,看看静态块是否引用了不存在的东西。 什么是tmln?我没有看到它在列表中的任何地方定义?只是播放动画的时间吗?此外,如果没有堆栈跟踪,很难猜测哪些代码失败了。堆栈跟踪中是否提到了您的代码,还是所有其他库,例如 JavaFX? @NathanDavis - 抱歉,tmln 是一个时间轴对象。如果您愿意,我可以发布完整的堆栈跟踪,但除了 Java 和 JavaFX 库之外没有提及任何其他内容。 @GV - 好建议。我不熟悉反编译 jars,但我确信网上有一些很好的教程。我会告诉你进展如何。 【参考方案1】:

答案是,对于某些要导入的 JavaFX 类,需要调用以下代码:

(defonce force-toolkit-init (javafx.embed.swing.JFXPanel.))

defonce 用于确保工具包不会以某种方式重新初始化。

最好在导入任何 JavaFX 类之前声明它。

【讨论】:

以上是关于线程“main”中的异常 java.lang.ExceptionInInitializerError (Clojure)的主要内容,如果未能解决你的问题,请参考以下文章

我的代码上的线程“main”java.util.NoSuchElementException 中的异常?

如何修复运行时错误-线程“main”java.util.NoSuchElementException中的异常

HTTPClient 示例 - 线程“main”中的异常 java.lang.NoSuchFieldError: INSTANCE

为啥我在代码中的线程“main”java.lang.StringIndexOutOfBoundsException 错误中收到异常?

线程“main”中的 Java 异常 java.lang.StringIndexOutOfBoundsException 错误

线程“main”中的异常 java.lang.ExceptionInInitializerError (Clojure)