Search code examples
javajna

JNA load multiple copies of the same library


I am using a C++ library that I load via JNA. I am trying to multi-thread my java program, but the C++ library is not threadsafe and making the library threadsafe is not a realistic option at the present. I know that you can only load one copy of a library in at a time, but I thought that if I copied the library file and had a copy for each thread, then I would be fine. However, I seem to be finding that this is not the case: here are two tests. The first loads a library, executes a method, loads a copy of the library, and executes the same method: it gives me an error. The second simply loads a library and executes the method twice, and it causes no problems.

Is it not possible to load two copies of the library even as two separate files (and if not, is there another way to do this?) The errors look like *** Error in `java': free(): invalid pointer: 0x00007feb9001eba0 *** The errors also always occur at the end of the test (it seems like the methods all work fine, and then when the test ends I get the error)

public class NativeLibraryTest {

    @Test
    public void test() throws IOException {
        final String libPath = "libjna.so";
        final MyLibrary library = Native.loadLibrary(libpath, MyLibrary.class);
        library.doThing();
        final String libPath2 = "libjna_copy.so";
        final MyLibrary library2 = Native.loadLibrary(libpath2, MyLibrary.class);
        library2.doThing();
        // get an error at the end of the test
    }

    @Test
    public void testSingle() throws IOException {
        final String libPath = "libjna.so";
        final MyLibrary library = Native.loadLibrary(libpath, MyLibrary.class);
        library.doThing();
        library.doThing();
        // no error
    }

}

Thanks


Solution

  • For JNI you can not load the same library more than once, even if it is renamed. The native method to be executed is identified only by it's name, the library name is ignored.

    If you want to to load two libraries you need two Java classes with distinct name or package location defining the JNI interface for each library. Then you have to created two implementations of the header file generated by the JNI compiler.

    Anyway depending on the implementation of the non-threadsafe library this may still cause trouble.

    IMHO the only safe way is to implement your application using multiple processes and then use inter-process communication. One main process and two worker process using the non-threadsafe library.