Search code examples
javajavafxjnlpjava-web-start

Starting JavaFx application via jnlp WebStart - not loading system native libraries defined in jnlp descriptor


I'm developing a JavaFX application which uses a webcam. To be able to access camera, I was forced to use opencv libraries and javacv which uses native opencv shared libs. Now I want the native dlls to be installed somehow on user machine so that java can use them. I read the whole ant tasks reference for javafx and found an example which is an explanation how to add native system libraries to application package to make it work. I'm using netbeans to build javafx application package. Here is how I'm customizing build.xml file used by netbeans to build app.

 <import file="nbproject/build-impl.xml"/>


<target name="-post-jfx-jar" depends="-check-jfx-sdk-version">
   <echo message="Embedding native libraries..."/>
      <fx:jar destfile="${basedir}/build/native-libs-win-x86.jar">
        <fx:fileset dir="${basedir}/natives/windows/x86" includes="*"/>          
      </fx:jar>              
      <fx:jar destfile="${basedir}/build/native-libs-win-x64.jar">
         <fx:fileset dir="${basedir}/natives/windows/x64" includes="*"/>    
      </fx:jar>
   <echo message="Natives embedded..."/>           
</target>
<target name="-post-jfx-deploy" depends="-post-jfx-jar">
   <echo message="deploying ..."/>
     <fx:deploy width="600" height="400"
                outdir="${basedir}/${bundle.outdir}"
                outfile="AppName">
            <fx:info title="AppName"/>
            <fx:application name="${bundle.name}"
                            mainClass="pl.company.project.EntryClass"/>
            <fx:permissions elevated="true"/>
            <fx:resources>

                <fx:fileset dir="dist" includes="*.jar"/>
                <fx:fileset dir="dist/lib" includes="*.jar"/>


                <fx:fileset dir="build" type="native"
                            os="windows" arch="x86"
                            includes="native-libs-win-x86.jar"/>

                <fx:fileset dir="build" type="native"
                            os="windows" arch="x64"
                            includes="native-libs-win-x64.jar"/>

            </fx:resources>
     </fx:deploy>       
</target>   

Now when I execute clean and build in netbeans, I'm getting a folder with set of jars which are my project dependency jars, one jnlp, html, executable jar, and also the two jars which have dll libraries embedded. One jar is native-libs-win-x64.jar and the second is native-libs-win-x86.jar. Native libraries are in top level - so in each jar we have set of dlls and META-INF folder with manifest containing: Manifest-Version: 1.0, Created-By: JavaFX Packager, Main-Class: null

Jnlp file also contains following entries:

 <resources os="windows" arch="x86">    <nativelib href="native-libs-win-x86.jar"/></resources>

and

Now when I start the jnlp, native libraries are not loaded, UnsatisfiedLinkError is raised. But when I unpack jars with dlls into the folder where executable jar, dependencies and jnlp are, everything works like a charm. So my question is.. what am I missing ? I've done everything as it was shown in ant task guide on JavaFX documentation pages.


Solution

  • To be specific, and follow rules of stackoverflow, I'm giving details on how I've managed to solve my problem:

    Java can be able to load native libraries specified in jnlp descriptor easily but we have to:

    1) Provide correct arch attribute value in resources element- Note that this value is taken from system variable os.arch and its not always x64 on 64 bit architecture or x86 on 32 bit. In my case I have to provide amd64 value.

    2) You jar file pointed by href attribute has to contain all native libraries, and all of them have to be in the top level of jar file.

    3) Also os attribute starts with upper case - for me it doesnt work if I provide is="windows" it must be os="Windows"