0

We can download the JavaFX jars for a particular version from

Let's focus on J17 [17.0.8] and Windows. Save the SDK to a local disk and look at, say, javafx.graphics in /lib. The file is of size 4,155kB.

We now include javafx.graphics as a Maven plugin and work our way to

...\.m2\repository\org\openjfx\javafx-graphics\17.0.8

where we see

  • javafx-graphics-17.0.8.jar (1kB) and
  • javafx-graphics-17.0.8-win.jar (5,736kB).

Notice the file size difference between the -win one and the one downloaded via Gluon's download page.

Why is this as we now a difference between the Gluon SDKs and a Maven plugin.

It gets worse.

I now want to ship these jars with my app, but which one's do I choose? I opt for Gluon's SDK versions but when I run the app that points to their jars I get the error:

Graphics Device initialization failed for :  d3d, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
        at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:283)
...

Hmmm .. the well-known JavaFX pipeline error. Ahh - maybe I forgot the dlls in the Gluon SDK /bin folder and so I add those as part of my 3rd-party libs. And I get the same runtime error.

So, I scrap the above and now ship the Maven jars (just the jars mind) and the ones that are a little bigger in size, and don't add any dlls. I have to go into each and every Maven local repo directory and ensure I pick out the correct ones. And hey-presto the app runs.

Now, to be strictly correct I keep with the artifactid-version style and drop the "-win" from the jars I ship. I mean - the "-win" isn't complete when one factors in the win, linux, mac, -x64, ... classifiers.

Is this what we supposed to do or am I missing something?

jewelsea
  • 150,031
  • 14
  • 366
  • 406
Graham Seed
  • 742
  • 3
  • 10
  • 24
  • 2
    See _packaging_ and _deployment_ in the [tag:javafx] tag [info](https://stackoverflow.com/tags/javafx/info). – trashgod Jul 24 '23 at 16:28
  • Do you a specific link? – Graham Seed Jul 24 '23 at 17:06
  • For "See packaging and deployment in the javafx tag info. ", do you have a specific link? – Graham Seed Jul 24 '23 at 17:17
  • 1
    Did you specify classifier in your maven dependency win? – user9035826 Jul 24 '23 at 18:12
  • Cj Y - Go through the steps I outlined and try to ship with the Gluon SDK Win jars and dlls and your app - it won't run. I do think there is something wrong with the 17.0.8 bin build. – Graham Seed Jul 25 '23 at 08:08
  • I just downloaded the 17.0.8 bin SDK and tried again using the provided jars and /bin dlls and once again it failed at runtime. Maybe it's my particular setup, Win10 or the application needs but jars+dlls does not work for me. The Maven jars - yes, but the SDK jars+dlls - no. – Graham Seed Jul 25 '23 at 14:58
  • Why is Win version of the SDK natives placed in a /bin folder but the Linux and Mac not? Do the Win jars point to the /bin dlls and the Linux and Mac not? Why the inconsistency? – Graham Seed Jul 25 '23 at 15:01
  • 1
    Answers to additional questions from comments are inline in my answer. – jewelsea Jul 25 '23 at 22:09

1 Answers1

2

For info on how to package your application for distribution, see:

This is a ridiculously long answer :( Sorry about that... just skim it for useful info if you need to.

In general, the linked official documentation is usually the best maintained and most useful source of info on developing JavaFX apps. When in doubt, rely on that rather than other sources on the net, including this one.

Answers to specific points in the question and comments

Notice the file size difference between the -win one and the one downloaded via Gluon's download page.

Why is this as we now a difference between the Gluon SDKs and a Maven plugin.

This is because the jars in the SDK don't include native components, but jars in Maven do.

I now want to ship these jars with my app, but which one's do I choose?

It is best not to ship the JavaFX jars with the app at all, but instead to ship a jlinked image or jpackaged app.

But if you must ship JavaFX jars, it is more convenient to ship the Maven ones because they include native components, and the JavaFX startup will ensure the native components are placed in a cache directory from which they can be loaded.

Otherwise, if you use jars from the SDK, you need to ensure that your installation also correctly copies all needed native components to a location that the JavaFX system can find them. Such a process is documented in the openjfx documentation in the section: "Runtime Images: Non-modular project: Command line", where it states in red:

Warning: This is a discouraged tedious error-prone manual process that should be avoided by using the Maven's shade plugin or the Gradle's jar task, in case jlink is not applicable.

I opt for Gluon's SDK versions

That is not recommended.

Is this what we supposed to do....?

No. No guide I know of recommends you to manually copy jar files from the maven repository or to manually copy jar files and dlls from the JavaFX SDK.

ship the Maven jars (just the jars mind) and the ones that are a little bigger in size, and don't add any dlls. I have to go into each and every Maven local repo directory and ensure I pick out the correct ones

You don't need to manually pick out jars from the local Maven repo. You can shade the components by following the instructions in "Runtime images: Non-modular project: Maven" or you can use the maven dependency or assembly plugins, to create a distribution bundle that includes the jars. The jars included can target a specific platform. Or you can include multiple classified jars in the build as documented in "Runtime images: Non-modular project: Maven: Cross-platform.jar"

to be strictly correct I keep with the artifactid-version style and drop the "-win" from the jars I ship.

IMO, it is not correct to drop the -win from the jar files, as the -win is a classifier and an important part of the name. In this case the classifier is used to differentiate the target OS (and in other cases also the CPU architecture) of the files in the jar.

I mean - the "-win" isn't complete when one factors in the win, linux, mac, -x64, ... classifiers.

Sure, that is why there are other classified jar files with different names for the other platforms.

Go through the steps I outlined and try to ship with the Gluon SDK Win jars and DLLs

Why though? That is not recommended.

Instead, study the runtime image section of the openjfx.io documentation.

FWIW, I did try this, and it worked. I followed the documentation on runtime images for packaging a non-modular JavaFX app from the command line using the JavaFX win x64 17.0.8 SDK and manually copying libraries from the SDK bin directory into a single bundled jar.

there is something wrong with the 17.0.8 bin build

As I was able to use the 17.0.8 SDK to assemble a running application on JavaFX win x64 17.0.8 SDK, I do not think there is an issue with that build of the SDK.

Why is Win version of the SDK natives placed in a /bin folder but the Linux and Mac not?

I don't know, the SDKs for the different platforms just have different directory structures. I don't think it is important or an issue.

Do the Win jars point to the /bin dlls and the Linux and Mac not?

Perhaps. I don't know, I'd need to search the jars and reverse-engineer the native library loading logic to find out, which I won't do at the moment.

But, even that aside, the JavaFX jars in the Windows SDK and the Mac SDK are significantly different in their contents, it is not just a matter of where and how they find native components.

Some differences in the javafx-graphics.jar are listed here.

Mac-specific Java classes, and GPU code for:

  • Mac accessibility support.
  • Mac cursors.
  • Mac menu bars.
  • Mac clipboards.
  • Mac UI automation robot.
  • Mac touchpad gestures.
  • Mac pulse timer.
  • Mac windows.
  • OpenGL ES2 interface.
  • OpenGL hardware accelerated shader code.
  • MacGL interface.

Win specific Java classes, properties, and D3Dcode for:

  • Translation string properties for various languages to support Windows accessibility settings.
  • Windows windows.
  • Windows dialogs.
  • Windows cursor.
  • Windows drag and drop.
  • Windows clipboard support.
  • Windows touch screen and gesture support.
  • Windows menus.
  • Windows UI automation robot.
  • Windows pulse execution timer.
  • D3D interface.
  • D3D hardware accelerated shader code.

So, basically, these files are very different.

  • The javafx-graphics.jar from the Windows SDK will only work on a Windows machine (when it is also provided matching versions of the required native libraries for Windows).
  • Similarly, the javafx-graphics.jar from the Mac SDK will only work on a Mac (with appropriate native components also supplied).

I just downloaded the 17.0.8 bin SDK and tried again using the provided jars and /bin dlls and once again it failed at runtime.

For reference, in case you want to compare with a working build: This was the setup I used, when following the openjfx instructions for packaging a non-modular JavaFX app from the command line:

>tree /F
├───libs
│       hellofx.jar
│
└───src
    └───main
        └───java
            └───hellofx
                    HelloFX.java
                    Launcher.java

Where the code comes from the repository mentioned in the instructions:

From the tree, I omitted the content of the intermediate output build directory which is created in the instructions to build the jar.

The app is run using:

java -jar libs\hellofx.jar

These are the dlls in the jar:

>jar tvf libs\hellofx.jar | findstr dll
 80384 Tue Jul 25 05:54:12 PDT 2023 decora_sse.dll
256000 Tue Jul 25 05:54:12 PDT 2023 glass.dll
 67584 Tue Jul 25 05:54:14 PDT 2023 javafx_font.dll
162304 Tue Jul 25 05:54:14 PDT 2023 javafx_iio.dll
 10752 Tue Jul 25 05:54:14 PDT 2023 prism_common.dll
155136 Tue Jul 25 05:54:14 PDT 2023 prism_d3d.dll
 55808 Tue Jul 25 05:54:14 PDT 2023 prism_sw.dll

The jar includes the entire JavaFX runtime in addition to the HelloFX app and Launcher classes, so there are many other items in the jar.

There are many dlls from the SDK which are not present in the app jar. This is because of the apps limited functionality. If the app used media components, for instance, it would require additional native code. Probably some dlls in the SDK are also used to support development of the JavaFX libraries themselves and aren't required at runtime.

If you have a more involved app using media or web components, I don't advise trying to figure out which dlls you do or do not need to manually copy and bundle with your application (as far as I can tell that isn't really documented anywhere), instead use one of the other recommended application packaging approaches.


The rest of this answer is an explanation of JavaFX runtime components required for application distribution. Ignore it if not interested or if it is not relevant for you

Given the question title is: "JavaFX RunTime Jars / Libs" and the question asks why the JavaFX jars in the Gluon SDK and Maven repository are different, I provide some explanation of these things here as I don't think they are explained in detail elsewhere.

What happens if native libraries are missing or misconfigured

To work, JavaFX requires that the correct JavaFX native libraries be placed on the java load library path.

Your JavaFX application will refuse to start with a message such as:

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

or:

Graphics Device initialization failed for : d3d, sw

You don't need to configure the java load library path directly or explicitly find and ship the native library files (raw .dll and .so files) if you correctly package your application distribution using a jlinked runtime built from the JavaFX jmods, or the appropriate classified JavaFX jars from Maven central. So, you will only see the above messages if you incorrectly created your runtime distribution or tried to run it on an incompatible platform.

JavaFX distribution requirements

To use JavaFX you need:

  1. Compiled JavaFX Java code and resources.
  2. Compiled JavaFX native libraries for your target OS and architecture.
  3. A compatible Java runtime for your target OS and architecture.

JavaFX distribution sources

JavaFX distributions can be obtained from these sources:

  1. The Gluon JavaFX SDK.
    • choose the type "SDK".
  2. The Gluon JavaFX jmods.
    • choose the type "jmods".
  3. Maven central, by including the JavaFX jars as dependencies using a compatible build tool
    • e.g. Maven or Gradle.
  4. A JDK or JRE version that includes JavaFX.

Gluon JavaFX SDK

Compiled JavaFX Java code and resources.

Included in the jar files that ship with the JavaFX SDK.

Compiled JavaFX native libraries for your target OS and architecture.

When you download the JavaFX SDK, you choose a target OS and architecture. The JavaFX SDK will include the JavaFX native libraries as separate native library files, e.g., .dll or .so files for the OS and architecture type you selected for the download.

The JavaFX native libraries are not included in the jar files that ship with the JavaFX SDK.

A compatible Java runtime for your target OS and architecture.

Must be obtained separately from a JDK provider (e.g. OpenJDK for Eclipse Temurin distributed by Adoptium).

Use in distribution packaging

The SDK is not well-suited to packaging JavaFX applications for distribution.

Purposes of the SDK

  • Development of the JavaFX platform itself.
  • Development of JavaFX applications when not using a build tool (such as Maven or Gradle, or not using a JDK which includes JavaFX).

Gluon JavaFX jmods

Compiled JavaFX Java code and resources.

Included in the jmod files from the Gluon JavaFX jmod distibution.

Compiled JavaFX native libraries for your target OS and architecture.

When you download the JavaFX jmods, you choose a target OS and architecture. The JavaFX jmods will include (inside the jmod files) the JavaFX native libraries for the OS and architecture type you selected for the download.

A compatible Java runtime for your target OS and architecture.

Must be obtained separately from a JDK provider (e.g. OpenJDK for Eclipse Temurin distributed by Adoptium).

Use in distribution packaging.

The jmods can be:

  • linked into a Java runtime image using the JavaFX linker

Purposes of the jmods

  • Can be used to compile your application against, using javac.
  • Linking JavaFX into a custom JDK or JRE, so the custom JDK or JRE will include JavaFX.
  • Linking a JDK or JRE with your application and JavaFX components to create a custom runtime image for distribution.

jmods can not be directly added to the module path at runtime using the java command. Instead, for their functionality to be available at runtime, they must be linked into an image using jlink.

JavaFX jars in Maven central

Compiled JavaFX Java code and resources.

Included in the maven JavaFX jar files.

Compiled JavaFX native libraries for your target OS and architecture.

Included in the maven JavaFX jar files.

Maven hosts multiple versions of the JavaFX jar files, each including native components for a given target OS and architecture.

The Maven classifier concept allows the choice of a given classified version of an artifact to use as a dependency for the application.

The JavaFX Maven jars are configured to use a default classifier based on the OS and architecture you are executing your build on. So, you don't need to explicitly specify the classifier for Maven to obtain the jar files matching your build OS and architecture. It is advised not to specify a classifier, unless you need to obtain Maven jar files for versions of the code which do not match your build OS and architecture.

When you run a JavaFX application, the JavaFX Java code will instruct the runtime on how to find the native components. For the JavaFX maven jars, it will extract the native libraries from the jars to a temporary directory which is placed on the Java load library path for native libraries. That is what allows the Java runtime to find the runtime components for Java when Maven jars are used as dependencies.

A compatible Java runtime for your target OS and architecture.

Must be obtained separately from a JDK provider (e.g. OpenJDK for Eclipse Temurin distributed by Adoptium).

Use in distribution packaging.

Using jlink or jpackage tools in the JDK, the JavaFX maven modules can be linked into an application runtime distribution. This can be done without using the JavaFX jmods. The jmods are probably a better thing to link, but it is unlikely that users will notice potential performance differences between linking the JavaFX maven jars or linking JavaFX jmods.

The linking can be performed:

  • natively from the command line OR
  • via a third-party plugin
    • maven javafx-maven-plugin.
    • gradle badass-jlink-plugin or badass-runtime-plugin.

Also, a single jar file can be created from the JavaFX Maven jars:

Alternatively, a zipped multiple jar distribution of a JavaFX application.

  • created by custom assemblies (probably preferred to the unsupported fat jar config), that include classified jars in a zip distribution with a script for execution (using the maven assembly and dependency plugins).

Purposes of the Maven jar files

  • Development of JavaFX applications when using a build tool (such as Maven or Gradle).
  • Creation of a native distribution package for a JavaFX application.
  • Creation of a single fat-jar distribution for a JavaFX application.
  • Creation of a zip file of multiple jars and execution shell script for a JavaFX application.

A JDK or JRE version that includes JavaFX

Compiled JavaFX Java code and resources.

Included in the Java jmods that ships with the JDK or JRE.

Compiled JavaFX native libraries for your target OS and architecture.

When you download a JDK or JRE that includes JavaFX, you choose a target OS and architecture. The JDK or JRE can include the JavaFX native libraries in jmod files for the OS and architecture type you selected for the download, allowing you to link against them to create a custom runtime.

A compatible Java runtime for your target OS and architecture.

The downloaded JDK or JRE is a compatible Java runtime, you don't need another.

Use in distribution packaging.

Assembly of JavaFX applications for packaging:

  • uses the jlink or jpackage tools in the JDK
  • the JDK linking and packaging can be accessed via 3rd party build tool plugins if needed.
  • jlink assembled distributables for multiple OS and architecture platforms can be built by downloading and linking JREs for the different OSes and architectures.

Purposes of a JDK or JRE which includes JavaFX

  • Development of JavaFX applications with or without a build tool.
  • Assembling native JavaFX application distributables for multiple target OSes and architectures.

FAQ

What if I want an Installer?

jpackage can be used to create a native installer for your application. Its usage is complicated and outside the scope of this answer.

What are modules?

Understand java modules.

What is a jmod and a jimage, why not just a jar?

This answer discusses the differences between jmod, jar and jimage file formats and their purposes.

Why not just use a fat jar?
  • Fat jars including JavaFX modules are not a supported configuration.
    • It can be made to work though (as of JavaFX 20).
    • It places JavaFX on the classpath, not the modulepath using an unsupported hack of the JavaFX launching system (launching from a separate class from the JavaFX Application class).
  • It is harder to create a usable fat jar than a zipped jlink image (IMO).
  • It is more difficult for the users of your application than a jlinked image or jpackaged installer as the users need to, independently and correctly, obtain a compatible Java runtime and use the correct execution command to run your application using that runtime.
My app uses non-modular or automatic module dependencies, can I use jlink?

No, but you can use jpackage (which is more complex).

Oh god, this is so complex, I just want somebody to use my app.

The easiest solution, IMO, for single-platform modular apps, is to use the javafx-maven-plugin jlink target to link and zip the JavaFX maven modules and your app, if that fits your requirements.

Unfortunately, this approach will not fit all requirements. Other options, such as native installers using jpackage are possible, but trickier and more complex (especially if you need to target multiple platforms, such as Macs, Linux, and Windows).

jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • @trashgod Yes, thanks. I didn't finish writing the info on jmods (and it was wrong). jmods can only be used for compilation and linking and can't be placed on the module path at runtime using the `java` command. To be used at runtime, they must first be linked into a new runtime image using `jlink`. I updated the information in the answer to correct it. – jewelsea Jul 26 '23 at 18:12