也许这是Clojure中的错误...我的问题是......
为什么当我在下面的代码中创建一个新的JLabel时,在创建JavaFX Stage时会得到ClassNotFoundException但是当我不创建JLabel时,就会创建JavaFX Stage(并且找到类) ?
要重现这个,请使用lein new app class-path-fail
创建一个新的leiningen项目,并将core.clj替换为此代码:
(ns class-path-fail.core
(:gen-class)
(:import (javafx.stage Stage)
(javafx.application Platform)
(javax.swing JLabel SwingUtilities)
(javafx.embed.swing JFXPanel)))
(JFXPanel.)
(SwingUtilities/invokeAndWait #(new JLabel "ha"))
(defn simple-fn-will-fail []
(let [form `(fn [] (new Stage))]
(eval form)))
(Platform/runLater #(simple-fn-will-fail))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!"))
你可以通过运行来验证这不起作用......但是......注释掉JLabel的创建并观察它是否有效!!
我使用的是Clojure 1.8.0。
这是我的project.clj:
(defproject class-path-fail "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.8.0"]]
:main ^:skip-aot class-path-fail.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
我发现如果前两行代码被反转,那么在类路径上找到Stage并加载。新的前两行看起来像:
(SwingUtilities/invokeAndWait #(new JLabel "ha"))
(JFXPanel.)
答案 0 :(得分:-1)
我遇到了类似的问题(虽然在不同的上下文中),我怀疑它是由JavaFX应用程序线程的类加载器配置引起的,不一定是Clojure特有的。例如,请参阅此类似问题:API works with Java application but not JavaFX和:https://community.oracle.com/thread/2564617?start=0&tstart=0
那就是说,你为什么要使用这么多级别的间接,以及如此多的不同机制来安排将来发生的事情?正常的Clojure代码中很少需要eval
函数。
可以简化行(Platform/runLater #(simple-fn-will-fail))
:不需要匿名函数,因为simple-fn-will-fail
已经是一个不带参数的函数。所以这一行完全等效(并且以完全相同的方式失败):(Platform/runLater simple-fn-will-fail)
此外,simple-fn-will-fail
实际上并没有尝试创建一个新的Stage
,它只返回一个将执行该操作的函数(并且该函数被丢弃,从不被调用),所以如果你没有调用通过调用eval
编译器,不会发生这个问题。
如果我们可以退后一步,更好地了解您实际要完成的工作,可能有办法解决JavaFX应用程序线程上的类加载器问题。
无论如何,这些都是一些想法。也许我们会从更深入了解JavaFX和Clojure编译的人那里听到更多信息。
我在下面发表评论后发现了更多,并发现即使我在-main
中删除了副作用形式,也会抛出同样的异常,试图评估{{1}中的表单}。因此,JavaFX类加载器更加强烈地指出了这个问题。
然而,通过确保在正常的Clojure线程上进行编译,然后使用{运行生成的函数(我认为,这可能是您想要做的),我能够让一切运行正常。 {1}}。这是我的调整版本:
simple-fn-will-fail
使用此版本,我可以毫无问题地调用Platform/runLater
。