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 <j...@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.

Reply via email to