I have written a JavaFx 2 application (using Eclipse on a Windows platform) and now I want to deploy it to a "clickable" jar-file. My application uses resource-code from a separate jar-file (in Eclipse, this resource code is a separate Project from the JavaFx application project).
With my Ant build.xml, I have compiled the code for both the application and the resource code and created two jar-files:
As a last step (I thought), using the JavaFX Ant tasks, I wanted to bundle these two jar-files to a "clickable" jar that starts my JavaFX application. I tried doing just that with the below extract from my build.xml.
<target name="deployFx" depends="fxdemo.jar" description="Releases FxDemo">
<taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
uri="javafx:com.sun.javafx.tools.ant"
classpath=".:${fxgui.javaHome}\lib\ant-javafx.jar"/>
<copy file="${fxgui.lib_guifw_path}" tofile="delivery/lib/guifw.jar"/>
<fx:application id="FxDemoGUI" name="Fx Demo GUI" MainClass="com.demo.main.MainGUI"/>
<fx:resources id="jars">
<fx:fileset dir="delivery/lib" includes="fxdemo.jar"/>
<fx:fileset dir="delivery/lib" includes="guifw.jar"/>
</fx:resources>
<fx:jar destfile="deploy/fxDemoGui.jar">
<!-- Define what to launch -->
<fx:application refid="FxDemoGUI"/>
<fx:platform javafx="2.1+">
<fx:jvmarg value="-Xms32m"/>
<fx:jvmarg value="-Xmx32m"/>
<property name="com.util.fxguifw.setup" value="com/util/fxguifw/demo/demo.properties"/>
<property name="user.language" value="en"/>
<property name="user.country" value="GB"/>
<property name="CSS_ID" value="NIGHT"/>
</fx:platform>
<fx:resources>
<fx:fileset dir="delivery/lib" includes="fxdemo.jar"/>
<fx:fileset dir="delivery/lib" includes="guifw.jar"/>
</fx:resources>
<manifest>
<attribute name="Implementation-Vendor" value="${fxgui.vendor}"/>
<attribute name="Implementation-Title" value="${fxgui.title}"/>
<attribute name="Implementation-Version" value="1.0"/>
</manifest>
<fileset dir="delivery"/>
</fx:jar>
However, afterwards when I try to start the application (by either clicking the jar or starting from command line with java -jar appname.jar) it seems as the application can not find the Main class:
JavaFX Launcher Error
Unable to find class: com.demo.main.MainGUI
C:\Program Files\Java\jdk1.7.0_09\bin>java -jar C:\MEKMAN\Clearcase_Views\wmarekm_ss_gambau\amb_c2_prototype\javafx\prototypeGUI\deploy\fxDemoGui.jar
java.lang.ClassNotFoundException: com.demo.main.MainGUI
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at com.javafx.main.Main.getAppClass(Main.java:506)
at com.javafx.main.Main.launchApp(Main.java:622)
at com.javafx.main.Main.main(Main.java:805)
When I studie the created MANIFEST.MF (in the created jar-file) it looks pretty much as what I expected.
Manifest-Version: 1.0
JavaFX-Version: 2.1+
implementation-vendor: MyVendor
implementation-title: MyfirstJavaFxDeploy
implementation-version: 1.0
JavaFX-Application-Class:com.demo.main.MainGUI
JavaFX-Class-Path: fxdemo.jar guifw.jar
Created-By: JavaFXPackager
Main-Class: com/javafx/main/Main
... but then again, it doesn't work so obviously I have done something wrong.
I also tried including the classes-directory (the output folders from each of the two Eclipse/projects) by adding:
<fileset dir="../guifw/classes"/>
<fileset dir="classes"/>
Then, the launcher does find my main class (com.demo.main.MainGUI) but failes to run correctly because it lacks the -D argument that I tried to specify with:
<property name="com.util.fxguifw.setup" value="com/util/fxguifw/demo/demo.properties"/>
So, if you have read this far, my questions are:
Best regards
I studied/tested the fix presented in post (2012-apr-12 03:32) in the link from @Anders Petersson:
Link from @Anders Petersson
From what I can see, this is a workaround that unbudles any used jar-file (in my case; guifw.jar & demofx.jar) within the resulting jar file (fxDemoGui.jar), much like adding the classes-folders from my two Eclipse-projects (as described in the question).
I adjusted the example to my build.xml and got it to work after one slight addition:
<target name="dist" depends="fxdemo.jar">
<taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
uri="javafx:com.sun.javafx.tools.ant"
classpath=".:${fxgui.javaHome}\lib\ant-javafx.jar"/>
<copy file="${fxgui.lib_guifw_path}" tofile="delivery/lib/guifw.jar"/>
<fx:jar destfile="predeploy/fxDemoGui.jar">
<!-- ADDITION -> Adds the Launcher's Main class to the resulting jar (com.javafx.main.Main)! -->
<fx:application id="FxDemoGUI"
name="Fx Demo GUI"
mainClass="com.demo.main.MainGUI"/>
<fileset dir="delivery"/>
</fx:jar>
</target>
In the dist-target from the example, I had to add:
<fx:application id="FxDemoGUI"
name="Fx Demo GUI"
mainClass="com.demo.main.MainGUI"/>
Without it, the resulting jar-file did not have the necessary com.javafx.main.Main-class and hence, failed to start.
So, this solution presents a useful workaround for my question 1)
Still, I'd be grateful if anyone comes up with a solution on how to keep the jar-files intact within the resulting jar/file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With