Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an .exe out of JavaFX application with built-in Java?

Tags:

java

javafx

I have a JavaFX application, I'm using it without modules (i.e. I deleted module-info file). The app is getting build with mvn clean package just fine and I can run it with java -jar myapp-with-dependecies.jar just fine. There's a Main class that runs my javafx app (lifehack to run javafx apps without modules, found on the internet):

public class Main {
  public static void main(String[] args) {
    DesktopApplication.main(args);
  }
}

These are my plugins in pom:

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.11.0</version>
        <configuration>
          <annotationProcessorPaths>
            <path>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
              <version>1.18.30</version>
            </path>
          </annotationProcessorPaths>
          <source>17</source>
          <target>17</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.1.0</version>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>my.Main</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.1.0</version>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>my.Main</mainClass>
            </manifest>
          </archive>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id> <!-- this is used for inheritance merges -->
            <phase>package</phase> <!-- bind to the packaging phase -->
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

I also found this configuration somewhere in the internet when searching how to make JavaFX run without modules. And obviously there are some files in my resources package, i.e. fxml files, css files and configuration file for hibernate.
Now you have a full understanding of structure of my project. Other than that, there are just dependencies for logic and my classes, that are not critical for my question, so you also have a reproducible example. These are my javafx dependencies:

<dependency>
      <groupId>org.openjfx</groupId>
      <artifactId>javafx-controls</artifactId>
      <version>19.0.2</version>
    </dependency>
    <dependency>
      <groupId>org.openjfx</groupId>
      <artifactId>javafx-fxml</artifactId>
      <version>19.0.2</version>
    </dependency>

My question is: how do I make an executable .exe file of my application now? I also want to include java in it, so client won't have to install java of needed version. What I tried so far:

  1. I used launch4j, and it creates an .exe file, but the problem is that it assumes the client has Java installed.
  2. I downloaded some project from github, that is already configured to easily create an exe with included java from JavaFX app. The problem is that I already have my project, and I don't want to transfer a lot of files to the new project just to build exe.

I think there should be a more clear way of how to do it, using some commands or something like that. Unfortunately, I didn't find a good step by step explanation of how to do it. So this is my question, if someone will enlighten me and tell me how to do it, I will appreciate that, thanks.
UPD: Just to make things clear, I'm using Linux and want to create .exe file for Windows. Is that possible?

like image 212
Arzybek Avatar asked Dec 29 '25 21:12

Arzybek


1 Answers

Preface:

This is not possible with standard things. You must build something by your own.

I can tell this is possible, because I did the same thing, but reverse. I use Windows and I executed the command in a Docker-Ubuntu-Container.

Solution 1, Part 1:

The best way to do this is by using jpackage.

Here is a direct link to the docs: https://docs.oracle.com/en/java/javase/14/docs/specs/man/jpackage.html

JPackage is a tool by Oracle theirself and is included in all newer JDKs.

Additional information:

Sometimes it is a bit tricky to create the need jpackage command.

I wrote an application that can create this command for you. After that you can execute this command with a wrapped Open JDK 17 or with a custom choosable JDK. Or you can edit, copy and execute it otherwise.

https://github.com/davidweber411/javafx-JavaFxProjectManager

You can create "portable exe applications which do not require Java installed" and an Installer If you want to - create desktop icon? create start Menü entry? Etc.

Solution 1, Part 2:

After part 1, you know the mechanics for "how to create a native executable".

JPackage is operating system dependent. You can only create EXE/MSI in Windows, DEB in Linux, etc. Especially JavaFX has extra Linux and extra Windows dependencies for example.

Your only option is to set up a Windows VM under Linux and execute jpackage from the VM. You can use Docker to setup a Windows Container.

Solution 2 (Experimental):

You could try to Install the JDK on Windows, copy it into your Linux System, and run the jpackage command with Wine. Maybe it is enough to Download the Windows JDK and extract it. JPackage.exe is located in the JDK.

like image 198
HelloThere12345 Avatar answered Dec 31 '25 11:12

HelloThere12345



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!