JavaFX Launch Failure on Ubuntu from JNI

Nir Lisker nlisker at gmail.com
Thu Jan 20 00:57:21 UTC 2022


>
> 1. If your main class extends Application, and you try to run it like:
> java -jar MyApplication.jar


> It will fail immediately with:
> Error: JavaFX runtime components are missing, and are required to run this
> application


> 2. If you "trick" it, by making your Application class a separate class
> that you call from your main class, it will run fine using:
> java -jar MyApplication.jar


This is documented behavior, although I admit it was hard to find it.
If you go to the getting started documentation at
https://openjfx.io/openjfx-docs/ and the go to Runtime images > Non-Modular
project it will tell you that:

"As explained here, in order to create a runnable jar with all the required
JavaFX dependencies, you will need to use a launcher class that doesn't
extend from Application." with a link to the explanation.

Another option is to add the vm argument -Djava.library.path and point to
the missing runtime components (which I believe is just the bin directory
of the JavaFX runtime where the .dll files are in the case of Windows).

If we could explain this in the error message somehow it will save a lot of
trouble for a lot of people. Something like:

"Error: JavaFX runtime components are missing, and are required to run this
application. Either start the application from a class that does not extend
Application or specify the -Djava.library.path VM argument pointing to the
bin directory".

 I don't know if this specific case is detectable. Maybe Johan can comment.

On Thu, Jan 20, 2022 at 2:08 AM Steve Hannah <steve at weblite.ca> wrote:

> I've reduced the problem down to something minimal and have found that:
>
> 1. If your main class extends Application, and you try to run it like:
> java -jar MyApplication.jar
>
> It will fail immediately with:
> Error: JavaFX runtime components are missing, and are required to run this
> application
>
> 2. If you "trick" it, by making your Application class a separate class
> that you call from your main class, it will run fine using:
> java -jar MyApplication.jar
>
> 3. It will also run fine in this scenario using
> -Djava.class.path=MyApplication.jar instead of -jar:
> java -Djava.class.path=MyApplication.jar Main
>
> 3. If I try to simulate the exact same thing with my own launcher, it will
> hang somewhere in the JavaFX initialization:
>
> with javafx.verbose=true, the output is:
>
> System.loadLibrary(prism_es2) succeeded
> JavaFX: using com.sun.javafx.tk.quantum.QuantumToolkit
> System.loadLibrary(glass) succeeded
>
> But it hangs there, and never displays the screen.
>
> The C code for this launcher is:
>
> char *mainClass;
>
> JavaVM *vm;
> JNIEnv *env;
> JavaVMInitArgs vm_args;
> JavaVMOption options[2];
> mainClass = "Main";
> options[0].optionString = "-Djava.class.path=MyApplication.jar";
> options[1].optionString = "-Djavafx.verbose=true";
> vm_args.version = JNI_VERSION_1_2;
> vm_args.options = options;
> vm_args.nOptions = 2;
> vm_args.ignoreUnrecognized = 0;
>
> jobjectArray args;
> jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);
> if (res < 0) {
>     printf("Can't create Java VM\n");
>     exit(1);
> }
> jclass cls = (*env)->FindClass(env, mainClass);
> if (cls == 0) {
>
>     printf("Main class %s class not found\n", mainClass);
>     exit(1);
> }
> jmethodID mid =
> (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
> if (mid == 0) {
>     printf("main() method not found\n");
>     exit(1);
> }
> //jstring argString = (*env)->NewStringUTF(env, ""); //empty arg list
> args =
>  (*env)->NewObjectArray(env, 0, (*env)->FindClass(env,
> "java/lang/String"), NULL);
> if (args == 0) {
>     printf("Out of memory\n");
>     exit(1);
> }
>
> (*env)->CallStaticVoidMethod(env, cls, mid, args);
>
>
>
> Can anyone spot any differences between that and running with the "java"
> binary:?
> java -Djava.class.path=MyApplication.jar Main
>
> I have experimented both with JDKs that include JavaFX (e.g. Zulu) and ones
> that do not (e.g. AdoptOpenJDK).  Both exhibit the same behaviour (except
> with AdoptOpenJDK, I also add the javafx jars to the classpath).
>
> For this test I'm using JDK 11 on Mac OS Mojave, but it is consistent with
> my earlier troubles on Ubuntu (also JDK11).
>
>
> Best regards
>
> Steve
>
>
> On Wed, Jan 19, 2022 at 3:06 PM John Neffenger <john at status6.com> wrote:
>
> > On 1/19/22 2:12 PM, Steve Hannah wrote:
> > > I have been resisting using modules for a long time because it just
> makes
> > > things more complicated, ...
> >
> > It also makes some things easier, though, and certainly smaller. It's
> > easier to use an old-school Makefile with modules, and using 'jlink' can
> > get a simple Hello World JavaFX application and Java runtime down to
> > just 31 megabytes.
> >
> > Here's my minimal, no-magic example:
> >
> > https://github.com/jgneff/hello-javafx
> >
> > with a simple Makefile:
> >
> > https://github.com/jgneff/hello-javafx/blob/main/Makefile
> >
> > and a Maven POM for use online with Maven Central or offline with a
> > local Debian- or Ubuntu-built Maven repository:
> >
> > https://github.com/jgneff/hello-javafx/blob/main/pom.xml
> >
> > John
> >
>
>
> --
> Steve Hannah
> Web Lite Solutions Corp.
>


More information about the openjfx-dev mailing list