alexb
alexb

Reputation: 470

Unable to deploy JavaFX applicaiton with external libraries in a JAR

I'm developing a JavaFX application in Eclipse. The app has external libraries, like log4j and others and runs perfectly from Eclipse. I've tried deploying it from Eclipse as a Runnable jar through the Eclipse built-in feature, and it runs well on some computers, while on others it would give me an obscure Undefined Link error. After digging around it seems JavaFX needs to be specially packaged either through an ANT script or through the javafxpackager application.

For the life of me I can't seem to deploy a runnable jar through either of those methods. Trying either of those methods, I get an Exception. Things I've tried:

  1. Build the JavaFX application through an ANT script, below is a snippet of the relevant parts of the build script

    <path id="classpath">
        <fileset dir="${lib.dir}" includes="**/*.jar"/>
        <fileset dir="${javafx.sdk.path}/jre/lib" includes="jfxrt.jar"/>
    </path>
    
    <target name="compile" depends="clean">
        <echo>Compiling the source</echo>  
        <mkdir dir="${classes.dir}"/>
        <!-- Copy over the misc files into the classes dir -->
        <copy todir="${classes.dir}/bundles">
           <fileset dir="${src.dir}/bundles"/>
        </copy>
        <copy todir="${classes.dir}/css">
            <fileset dir="${src.dir}/css"/>
        </copy>
        <copy todir="${classes.dir}/img">
           <fileset dir="${src.dir}/img"/>
        </copy>
        <copy todir="${classes.dir}/views">
           <fileset dir="${src.dir}/views"/>
        </copy>
    
        <copy todir="${classes.dir}/bundles">
           <fileset dir="${src.dir}/bundles"/>
        </copy>
    
        <copy file="${src.dir}/log4j2.xml" todir="${classes.dir}"/>
    
        <javac target="1.7" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" debug="on">
        </javac>
    </target>
    
    <target name="jar" depends="compile">
        <echo>Creating the main jar file</echo>  
        <mkdir dir="${distro.dir}" />
        <fx:jar destfile="${distro.dir}/main.jar" verbose="true">
            <fx:platform javafx="2.1+" j2se="7.0"/>
            <fx:application mainClass="${main.class}"/>
    
            <!-- What to include into result jar file?
                 Everything in the build tree-->
            <fileset dir="${classes.dir}"/>
    
            <!-- Define what auxilary resources are needed
                  These files will go into the manifest file,
                  where the classpath is defined -->
             <fx:resources>
                <fx:fileset dir="${distro.dir}" includes="main.jar"/>
                <fx:fileset dir="." includes="${lib.dir}/**" type="jar"/>
                <fx:fileset dir="." includes="."/>
            </fx:resources>
    
            <!-- Make some updates to the Manifest file -->
            <manifest>
               <attribute name="Implementation-Vendor" value="${app.vendor}"/>
               <attribute name="Implementation-Title" value="${app.name}"/>
               <attribute name="Class-Path" value="${lib.dir}"/> 
               <attribute name="Implementation-Version" value="1.0"/>
            </manifest>
        </fx:jar>
    </target>
    

Compiling/generating the jar through the ant script, I get a window pop up for half a second and "Exception in Application start method" in the console, with no stack trace. I've tried runnning java with the -XX:-OmitStackTraceInFastThrow flag, but it still won't give me a stack trace.

  1. Running through javafxpackager gives the following error:

    RenderJob.run: internal exception java.lang.UnsatisfiedLinkError: com.sun.prism.d3d.D3DContext.nSetBlendEnabled(JZ Z)I at com.sun.prism.d3d.D3DContext.nSetBlendEnabled(Native Method) at com.sun.prism.d3d.D3DContext.initState(D3DContext.java:84) at com.sun.prism.d3d.D3DResourceFactory.(D3DResourceFactory.java:5 7) at com.sun.prism.d3d.D3DPipeline.createResourceFactory(D3DPipeline.java: 147) at com.sun.prism.d3d.D3DPipeline.getD3DResourceFactory(D3DPipeline.java: 153) at com.sun.prism.d3d.D3DPipeline.findDefaultResourceFactory(D3DPipeline. java:179) at com.sun.prism.d3d.D3DPipeline.getDefaultResourceFactory(D3DPipeline.j ava:201) at com.sun.prism.GraphicsPipeline.getDefaultResourceFactory(GraphicsPipe line.java:97) at com.sun.javafx.tk.quantum.QuantumRenderer$3.run(QuantumRenderer.java: 143) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:47 1) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) at com.sun.prism.render.RenderJob.run(RenderJob.java:37) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor. java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor .java:615) at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(Quantu mRenderer.java:98) at java.lang.Thread.run(Thread.java:724)

Upvotes: 4

Views: 4442

Answers (3)

alistair
alistair

Reputation: 1172

With ant files you have two main options: <fx:jar> and <fx:deploy>. The former just produces a jar that allows you to refer to your dependencies if they are in the same file as the jar. You can unpack the jar and look at the MANIFEST file produced to see how they are added to the javafx classpath.

<fx:deploy> allows you to pull in dependencies, but requires that you build a platform-specific installer. It can't be done using a jar. Apparently NetBeans allows you to create a stand-alone jar but I have not tested with that.

Upvotes: 1

Marc
Marc

Reputation: 2639

You can deploy your application using javafxpackager. If you deploy a self contained application, the Java Runtime Environment will be bundled with your application and it will run on any machine whether the right version of Java is installed or not. (You should have javafxpackager in your jdk directory under the bin folder.)

  1. Look for your compiled files (.class) in your eclipse workspace folder. They should be in the bin directory.

  2. Create a createjar folder and inside it create a classes and a out folder. Copy all of your .class files in the classes folder. Also include in the classes folder all jar needed by your application.

  3. Now on the command line go inside the createjar directory and run this command :

    "C:\path\to\jdk\jdk1.7.0_25\bin\javafxpackager.exe" -createjar -appclass package.MainClass -srcdir classes -outdir out -outfile NameOfYourJar -classpath "" -v

This should create a runnable jar in the out directory. You will need it for the next step.

  1. Now create a deploy folder alongside the createjar folder.

  2. Inside the deploy folder make to other directories dist and packages.

  3. In the dist folder copy your freshly created jar from above plus all the dependencies/ressources it will need.

Go back on the command line (if you ever left it) and go in the deploy directory. Run the following command from there :

"C:\path\to\jdk\jdk1.7.0_25\bin\javafxpackager.exe" -deploy -native -outdir packages -outfile NameOfYourApp -srcdir dist -srcfiles NameOfYourJar.jar -appclass package.MainClass -name "Name of You Application" -title "Title of your application"

Once it is done it should have created all you need to deploy your app including native .exe file to run on Windows platform. This is the self contained application ! To be able to run it you need to go into bundles\NameOfYourApp\app and paste here all dependencies/ressource your app needs.

At last, double click on YourApp.exe and it should run even on machines without Java installed.

Upvotes: 3

tomsontom
tomsontom

Reputation: 5897

  1. you do not package javafxrt.jar with your app
  2. e(fx)clipse would have produced the ant-script for your if you use it

Upvotes: 0

Related Questions