Java Web Start - load native dependency with another native dependency -


i using java web start launch java application depends on third party native libraries. these native libraries subsequently load native library (commonlib) dependency using loadlibrary/dlopen.

when not using web start, works expected when native libraries located in same directory.

web start, however, requires native libraries packed in jar file , referenced in jnlp file, did:

  <!-- windows os -->     <resources os="windows">         <nativelib href="native/native-windows.jar" />     </resource>    <!-- linux os -->     <resources os="linux">         <nativelib href="native/native-linux.jar" />     </resources>    <!-- mac osx -->     <resources os="mac os x">         <nativelib href="native/native-osx.jar"/>        </resources> 

the native libraries load fine fail load dependency commonlib - c++ loadlibrary/dlopen call fails because file present in jar/cache folder not on current library search path.

on windows, able solve problem pre-loading commonlib in java before trying load jni library, so:

system.loadlibrary("commonlib"); system.loadlibrary("mynativelib"); 

however, approach doesn't work on os x - dlopen in native code fails. dlopen apparently not smart enough not try load library again if loaded.

is there cross-platform way pack , load native libraries depend on other native libraries in java web start?

i able find (ugly) workaround. trick pack dependent libraries (commonlib) simple resource jar , add jnlp file:

... <resources os="windows">   <jar href="native/deps-windows.jar" /> </resources> <resources os="linux">   <jar href="native/deps-linux.jar" /> </resources> <resources os="mac os x">   <jar href="native/deps-osx.jar" /> </resources> ... 

step 2 extract these resources using java temporary directory:

string tmpdir = system.getproperty("java.io.tmpdir"); if (!tmpdir.endswith("/") && !tmpdir.endswith("\\"))     tmpdir += "/"; string resource = "commondir.dll"; // adjust accordingly current os, omitted brevity inputstream = loader.getresourceasstream(resource); if (is == null) {     // handle error - resource not found     return; } try {     fileoutputstream os = new fileoutputstream(tmpdir + resource);     byte[] buffer = new byte[1024*1024];     int len = is.read(buffer);     while (len != -1) {         os.write(buffer, 0, len);         len = is.read(buffer);     }     os.close();     is.close();     system.out.println("extracted " + resource + " " + tmpdir); } catch(ioexception ex) {     // handle exception - cannot write temp directory     system.out.println("could not extract resource " + resource + " " + tmpdir + ": " + ex.getmessage()); } 

step 3 either inform native jni library full path extracted dependency, or temporarily set current directory temp directory tmpdir, load jni library , set back. problem - in java hard change current working directory. may solve creating small utility jni library c though [1].


Comments

Popular posts from this blog

html5 - What is breaking my page when printing? -

html - Unable to style the color of bullets in a list -

c# - must be a non-abstract type with a public parameterless constructor in redis -