Is it possible to load different versions of the same DLL in Java?

I have a JNI library that interacts with a set of third-party libraries, and there can be more than one version of a third-party library in the system. For each version of the third-party library, I have to recompile the JNI code for reasons of comparability. I am currently doing this by loading a DLL with a specific name, and if a version change changes the names of the JNI DLLs, so the correct version has the correct name to load.

I would like to be able to dynamically load the dll, but based on the version that the user wants to use. What happens if I call System.loadLibrary twice in a DLL with different names but with the same method signatures?

System.loadLibrary("JNIv1"); // Same code compiled against a different third party version System.loadLibrary("JNIv2"); 

I need to use only one of the versions at a time, so it’s great if the old version is no longer available.

Is it possible to load two different versions of a DLL with the same method signatures without restarting the program?

+6
java jni
source share
3 answers

It is possible and actually fully supported and works brilliantly.

I had to do this in a production environment, and in the sun the JVM is a solid.

Basically, if you load a library from another classloader, then it will load another copy of the library. It is so simple.

I would not recommend doing this unless you really need to ... but it works.

Alternatively, depending on your specific requirements, you can simply exclude it from the process and have a simple protocol (using say jetty / xstream / httpclient or netty) between the client and different servers, each of which has a different version of the dll.

This is essentially due to the fact that you are writing a class loader

 public class MyClassLoader extends URLClassLoader { protected String findLibrary(String libName) { if ( libName.equals("mylib.dll")) { return "full/path/to/library"; } else { super.findLibrary(libName); } } } 

Then you organize the loading of your class implementation using the appropriate class loader ...

 public interface Implementation { } public class ImplementationLookerUpper { Classloader v1 = new MyClassloader(version1); Classloader v2 = new MyClassloader(version2); public Implementation implementationUsingVersion(Version someversion) { Classloader classloader = pickCorrectClassLoaderForVersion(someVersion); return (Implementation) classloader.loadClass(RealImplementation.class.getName()).newInstance(); } } 

That kind of thing .....

+3
source share

This is not safe and pretty messy to implement. It is possible to have different class loaders for different dll versions. You will need to make sure the class loader is loaded with garbage to make sure the dll is unloaded. (See Java JNI - DLL Unloading )

In the past, we solved this problem by writing a lightweight java middleman process that processes a user request and creates a new child Java process with the requested version of the DLL. When the user requests a different version, the mediator disconnects the existing child and creates a new one with a different library path. This approach works well. The only drawback is the time taken to launch the new JVMs, but this will only be noticeable if you have a lot of version switching requests very often.

+1
source share

I don’t know the details of how the DLL works in windows, but my gut feeling tells me that it is definitely unsafe to have overlapping libraries at the same time. But, perhaps if you first unload the first, perhaps it will.

As far as I can see, there is no way to explicitly unload the library. If you look at java.lang.Classloader.NativeLibrary, you will see that the library is unloaded when the classloader that caused it to load gets the garbage collection (in the finalize () method). Therefore, if you load it into a separate class loader, and then wait for it to be garbage collected (with some malicious calls to System.gc () so that this happens faster) before loading a new one, which might help.

0
source share

All Articles