Discussion:
Error: JavaFX runtime components are missing, and are required to run this application
Mark Raynsford
2018-10-13 16:19:09 UTC
Permalink
Hello!

Now that Java 11 is at general availability, I decided to give OpenJFX
11 a shot today. Unfortunately, I encountered the above error with an
extremely trivial example project:

Error: JavaFX runtime components are missing, and are required to run
this application

The Maven project setup I'm using is here:

https://github.com/io7m/javafxhello

$ java -version
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

$ mvn --version
Apache Maven 3.5.4 (NON-CANONICAL_2018-09-08T01:02:16+02:00_root;
2018-09-08T00:02:16+01:00) Maven home: /opt/maven
Java version: 11, vendor: Oracle Corporation,
runtime: /usr/lib/jvm/jdk-11 Default locale: en_GB, platform encoding:
UTF-8 OS name: "linux", version: "4.18.12-arch1-1-arch", arch: "amd64",
family: "unix"

If I try to run the program from the IDE (Intellij), the exact command
line used is:

$ /usr/lib/jvm/jdk-11/bin/java
-javaagent:/usr/share/idea/lib/idea_rt.jar=34729:/usr/share/idea/bin \
-Dfile.encoding=UTF-8 \
-classpath /home/rm/doc/dev/2018/10/javafxhello/target/classes:/home/rm/var/maven/org/openjfx/javafx-controls/11/javafx-controls-11.jar:/home/rm/var/maven/org/openjfx/javafx-controls/11/javafx-controls-11-linux.jar:/home/rm/var/maven/org/openjfx/javafx-graphics/11/javafx-graphics-11.jar:/home/rm/var/maven/org/openjfx/javafx-graphics/11/javafx-graphics-11-linux.jar:/home/rm/var/maven/org/openjfx/javafx-base/11/javafx-base-11.jar:/home/rm/var/maven/org/openjfx/javafx-base/11/javafx-base-11-linux.jar
com.io7m.javafxhello.Main

Am I doing something wrong? I feel like I've set things up the same way
as shown in the documentation.
--
Mark Raynsford | http://www.io7m.com
Johan Vos
2018-10-13 17:46:34 UTC
Permalink
The Java launcher (in the Java 11 JDK) checks if your main class extends
Application, and in that case it checks the module path and tries to find
javafx.graphics module. If you have that module on the classpath, but not
as a module, the launcher will exit with the message you see.

There are some workarounds (e.g. you can have a Main class that doesn't
extend Application that calls your Application), but the best approach is
go modular, as explained here:
https://stackoverflow.com/questions/52467561/intellij-cant-recognize-javafx-11-with-openjdk-11/52470141#52470141

- Johan
Post by Mark Raynsford
Hello!
Now that Java 11 is at general availability, I decided to give OpenJFX
11 a shot today. Unfortunately, I encountered the above error with an
Error: JavaFX runtime components are missing, and are required to run
this application
https://github.com/io7m/javafxhello
$ java -version
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)
$ mvn --version
Apache Maven 3.5.4 (NON-CANONICAL_2018-09-08T01:02:16+02:00_root;
2018-09-08T00:02:16+01:00) Maven home: /opt/maven
Java version: 11, vendor: Oracle Corporation,
UTF-8 OS name: "linux", version: "4.18.12-arch1-1-arch", arch: "amd64",
family: "unix"
If I try to run the program from the IDE (Intellij), the exact command
$ /usr/lib/jvm/jdk-11/bin/java
-javaagent:/usr/share/idea/lib/idea_rt.jar=34729:/usr/share/idea/bin \
-Dfile.encoding=UTF-8 \
-classpath
/home/rm/doc/dev/2018/10/javafxhello/target/classes:/home/rm/var/maven/org/openjfx/javafx-controls/11/javafx-controls-11.jar:/home/rm/var/maven/org/openjfx/javafx-controls/11/javafx-controls-11-linux.jar:/home/rm/var/maven/org/openjfx/javafx-graphics/11/javafx-graphics-11.jar:/home/rm/var/maven/org/openjfx/javafx-graphics/11/javafx-graphics-11-linux.jar:/home/rm/var/maven/org/openjfx/javafx-base/11/javafx-base-11.jar:/home/rm/var/maven/org/openjfx/javafx-base/11/javafx-base-11-linux.jar
com.io7m.javafxhello.Main
Am I doing something wrong? I feel like I've set things up the same way
as shown in the documentation.
--
Mark Raynsford | http://www.io7m.com
Mark Raynsford
2018-10-13 17:58:12 UTC
Permalink
On 2018-10-13T19:46:34 +0200
Post by Johan Vos
The Java launcher (in the Java 11 JDK) checks if your main class extends
Application, and in that case it checks the module path and tries to find
javafx.graphics module. If you have that module on the classpath, but not
as a module, the launcher will exit with the message you see.
There are some workarounds (e.g. you can have a Main class that doesn't
extend Application that calls your Application), but the best approach is
https://stackoverflow.com/questions/52467561/intellij-cant-recognize-javafx-11-with-openjdk-11/52470141#52470141
Ah, ok, thanks!

I'm an OSGi user and although the vast majority of the library code I
write is JPMS modularized, the application code I write almost
certainly won't ever be (because I use OSGi rather than the JPMS).

I'm fine with not extending Application - in fact I won't even have the
option to do so because OSGi applications don't have that traditional
main() method.

Is there documentation somewhere on the workaround you mentioned?
--
Mark Raynsford | http://www.io7m.com
Mark Raynsford
2018-10-13 18:29:41 UTC
Permalink
On 2018-10-13T19:46:34 +0200
Post by Johan Vos
There are some workarounds (e.g. you can have a Main class that doesn't
extend Application that calls your Application), but the best approach is
https://stackoverflow.com/questions/52467561/intellij-cant-recognize-javafx-11-with-openjdk-11/52470141#52470141
The following appears to work: Given an unsurprising subclass of
Application:

public final class ExampleApplication extends Application
{
private static final Logger LOG =
Logger.getLogger(ExampleApplication.class.getCanonicalName());

public ExampleApplication()
{

}

@Override
public void start(
final Stage stage)
{
LOG.info("started");

final Button button = new Button();
button.setText("Click");

final BorderPane pane = new BorderPane();
pane.setCenter(button);

final Scene scene = new Scene(pane, 640.0, 480.0);
stage.setScene(scene);
stage.setTitle("Example");
stage.show();
}
}

Then a main method that passes a class reference rather than allowing
the launcher to reflectively find the application:

public final class Main
{
private Main()
{

}

public static void main(
final String[] args)
{
/*
* Non-modular applications must specify the application class explicitly rather
* than allowing the launcher to use reflection to try to instantiate and start
* an application.
*/

Application.launch(ExampleApplication.class, args);
}
}

The application starts up and runs without issue.
--
Mark Raynsford | http://www.io7m.com
Loading...