Skip to main content

FXEvaluator defined classes can't be found in current JavaFX ClassLoader

3 replies [Last post]
jonathanbranam
Offline
Joined: 2009-02-06
Points: 0

I am trying to built a site that includes a tutorial section where someone can type in some JavaFX code and execute it. I have the FXEvaluator working, but when I define a class using FXEvaluator.eval() the class is defined in a different ClassLoader and is not accessible by the JavaFX that is currently running. I can have the evaluated script return either the defined class or an instance of the class, but if that class extends CustomNode, JavaFX fails when adding it to the Stage.

Apparently, the JavaFX stylesheet support tries to lookup the class definition using Class.forName() on any Node that is added to the Stage. Class.forName() in this case fails because FXEvaluator uses a different ClassLoader. Is there any way to fix this?

com.sun.stylesheet.StylesheetException: java.lang.reflect.InvocationTargetException
at com.sun.stylesheet.types.TypeManager.getStyleable(TypeManager.java:302)
at com.sun.stylesheet.javafx.FXObjectStyleSupport.getStyleableChildren(FXObjectStyleSupport.java:247)
at com.sun.stylesheet.styleable.DefaultStyleable.getStyleableChildren(DefaultStyleable.java:172)
at com.sun.stylesheet.Stylesheet.applyTo(Stylesheet.java:279)
at com.sun.stylesheet.Stylesheet.applyTo(Stylesheet.java:257)
at javafx.scene.Scene.userInit$(Scene.fx:219)
at javafx.scene.Scene.initialize$(Scene.fx:43)
at evalproject.Main.javafx$run$(Main.fx:53)
at evalproject.Main.javafx$run$(Main.fx:53)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.sun.stylesheet.types.TypeManager.getStyleable(TypeManager.java:287)
at com.sun.stylesheet.javafx.FXObjectStyleSupport.getStyleableChildren(FXObjectStyleSupport.java:247)
at com.sun.stylesheet.styleable.DefaultStyleable.getStyleableChildren(DefaultStyleable.java:172)
at com.sun.stylesheet.Stylesheet.applyTo(Stylesheet.java:279)
at com.sun.stylesheet.Stylesheet.applyTo(Stylesheet.java:257)
at javafx.scene.Scene.userInit$(Scene.fx:219)
at javafx.scene.Scene.initialize$(Scene.fx:43)
at evalproject.Main.javafx$run$(Main.fx:53)
at evalproject.Main.javafx$run$(Main.fx:53)
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 com.sun.javafx.runtime.provider.AWT_EDT_RuntimeProvider$1.run(AWT_EDT_RuntimeProvider.java:104)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: com.sun.stylesheet.StylesheetException: java.lang.reflect.InvocationTargetException
at com.sun.stylesheet.types.TypeManager.getStyleSupport(TypeManager.java:348)
at com.sun.stylesheet.styleable.DefaultStyleable.getStyleSupport(DefaultStyleable.java:125)
at com.sun.stylesheet.styleable.DefaultStyleable.(DefaultStyleable.java:74)
... 25 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.sun.stylesheet.types.TypeManager.getStyleSupport(TypeManager.java:333)
... 27 more
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: ___FX_SCRIPT___$ParticleA
at javafx.reflect.FXLocal$Context.findClass(FXLocal.java:131)
at javafx.reflect.FXLocal$Context.findClass(FXLocal.java:110)
at com.sun.stylesheet.javafx.FXObjectStyleSupport.(FXObjectStyleSupport.java:161)
... 32 more
Caused by: java.lang.ClassNotFoundException: ___FX_SCRIPT___$ParticleA
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at javafx.reflect.FXLocal$Context.findClass(FXLocal.java:119)
... 34 more

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
pforhan
Offline
Joined: 2003-08-07
Points: 0

We use OSGi, so we are in a similar boat. We set up DelegatingClassLoader (you can find instances of this around) made up of classloaders for the current context classloader, the node in question, and the loader of the class dealing with the Scene/Stage.

Then, set the thread context classloader, do your work, and set it back to its original value. A bit annoying, but all our code in this part is pretty rough, so it fits right in!

Pat.

meuter
Offline
Joined: 2009-05-13
Points: 0

I get a similar error with OSGi. I created a fx class which extends Stage and implements a BundleActivator. This works fine until you use a CustomNode. Is there any news to solve this. I'll try the DelegatiggClassloader solution. Yet, I've no clue if or how this may work....

pforhan
Offline
Joined: 2003-08-07
Points: 0

Here's how we got around a host of problems:

http://blog.muddyhorse.com/2009/02/maven-osgi-spring-javafx-ant/

Pat.