Page 1 of 1

Cannot load JavaFX classes from JDKs that include them

Posted: 22 May 2020, 00:00
by thezboe
Here's my situation:
I have tried using both the Liberica JDK 14 that includes JavaFX as well as Azul 13 that includes JavaFX.

I am trying to webstart an application that does not depend on JavaFX directly. However, it has "plugin" JARs that are downloaded to provide extra functionality based on configuration. These plugin JARs are not in the JNLP, but they are loaded with a URLClassLoader with the JNLPClassLoader set as the parent. I have a few that also do not have any mention of JavaFX and those all work fine.

I know that the javafx modules are available via running

Code: Select all

ModuleLayer.boot().findLoader("javafx.swing").loadClass("javafx.embed.swing.JFXPanel");
and also

Code: Select all

ModuleLayer.boot().modules().stream()
                .map(Module::getName)
                .forEach(System.out::println);
Those both run successfully, but then the code errors out when trying to load JFXPanel directly after. It appears that the classloader that has access to the javafx classes is the InternalPlatformClassLoader. I thought the behavior of ClassLoaders was to delegate to the parent. In that case, why isn't it loading the classes that are being found?

Sorry, but I cannot share code, jnlp, or log files in this case.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 22 May 2020, 12:00
by Janak Mulani
Hello,

Please see:

https://github.com/karakun/OpenWebStart ... enwebstart

You are using JVM with JavaFX for running your Jnlp Application which has some JavaFx code. In this case you must make sure that required JavaFx libs are on the class path.

For example for JFxPanel you will have to make sure that javafx-swing-x.x.x-win.jar is available on the class path.

Thanks

Janak

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 22 May 2020, 18:31
by thezboe
Shouldn't that only be necessary if I didn't have a JDK installed on my machine that includes JavaFX?

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 22 May 2020, 21:34
by Stephan Classen
yes, if the JDK (I think Oracle Java 8 is the only one) has the JavaFX included then the application should run without a dependency to the jfx jars

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 22 May 2020, 22:10
by thezboe
Maybe I'm confused. Do the Liberica and Azul JDKs not include JavafX in the "same way" that Oracle Java 8 used to?
For Azul, I've downloaded from here https://www.azul.com/downloads/zulu-com ... age=jdk-fx
It specifically states that includes JavaFX. As well as the Liberica JDK that states it comes with "LibericaFX".

I have verified that a JavaFX application works fine being webstarted with these, but not with the plugin architecture of my app. Where the plugin JARs are not explicitly listed in the JNLP.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 22 May 2020, 22:12
by Stephan Classen
so your app has its own classloader?

Or how are you loading your "plugins"?

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 22 May 2020, 22:24
by thezboe
I'm instantiating a new URL ClassLoader that points to the download location of the plugin JAR I want to download, with the JNLP ClassLoader as the parent. Then I'm creating the class by calling

Code: Select all

Class clazz = urlLoader.loadClass(classname);
Object o = clazz.newInstance();
I know newInstance() is deprecated, but updating to the newer way doesn't fix anything, so I've left it like this because it's shorter.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 22 May 2020, 23:17
by Stephan Classen
maybe try the 3.0.0-alpha1 version.
it has a completely new classloader implementation.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 23 May 2020, 00:20
by thezboe
Okay, after some modification to the JNLP (lazy download does not work, and java version seems to be checking against the embedded OWS JRE instead of the JDK/JRE we want to run with) it seems to be working with the 3 alpha.

I assume this will mean I will have to deal with this not working with the current version of OWS. Sounds like not many people have this use case.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 23 May 2020, 00:44
by Stephan Classen
no, it is generally discouraged to create a own classloader in a JNLP application.
We will release a new 3.0.0 candidate soon so please register for the newsletter to get informed

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 23 May 2020, 01:00
by thezboe
Is there a way to do the "plugins" without creating my own classloader? I've seen the reflection hack that some people have done to add URLs to an existing classloader.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 23 May 2020, 03:51
by Stephan Classen
You could try to leverage lazy loading.
But this would still require you to list all possible plugins in the JNLP.

So maybe this is not the sufficient

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 25 May 2020, 08:29
by thezboe
Yea, and we're trying to avoid that since we allow 3rd parties to potentially make their own plugins.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 25 May 2020, 10:59
by Hendrik Ebbers
Hi,

I assume that "DownloadService.loadResource()" might help here (https://docs.oracle.com/javase/9/docs/a ... rvice.html). By doing so you should be able to add new Jars to the JNLP ClassLoader without creating your own classloader. To be true I never tested that behaviour and assume that it will only work in the 3.0.0-alpha.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 28 May 2020, 14:19
by Janak Mulani
Hi

I have installed Zulu13.31.11-ca-fx-jdk13.0.3-win_x64.

My OWS uses this JVM to run the Jnlp Application.

I created two Jnlp applications : one simple Hellowworld and second one which uses JFxPanel and JavaFX webView.

The following Jnlp files run without any problem with the above JVM with JavaFX

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="$$codebase">
    <information>
        <title>JavaFX 8-11 App</title>
        <vendor>Karakun AG</vendor>
        <offline-allowed/>
    </information>
    <security>
        <all-permissions/>
    </security>
    <resources>
        <java version="13*"/>
        <jar href="generated-jars/javafx-test.jar"/>
    </resources>
    <application-desc main-class="com.karakun.ows.javafx_test.HelloWorld11Launcher"/>
</jnlp> 

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="$$codebase">
    <information>
        <title>JavaFX 11 App</title>
        <vendor>Karakun AG</vendor>
        <offline-allowed/>
    </information>
    <security>
        <all-permissions/>
    </security>
    <resources>
        <j2se version="13*"/>
        <jar href="jars/s_jfx11lib.jar"/>
    </resources>
    <application-desc main-class="com.karakun.ows.jfx.LauncherSwingFXBrowser"/>
</jnlp> 

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 29 May 2020, 06:39
by thezboe
Are you running with the official released version or the 3 alpha?
Also, the problem seems to have to do with downloading and running javafx JARs outside of the JNLP file with an extra URL Class Loader.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 29 May 2020, 08:11
by Hendrik Ebbers
Please have a look at "DownloadService.loadResource()" (https://docs.oracle.com/javase/9/docs/a ... rvice.html). I assume that this will be a better solution than a custom class loader.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 29 May 2020, 12:57
by Janak Mulani
> Are you running with the official released version

With official release.1.1.7

>Also, the problem seems to have to do with downloading and running javafx JARs outside of the JNLP file with an extra URL Class Loader.

But if JavaFx classes are provided by the Jvm (eg Azul JDK FX 13) and are available on the classpath then is there still a need to download JavaFx jars and load classes with custom classloader?

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 29 May 2020, 17:52
by thezboe
Hendrik Ebbers wrote: 29 May 2020, 08:11 Please have a look at "DownloadService.loadResource()" (https://docs.oracle.com/javase/9/docs/a ... rvice.html). I assume that this will be a better solution than a custom class loader.
I will try that, but I don't have the time currently.

Re: Cannot load JavaFX classes from JDKs that include them

Posted: 29 May 2020, 17:53
by thezboe
Janak Mulani wrote: 29 May 2020, 12:57 > Are you running with the official released version

With official release.1.1.7

>Also, the problem seems to have to do with downloading and running javafx JARs outside of the JNLP file with an extra URL Class Loader.

But if JavaFx classes are provided by the Jvm (eg Azul JDK FX 13) and are available on the classpath then is there still a need to download JavaFx jars and load classes with custom classloader?
I am not downloading the JavaFX jars. I am downloading a jar that imports JavaFX functionality, and it is failing to find JavaFX libraries because of the separate classloader.