无法从共享的Tomcat类加载器中加载的库中调用本机函数

时间:2019-04-03 15:30:04

标签: java dll classloader tomcat8

我正在尝试从Web应用程序调用JNI本机函数。在过去,这一直有效,但是我不得不更改工作方式,因为我们要添加一个额外的Web应用程序,该应用程序也使用相同的动态库。遗憾的是,该库无法在两个单独的类加载器中加载。

无论如何,为了实现此目的,我已经在Tomcat 8的通用类加载器中加载了该库。我正在使用this answer作为模板。我相信我有充分的证据证明这确实有效。我正在使用this snippet检查我的库是否已加载并查看在哪个类加载器中。

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

这使我相信我的JNI-DLL实际上已加载到整个应用程序中,并且应该可供Web应用程序和用作依赖项的其他库使用。

但是,当我尝试此操作时。我收到一个类似于以下内容的UnsatisfiedLinkException:

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)

一点都不像我完全不加载库时看到的行为。

当我退回到在静态块中加载库时,一切似乎都能正常工作。但是,当我添加第二个应用程序时,会收到一条already loaded in another classloader消息。这对我来说很有意义,但并没有让我更进一步。

我认为我不太了解这是如何正常工作的。谁能对此有所启发?

我能解决的唯一方法是将我的库部署在Tomcat8的lib目录中,但我宁愿避免这种情况。

0 个答案:

没有答案