Sunday, February 3, 2013

Native idea...

Hi there,

This will be a short blogpost about how to get native packaging up and running in IntelliJ Idea. Usually I used NetBeans to create native packages in JavaFX because it's so easy with NetBeans but it would be nice to be able to build the native package also in IntelliJ. Fortunately Thierry Wasyl blogged about how to create startable JavaFX jar files in IntelliJ Idea a few weeks ago so I just had to modify his work a bit to get also native packages out of a build.
In principle you just have to do the following:

1. create a Java project in IntelliJ Idea or use an existing one

2. go the 'Build' menu and select 'generate Ant Build...'

3. open the generated ant xml file and delete all content

4. copy the following content into the ant xml file

<?xml version="1.0" encoding="UTF-8"?>
<project name="PROJECT_NAME" default="default" basedir="." xmlns:fx="">

Project structure:
PROJECT_NAME/src              Sources folder
PROJECT_NAME/lib              Folder of external jar files
PROJECT_NAME/build            Folder for the output
PROJECT_NAME/build/classes    Folder that will contain the class files
PROJECT_NAME/build/dist       Folder that will contain the jar file
PROJECT_NAME/build/bundles    Folder that will contain the native package

    <property name="application.title" value="APPLICATION_TITLE"/>
    <property name="" value="VENDOR_NAME"/>
    <property name="java.home" value="${env.JAVA_HOME}"/>
    <property name="source.dir" value="src"/>
    <property name="lib.dir" value="lib"/>
    <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="out.dir.dist.lib" value="${out.dir.dist}/lib"/>
    <property name="" value="JAR_FILE_NAME.jar"/>
    <property name="main.class" value="PATH.TO.MAIN.CLASS"/>
    <property name="manifest.classpath" value="lib"/>
    <property name="manifest.externaljars" value="${manifest.classpath}/EXT_LIB1.jar ${manifest.classpath}/EXT_LIB2.jar"/>

    <path id="external.jars">
        <fileset dir="${lib.dir}" includes="**/*.jar"/>

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

    <target name="default">
        <taskdef resource="com/sun/javafx/tools/ant/antlib.xml"

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

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

    <target name="compile" depends="default, init">
        <javac srcdir="${source.dir}" destdir="${out.dir}/classes" classpathref="classpath"
               target="1.7" />
        <copy todir="${out.dir}/classes">
            <!-- Define all filetypes that you need in your project -->
            <fileset dir="${source.dir}">
                <include name="**/*.png"/>
                <include name="**/*.fxml"/>
                <include name="**/*.css"/>
                <include name="**/*.wav"/>
                <include name="**/*.ttf"/>
                <include name="**/*.otf"/>
                <include name="**/*.html"/>
        <copy todir="${out.dir.dist.lib}">
            <fileset dir="${lib.dir}">
                <include name="**/*.jar"/>

    <target name="build" depends="compile">
        <fx:application id="APPLICATION_TITLE" mainClass="${main.class}"/>

        <!-- Create the jar file -->
        <fx:jar destfile="${out.dir.dist}/${}">
            <fx:application refid="${application.title}"/>

                <attribute name="Implementation-Vendor" value="${}"/>
                <attribute name="Implementation-Title" value="${application.title}"/>
                <attribute name="Implementation-Version" value="1.0"/>
                <attribute name="Class-Path" value="${out.dir.dist.lib}"/>
                <attribute name="Main-Class" value="com/javafx/main/Main"/>
                <attribute name="JavaFX-Application-Class" value="${main.class}"/>
                <attribute name="JavaFX-Class-Path" value="${manifest.externaljars}"/>

            <fileset dir="${out.dir.classes}"/>

        <!-- Create the native package -->
        <fx:deploy verbose="true" width="200" height="400" nativeBundles="all" outdir="${out.dir.dist}" outfile="${application.title}">
            <fx:application name="${application.title}" mainClass="${main.class}"/>
                <fx:fileset dir="${out.dir.dist}" includes="*.jar"/>
                <fx:fileset dir="${out.dir.dist}" includes="lib/*.jar"/>
            <fx:info title="${application.title}" vendor="${}"/>

5. modify all the yellow marked text in the build xml file which should be self explaining

6. open the Ant Build area and add the build xml file by pressing the plus button

7. select the build entry and press play and after some seconds you should have a native package of your JavaFX application.

Please keep in mind that I'm running 7u13 on OS X which means the path to the jdk might be different on your machine. This build script is also able to add external jar files but therefor you have to put the external jar files in a "lib" folder that is at the same level as the source folder.

After the build is finished you should find a build folder that contains a classes folder which contains all the generated class files. In addition you will find a dist folder that contains the jar file and the lib folder with the external libs (jars)

In the dist folder you will also find a bundles folder that contains the native package and the setup program.

In my case it's the app folder and the dmg file.

You could also download the buildfx.xml file directly here.

I hope this was helpful for some of keep coding...

No comments:

Post a Comment