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
Post a Comment