0

We have an app that sometimes is installed with an associated app. Both may be installed separately, at different times, and neither is usually in the OS Path environment setting.

IF both apps are installed, the one I'm working on needs to use a JNI library from the other app. This library uses a dozen or so other native libs. While I can FIND the JNI lib, I can't seem to find a way to use it without requiring the user to change their system setup.

I've found the (hacky) technique to add the JNI lib to the java.library.path, I've been unable to find any way of updating the native Path so the JNI lib can find it's associated libs.

The only things that have worked so far are to:

  1. Add the folder that the JNI and associated files are in to the OS path before launching our app.

  2. Launch our app so the Current Working Directory is the JNI lib folder.

Neither of which makes for a hassle-free user experience.

So, is there any way for a Java app to modify it's own environment Path so the JNI lib can find it's associated native libs? (currently testing on Win7, will also need to support OS/X)

CasaDelGato
  • 1,263
  • 1
  • 12
  • 29
  • isn't there a `system.load()` to use, i think i have used that before to load the jni `.so` files – jgr208 Nov 25 '14 at 16:18
  • I've already solved finding the jni library and loading it. I need to solve the issue of the native jni code being able to find associated libraries it depends on. – CasaDelGato Nov 25 '14 at 17:11

2 Answers2

0

This can not be done with an unknown location at run time. According to jni documentation

"To load your shared native library module in Java, simply use Java's System.loadLibrary method in a Java class:"

as well as

"Another common reason for the native library not loading is because it is not in your path. On Windows make sure the path environment variable contains the path to the native library. On Unix make sure that your LD_LIBRARY_PATH contains the path to the native library. Adding paths to LD_LIBRARY_PATH can slow down other programs on your system so you may want to consider alternative approaches. For example you could recompile your native library with extra path information using -rpath if you're using GNU, see the GNU linker documentation (ld man page). You could use a command such as ldconfig (Linux) or crle (Solaris) to add additional search paths to the default system configuration (this requires root access and you will need to read the man pages)."

So thus you need to know the location and must be in a path to be able to load the file. If the location is not known it can not be done due to how jni works and the jvm works.

jgr208
  • 2,896
  • 9
  • 36
  • 64
  • Apparently I was unclear. I don't know where the lib is until runtime, and it may not exist. So, I can't set a command line argument to point to it. Also note that I said that I've already SOLVED the java.library.path issue. I need to solve the OS issue of the native lib being able to find other native lib's it depends on. – CasaDelGato Nov 25 '14 at 17:08
  • well there is nothing you can do then. Java has to know the path when the jvm is created. See http://stackoverflow.com/questions/903530/how-should-i-load-native-libraries-for-jni-to-avoid-an-unsatisfiedlinkerror – jgr208 Nov 25 '14 at 17:11
  • Actually, the java.library.path is a solved issue. Java can find the JNI native library. The NATIVE library needs to be able to find associated NATIVE libraries. Nothing directly to do with the JVM. I was just hoping for some technique of updating the OS Environment the JVM is running in, so the native code can find other native code. – CasaDelGato Nov 25 '14 at 17:20
  • Then link the other library against the JNI library at compile time – jgr208 Nov 25 '14 at 17:22
  • They are. (and I don't build those and have no control over them.) On Win7, they still need to be able to FIND the other DLL's. Sounds like there is no way to update the environment the JVM is running in. PITA. – CasaDelGato Nov 25 '14 at 17:37
0

One way to load a JNI lib with dependent libraries is to load each of the dependents then load the JNI library.

For example, if bar.so is dependent on foo.so and both libraries exist in /some/dir, do the following:

System.load("/some/dir/foo.so");
System.load("/some/dir/bar.so");

Use System.load() instead of System.loadLibrary() so you can specify the absolute path to the library.

You'll have to load all dependents of all loaded libraries unless they can be found in the java.library.path path.

Hope this helps.

rg8443
  • 101
  • 1