Hi Razvan,

I don't know Clojure but if this happens during compilation of Clojure source(s) (in clojure.lang.Compile), then the question is: Does Clojure compiler really need to execute static initializers of classes it is "resolving"? It seems it needs to load the classes (presumably because it is using Java reflection to introspect them), but does it really need to initialize the classes?

If it only needs to introspect the classes (but not execute constructors or methods in them or access fields), then it should be using the 3-arg Class.forName() method:

     public static Class<?> forName(String name, boolean initialize, ClassLoader loader)

...passing 'false' as the 2nd argument. That way the "resolved" classes would be loaded but not initialized. Clojure compiler could still introspect them, but no code in classes would be executed. This would be much safer.

Regards, Peter


On 3/24/19 3:16 PM, Răzvan Rotaru wrote:
Hi,

I am trying to use OpenJFX 11.0.2 (for Linux) with Clojure and
https://github.com/fn-fx/fn-fx, and stumbled upon a problem for which I
would like to ask for advice here. The Problem occurs during compilation of
some clojure code, which triggers class loading for javafx.stage.Screen,
which fails with following stack trace (only the relevant part):

java.lang.IllegalStateException: This operation is permitted on the event
thread only; currentThread = main
     at com.sun.glass.ui.Application.checkEventThread(Application.java:441)
     at com.sun.glass.ui.Screen.setEventHandler(Screen.java:369)
     at
com.sun.javafx.tk.quantum.QuantumToolkit.setScreenConfigurationListener(QuantumToolkit.java:684)
     at javafx.stage.Screen.<clinit>(Screen.java:74)
     at java.base/java.lang.Class.forName0(Native Method)
     at java.base/java.lang.Class.forName(Class.java:398)
     at clojure.lang.RT.classForName(RT.java:2207)
     at clojure.lang.RT.classForName(RT.java:2216)
     at clojure.lang.Compiler.resolveIn(Compiler.java:7394)
     at clojure.lang.Compiler.resolve(Compiler.java:7357)
     at clojure.lang.Compiler.analyzeSymbol(Compiler.java:7318)
     at clojure.lang.Compiler.analyze(Compiler.java:6768)
     at clojure.lang.Compiler.analyze(Compiler.java:6745)
     at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3888)

Being only compilation, there should be no Toolkit initialisation, hence no
event thread. Looking at the code it seems that the Screen class can only
be loaded from the event thread. Is this a bug or the intended behaviour?
Is there a way around this for my use case? How does OpenJFX ensure that
Screen is always loaded on the correct thread?

Related bug in fn-fx: https://github.com/fn-fx/fn-fx/issues/25


Cheers,
Răzvan


Reply via email to