Build JavaFX runnable JAR with IntelliJ IDEA (and Ant)

For years now I’ve been using NetBeans and I’m satisfied about it. But I wanted to give IntelliJ IDEA a try so I decided to test it by creating some JavaFX apps. And if you’re following the news, JetBeains has released IntelliJ IDEA 12. The thing is IntelliJ doesn’t have specific JavaFX features so I really wanted to see how to deal with it. Since JavaFX 2 is a part of the JDK 7 now, you won’t face any problem according like the JavaFX classes. The “problem” is I really have my habits on NetBeans and it is kind of difficult to throw them away. And one of my first problem was: how do I create a runnable JAR for my JavaFX app? Well I know the stuff about Ant tasks, the JavaFX packager in theory. But I didn’t had to really know them in details because NetBeans really does everything for you.
To be very clear: I won’t judge neither NetBeans, neither IntelliJ. Both have their pros and cons and both are great products. The subject here is really to focus on how to create a runnable JavaFX JAR in IntelliJ using Ant. And because I am really a newbie to IntelliJ, I hope this post could help others.

Configuration and tools

The configuration and tools that is used:

  • OS X Lion or Mountain Lion
  • Java 7u9 (with JavaFX 2.2.3)
  • IntelliJ IDEA 12 CE
  • Ant (shipped with the IDE)

The project I’m using is a simple project that you can grab here.

The Ant build script

First thing we have to do is to create the Ant build script. Go to Build > Generate Ant Build …
IntelliJ_Generate_Ant_build_script_01
Then create the script by giving it a name. I personally decided to make it as simple as possible.
IntelliJ_Generate_Ant_build_script_02
After that, I replaced the whole generated content of the build script by the following one:

<?xml version="1.0" encoding="UTF-8"?>
<project name="testerfx" default="default" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">

  <property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home"/>
  <property name="source.dir" value="src"/>
  <property name="out.dir" value="build"/>
  <property name="out.dir.classes" value="${out.dir}/classes" />
  <property name="out.dir.dist" value="${out.dir}/dist"/>
  <property name="app.jar.name" value="TesterFX.jar"/>

  <path id="classpath">
    <fileset dir="${java.home}/lib" includes="**/*.jar"/>
  </path>

  <target name="default">
    <taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
                 uri="javafx:com.sun.javafx.tools.ant"
                 classpath=".:${java.home}/lib/ant-javafx.jar"/>
  </target>

  <target name="clean">
    <delete dir="${out.dir}"/>
  </target>

  <target name="init" depends="clean">
    <mkdir dir="${out.dir}"/>
    <mkdir dir="${out.dir.classes}"/>
    <mkdir dir="${out.dir.dist}"/>
  </target>

  <target name="compile" depends="default, init">
    <javac srcdir="${source.dir}" destdir="${out.dir}/classes" classpathref="classpath"
               source="1.7"
               target="1.7" />
    <copy todir="${out.dir}/classes">
      <fileset dir="${source.dir}">
        <include name="**/*.png" />
        <include name="**/*.fxml" />
        <include name="**/*.css" />
      </fileset>
    </copy>
  </target>

  <target name="build" depends="compile">
    <fx:application id="TesterFX" mainClass="com.twasyl.testerfx.app.TesterFX"/>
    <fx:jar destfile="${out.dir.dist}/${app.jar.name}">
      <fx:application refid="TesterFX"/>

      <manifest>
        <attribute name="Implementation-Vendor"
                           value="Thierry"/>
        <attribute name="Implementation-Title"
                           value="TesterFX"/>
        <attribute name="Implementation-Version" value="1.0"/>
      </manifest>

      <fileset dir="${out.dir.classes}"/>
    </fx:jar>
  </target>
</project>

If you’re familiar with Ant, this is pretty easy: I define some basic targets for cleaning and compiling. The most interesting part is the target build. It is there that the final jar for our application is done using some new tags like:

  • fx:application that represents our JavaFX app, where you define the application class, the fallback one and so on ;
  • fx:jar that will create the final JAR by assembling the classes, convert CSS files into binary format if wanted and so son.

Of course there are other tags like fx:deploy, fx:signJar, etc. But here we only wanted to build a simple JAR without any particular configuration.

Try it

Once your build script is ready you just have to execute the build target to get your runnable JAR. To do so, at the right of IntelliJ click on Ant Build and then on the + in order to add your build script.IntelliJ_Generate_Ant_build_script_03
Choose your file:
IntelliJ_Generate_Ant_build_script_04
And then you will be able to execute targets you want.
IntelliJ_Generate_Ant_build_script_05

That’s it. I hope this could help you.

Useful resources