I'm trying my hardest to export my javafx(11) projects, but nothing seems to work. I am on IntelliJ IDE, and for example let's use this project: https://github.com/EveningSt3r/JFX-hotel-project. (I wrote this in 30 minutes but it's simple and fills this question's purpose)
When I use IntelliJ's Build Artifacts function: "fx:deploy is not available" I have no idea how to use jlink, and all tutorials online are stumping me. Most javafx tutorials are from when it was part of the JDK, so that doesn't help. I have no idea how to use Maven and Gradle.
This is coming from a dude who doesn't have a great understanding of how Java actually works, just knows how to make stuff.
I've spent weeks trying to figure this out, so can someone please just dumb it down to baby levels for me, on how to get this into something runnable or an exe? I know I sound stupid but I'm just tired
One option is to use the jpackage
tool. That tool was an incubating feature in Java 14-15 and was standardized in Java 16. It creates a self-contained application. In other words, the resulting application contains not only your own code and any dependencies, but an embedded Java Runtime Environment (JRE) as well. That way your end users don't need to worry about having Java or JavaFX installed. Instead, they end up with a native installer/executable.
There is a user guide for jpackage
. There's also a script another user on this site (along with others, if I'm not mistaken) has created that may make things simpler for you: JPackageScriptFX.
Here is a minimal example of creating a JavaFX application, where the application is packaged with jpackage
, entirely from the command line. The example assumes a modular application (i.e. your code and all dependencies have a module-info
file), but jpackage
is also capable of packaging class-path based applications (i.e. non-modular applications).
├───out
│ ├───classes
│ └───package
└───src
└───com.example
│ module-info.java
│
└───com
└───example
└───app
Main.java
Note I have the source code under a directory named com.example
. That is the same name as the module and makes working with javac
manually easier (when compiling modules). However, you don't need to do that. In fact, if you're using an IDE then your source code is likely directly under src
(or src/main/java
if using Maven/Gradle).
Since you're likely letting your IDE compile the code I would not recommend creating a directory whose name matches the module name.
Here is the module-info.java
file:
module com.example {
requires javafx.controls;
exports com.example.app to javafx.graphics;
}
Here is the Main.java
file:
package com.example.app;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Main extends Application {
public void start(Stage primaryStage) {
StackPane root = new StackPane(new Label("Hello, World!"));
Scene scene = new Scene(root, 500, 300);
primaryStage.setScene(scene);
primaryStage.setTitle("JPackage Example");
primaryStage.show();
}
}
Here is the command to compile the above code. Note the working directory is the project directory.
javac --module-source-path src --module com.example -d out\classes
I have a JDK which includes JavaFX. If you do not then you need to make sure to put JavaFX on the module-path. For example:
javac --module-path <path-to-fx> --module-source-path src --module com.example -d out\classes
But again, you are likely letting your IDE handle compilation.
Here is the command to package the now-compiled application.
jpackage --type app-image --name JPackageExample --module-path out/classes --module com.example/com.example.app.Main --dest out/package
The --type
determines the application type. On Windows there's three options: app-image
(common to all platforms, I believe), exe
, and msi
. The first will simply create an exploded directory (containing a exe
file on Windows). The latter two will create Windows installers for your application. Note you must be on Windows to create Windows packages (same for MacOS and Linux).
The --module
argument tells the tool what the main module and class is (i.e. the entry point of the application). It's format is <main-module>[/<main-class>]
. The main class may be omitted if appropriate (e.g. you packaged your code into a JAR file with --main-class
specified).
Again, I have a JDK which includes JavaFX. If you do not then make sure to include JavaFX in the --module-path
argument, along with your own code. Important: Unlike during compilation, if you have JavaFX separate from the JDK then make sure to place the JavaFX JMOD files on the module-path, not the normal JAR files; you can get the JMOD files from Gluon (likely same place you got the JavaFX SDK). Keep in mind that JavaFX is platform-specific.
The above example is entirely from the command-line. You are likely using an IDE so some of the steps may be different. For instance, you can rely on the IDE to compile your code and, if you want, package it into a JAR file. You might even be able to let the IDE handle invoking jpackage
as well but I'm not sure.