How to create Apache Maven project with JavaFX and FXML support

If you want to create a maven project with JavaFX and FXML support, you are in the right place. Here is a simple guide.
We will prepare a simple maven project. You can download source code at the end of the post.

[wp_ad_camp_1]

Prerequisites

We have installed in computer:

Create maven project

At first create new maven Java Application project in your faworite IDE.


Modify pom.xml

Add property elements to the “<properties>” section

<javafx.version>2.2</javafx.version>
<exec.mainClass>org.korecky.myhavafx.App</exec.mainClass>

If you use different package or Main class you have to modify property “<exec.mainClass>”

To the “<dependencies>” section add JavaFX

<dependency>
    <groupId>com.oracle</groupId>
    <artifactId>javafx</artifactId>
    <version>${javafx.version}</version>
    <systemPath>${java.home}/lib/jfxrt.jar</systemPath>
    <scope>system</scope>
</dependency>

At the end of the “<project>” section add Build section. Modify only element “<finalName>” to the desired JAR file name.

<build>
    <finalName>MyJavaFX</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.5.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
            <!-- copy all dependencies of your app to target folder-->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.4</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <configuration>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                        <outputDirectory>${project.build.directory}</outputDirectory>
                    </configuration>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <descriptors>
                    <descriptor>src/main/assembly/jar-with-dependencies.xml</descriptor>
                </descriptors>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>${exec.mainClass}</mainClass>
                        <classpathLayoutType>repository</classpathLayoutType>
                    </manifest> 
                    <manifestEntries>
                        <JavaFX-Application-Class>${exec.mainClass}</JavaFX-Application-Class>
                        <Main-Class>${exec.mainClass}</Main-Class>
                        <JavaFX-Version>${javafx.version}+</JavaFX-Version>
                        <implementation-version>1.0</implementation-version>
                        <!--                            <JavaFX-Class-Path>
                        </JavaFX-Class-Path> -->
                        <!-- The artifactId (name) of the jfxrt.jar ... see dependency system scope--> 
                        <Class-Path>javafx-${javafx.version}.jar</Class-Path>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>   
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <configuration>
                        <target>
                            <!-- define the deploy ANT task-->
                            <taskdef name="jfxdeploy" 
                                     classname="com.sun.javafx.tools.ant.DeployFXTask"
                                     classpathref="maven.plugin.classpath" />
                            <!-- define the JarSing ANT task-->
                            <taskdef name="jfxsignjar" 
                                     classname="com.sun.javafx.tools.ant.FXSignJarTask"
                                     classpathref="maven.plugin.classpath" />

                            <jfxdeploy width="1024" height="768"
                                       outdir="${project.build.directory}/deploy" 
                                       outfile="${project.build.finalName}"
                                       nativeBundles="all">
                                <info title="${project.name}" />
                                <application name="${project.name}" mainClass="${exec.mainClass}" />
                                <resources>
                                    <fileset dir="${project.build.directory}" includes="*.jar" />
                                    <!--                                        <fileset dir="${project.build.directory}/dependency"
                                    includes="*.jar" />-->
                                </resources>
                                <!-- set your jvm args-->
                                <platform javafx="${javafx.version}+">
                                    <jvmarg value="-Xms512m" />
                                    <jvmarg value="-Xmx1024m" />
                                </platform>
                            </jfxdeploy>

                            <!-- you need to generate a key yourself -->
                            <jfxsignjar destdir="${project.build.directory}/deploy"
                                        keyStore="${basedir}/src/main/resources/keystore/javafx.ks" 
                                        storePass="password" alias="javafx"
                                        keyPass="password" >
                                <fileset dir="${project.build.directory}/deploy"
                                         includes="*.jar" />
                            </jfxsignjar>

                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>com.oracle</groupId>
                    <artifactId>ant-javafx</artifactId>
                    <version>${javafx.version}</version>
                    <systemPath>${java.home}/../lib/ant-javafx.jar</systemPath>
                    <scope>system</scope>
                </dependency>
                <dependency>
                    <groupId>com.oracle</groupId>
                    <artifactId>javafx</artifactId>
                    <version>${javafx.version}</version>
                    <systemPath>${java.home}/lib/jfxrt.jar</systemPath>
                    <scope>system</scope>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>    
</build>

[wp_ad_camp_1]

Fix JavaFX classpath problem

When you install the JDK currently, it includes JavaFX but does not put it on the classpath. To fix this, open a Command Prompt and type:

mvn com.zenjava:javafx-maven-plugin:1.3:fix-classpath

This will ask you to confirm that you want to do this, type “Y”.
You will need to do this only once for each development machine (and you will never need to do it on your users’ machines, only development ones).

Note: You have to run command prompt as Administrator on Windows machines

Create project structure

In JavaFX project are java classes stored in src/main/java and FXML, CSS, images, etc. in src/main/resources. There is example of these structure (base package is: org.korecky.myjavafx


│   pom.xml
└───src
    ├───main
        ├───java
        │   └───org
        │       └───korecky
        │           └───myjavafx
        │               │   App.java
        │               └───fxml
        └───resources
            └───org
                └───korecky
                    └───myjavafx
                        ├───css
                        ├───fxml
                        └───images

Key file for signing

For signing is used file generated with keytool named javafx.ks in a directory named keystore which is stored in “src/main/resources/keystore/javafx.ks”

Create directory “src/main/resources/keystore”. Run command prompt in this directory and in terminal run commands:

keytool -genkey -keystore javafx.ks -alias javafx
keytool -selfcert -alias javafx -keystore javafx.ks

Note: Don’t forgot modify password in element “jfxsignjar” in your pom.xml file!

Note: “keystore” should be placed in your home directory not in project

Done

You are now done.
You can write your code now.
If you would like download source code of this tutorial with simple FXML form, you can do that here:
Download Maven JavaFX example project

Resources

Resources which helped me wrote this guide:
From Zero To JavaFX In 5 Minutes
JFXMavenPkgExample
Thanks Carl J. Mosca for help with classpath problem.
[wp_ad_camp_1]

Leave a Reply

Your email address will not be published. Required fields are marked *