Skip to main content

Will the real JNI expert please stand up?

6 replies [Last post]
cowwoc
Offline
Joined: 2003-08-24
Points: 0

Hi,

Given an application that depends upon JNI library "jniLibrary.dll" which in turn depends upon "otherLibrary.dll" when one invokes System.loadLibrary("jniLibrary") two things happen:

1) Under normal applications, the system will complain it can't find dependent library "otherLibrary" because it isn't in the PATH. You can work around this by invoking System.loadLibrary("otherLibrary") first but I've been told System.loadLibrary() is only meant for JNI libraries and invoking it on any other library is not guaranteed to work.

2) Under Webstart applications, if you try loading "otherLibrary" first it will fail because of http://bugs.sun.com/view_bug.do?bug_id=6191612

There doesn't seem to be a "correct" way to fix this problem under all environments. Can someone please explain what the application should be doing in this case to ensure that "jniLibrary" loads correctly? Modifying the PATH is not an option because of the Webstart use-case (besides which, users don't appreciate it).

Thank you,
Gili

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
drdad5727
Offline
Joined: 2008-10-16
Points: 0

Is "otherLibrary" a system lib? (probably not, since its not in system32 or the load wouldn't fail). Do you have the source code for jniLibrary?

If you have the source code, try soft-loading otherLibrary, which will presumably be in the same directory you're in. (By JNI expert, do you mean C-programmer? There's nothing inherently JNI-ish about this problem.)

More easily, you can set the environment PATH variable programmatically. It will only affect your process. The user won't even know. Of course, that would have to happen in a 3rd .dll that gets loaded/called before jniLibrary.

mthornton
Offline
Joined: 2003-06-10
Points: 0

That won't work. Unfortunately WebStart hasn't even unpacked the other DLL and if it does it may not end up in the same directory.

drdad5727
Offline
Joined: 2008-10-16
Points: 0

Ok. So this isn't a JNI problem nor a C problem but a javaws problem with two parts:

How to get javaws to unload the dependent dll.
How to find out where it is.

I visited the bug report cited in the original post (I voted for it, too, but since it's four years old I doubt it'll do any good) and didn't see that doing the loadLibrary on the dependent library to get javaws to unload it wouldn't work for the first part. There's a trick I found on this forum for finding out where a library is. The trick is to use reflection (getDeclaredMethod) to get access to the findLibrary method of the class loader. That'll tell you where the library is.

This all relates to my post about "related-content". No one has told me what that jnlp entry is good for. It seems to me that this dependent library is just such related content.

john_burgess
Offline
Joined: 2005-08-19
Points: 0

For the webstart case, what you should do is pack all the dlls into a jar which should then be added to the resources.

cowwoc
Offline
Joined: 2003-08-24
Points: 0

> For the webstart case, what you should do is pack all
> the dlls into a jar which should then be added to the
> resources.

I'm not sure what "should then be added to the resources" refers to, but I have packed DLLs into dependent JARs before and it did not help. When you LoadLibrary("foo") the WebStart ClassLoader only extracts foo.dll into a temporary directory, not the entire JAR. As a result, foo.dll will never find its dependencies.

mthornton
Offline
Joined: 2003-06-10
Points: 0

In the absence of a JNI expert, my suggestions are:

1. Use some jni to modify the process library search path so that the location of otherLibrary.dll is included.

2. For WebStart use an installer to unpack the indirectly accessed libraries into a convenient location. Then have another component which checks the 'installed' version of these libraries and updates them as required.

All a bit messy, but at least your code will then run.