java - 无法从共享 Tomcat 类加载器中加载的库中调用本机函数
问题描述
我正在尝试从我的 Web 应用程序调用 JNI 本机函数。在过去,这一直有效,但我不得不改变我们的工作方式,因为我们正在添加一个额外的 Web 应用程序,它也使用相同的动态库。遗憾的是,该库无法在两个单独的类加载器中加载。
无论如何,为了实现这一点,我已经在 Tomcat 8 的通用类加载器中加载了该库。我使用这个答案作为模板。我相信我有强有力的证据表明这确实有效。我正在使用此代码段来检查我的库是否已加载并查看哪个类加载器。
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
目录中,但我宁愿避免这种情况。
解决方案
推荐阅读
- java - 如何从 cassandra 查询部分分页数据
- html - 当链接被分成多个 CSS 列时,悬停状态出现故障
- sql - 如何获取列的唯一值并使用 SELECT 将它们转换为新列?
- angular - 如何将 className 附加到投影内容?
- python - 烧瓶登录问题
- node.js - 我只能使用 .require() 来要求一个模块 - 有替代方案吗?
- python - 在 Numba 中嵌套类
- git - 在子模块中转换文件夹后,“以下未跟踪的工作树文件将被覆盖”
- owlready - 如果使用不同的命名空间,OWLREADY 2 无法加载本体
- vba - VBA Web Scraping- 抓取“hrefs”列表