I am trying to call a JNI native function from my web application. In the past this has always worked, but I have had to change the way we work because we are adding an extra web application that also uses the same dynamic library. Sadly the library cannot be loaded in two separate class loaders.
In order to achieve this anyway, I have loaded the library in Tomcat 8's common class loader. I am using this answer as a template. I believe I have strong evidence that this is actually working. I am using this snippet to check if my libraries are loaded and to see in which classloader.
Classloader: java.net.URLClassLoader@26b418
Loaded:
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\zip.dll
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\management.dll
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\net.dll
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\nio.dll
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\sunec.dll
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\sunmscapi.dll
C:\Repositories\binaries\build\release\myAppJni.dll
Classloader: ParallelWebappClassLoader
context: myApp-display
delegate: false
----------> Parent Classloader:
java.net.URLClassLoader@26b418
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\zip.dll
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\management.dll
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\net.dll
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\nio.dll
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\sunec.dll
C:\Program Files (x86)\Java\jdk1.8.0_202\jre\bin\sunmscapi.dll
C:\Repositories\binaries\build\release\myAppJni.dll
This leads me to believe that my JNI-DLL is actually loaded in the entire application, and that it should be available to the web application and the other libraries that I use as dependencies.
However, when I try this. I get an UnsatisfiedLinkException that resembles this:
java.lang.UnsatisfiedLinkError: org.my.application.printer_create_handle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
at org.my.application.Printer.printer_create_handle(Native Method)
Which more or less resembles the behavior I see when I do not load the library at all.
When I step back to loading the library in a static block, everything seems to work correctly. But when I add a second application I get an already loaded in another classloader
message. This makes sense to me, but it doesn't get me any further.
I think I don't really understand how this works correctly. Can anyone shed some light on this?
The only way I can see to get around this is to deploy my library in Tomcat8's lib
directory but I would rather avoid this.