On 3/26/19 1:18 PM, Răzvan Rotaru wrote:
Thank you. I don't know whether the clojure compiler needs initialized
classes or not, but I suspect it does. Clojure has macros, which are
executed at compile time, which means some classes are instantiated. I will
ask the clojure developers. If that's the case though it means clojure will
not be able to compile Java FX. This is actually half bad, since this is
only needed when one uses something called ahead of time compilation (AOT),
so one can use Java FX in clojure but not with AOT (i.e. compilation will
occur at runtime).
But apart from that, I think it's rather strange that class
loading/initalisation depends on the thread it happens. How do you make
sure that javafx.stage.Screen is not loaded from the wrong thread?
Java (JVM) loads and initializes classes lazily, when 1st needed. So if
javafx.stage.Screen API is specified to be invoked in special JavaFX
Application thread only, then this is where the static initializer will
get executed too. It seems that this has not been a problem for normal
(Java-side) use.
Regards, Peter
Regards,
Răzvan
On Mon, 25 Mar 2019 at 17:41, Peter Levart <[email protected]> wrote:
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