In Eclipse, how do you create an .exe file of your project

195 Views Asked by At

Been stuck on this for 3 days. My app uses JavaFX and it runs perfectly fine when I press the "Play" button. I want to create a runnable .exe file. Here is the pom.xml of my project:

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.schematix</groupId>
    <artifactId>schematix</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    <description>Building electricity calculator</description>
    <url>http://maven.apache.org</url>

    <properties>
        <runtime.version>7.0.0.Final</runtime.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.12.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>20.0.1</version>
        </dependency>

    </dependencies>

    <build>
        <sourceDirectory>src</sourceDirectory>

        <resources>
            <resource>
                <directory>src/resources</directory>
            </resource>
        </resources>

        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

I have the Compiler Compliance Level set to 17.

I created a JAR file like this: Right-click on my project in Project Explorer, select Export, select Runnable JAR file, click Next, select Extract required libraries into generated JAR and choose the correct Launch configuration (Main - schematix) and an export destination.

I then opened the Launch4j program, and in the Basic tab added the output .exe file's destination, selected the Jar file, selected a .ico file for the icon. I also went to the JRE tab and set the min JRE version to 17. That's all I did. I then pressed the Build wrapper button and it generated the .exe. When I try to run that .exe using the Test wrapper button in Launch4j I get the following error:

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

1

There are 1 best solutions below

4
On BEST ANSWER

Preface:

Eclipse can't do that out of the box and launch4j is not really good. Use one of Oracles applications called "jpackage" instead to do this. Or "jlink".

You need to create a fat JAR. A fat JAR is a JAR, which contains all needed dependencies additionally to the standard JDK dependencies. JavaFX dependencies are not part of the standard anymore, so you have to create a fat JAR.

I posted the same answer here and it worked: EXE using launch4j does not work (javafx project), JAR files need to be ran from the console specifying the VM argument of the javafx location

Example working JavaFX application with gradle and fat JAR task:

https://github.com/davidweber411/JavaFxAppGradleNonModular

Example working JavaFX application with maven and fat JAR goal:

https://github.com/davidweber411/JavaFxAppMavenNonModular

Example pom.xml for creating a fat JAR with the shade plugin:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>your.groupId</groupId>
    <artifactId>JavaFxAppMavenNonModular</artifactId>
    <version>1.0.1</version>
    <name>JavaFxAppMavenNonModular</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.8.2</junit.version>
        <mainclassnameparam>your.groupid.javafxappnonmodular.MainApplicationLauncher</mainclassnameparam>
    </properties>

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

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running with: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>${mainclassnameparam}</mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <shadedArtifactAttached>true</shadedArtifactAttached>
                            <transformers>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>${mainclassnameparam}</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Create EXE out of fat JAR:

You can use jpackage for this. It is very easy to use. https://docs.oracle.com/en/java/javase/17/docs/specs/man/jpackage.html

Create EXE/MSI with an external application:

You need JDK 17 installed.

This application allows you to configure an icon, installer, etc. in a simple GUI. It creates the needed jpackage command for you, which you can just copy and execute it local, OR you can execute the command in the wrapped JDK 17.

https://github.com/davidweber411/Java2NativeWinConverter

How to Install?

  1. Clone this repository

  2. Navigate to the project

  3. Execute the gradle task "createCustomFatJar".

    Windows: .\gradlew createCustomFatJar

  4. Double click on the created fat JAR.