.dll已经加载到另一个类加载器中了?
我有一个在Tomcat 3.2.1下运行的Web应用程序,需要进行JNI调用才能访问传统C ++代码中的数据和方法。 在webapp启动时加载一个servlet,作为init
方法的一部分,它使得一个特定于该webapp实例的数据集被加载到C ++数据结构中。
这个servlet的Java代码包含以下内容:
static { try { System.loadLibrary("JCoreImpl"); System.out.println("JCoreImpl loaded"); m_bLibraryLoaded = true; } catch (UnsatisfiedLinkError e) { m_bLibraryLoaded = false; System.out.println("JCoreImpl NOT loaded " + e); } }
事情工作正常,如果只有一个Web应用程序(我们称之为“webapps / aaa”)。
如果除了C ++数据结构中使用的数据集之外,还有另一个与webapps / aaa相同的webapp(“webapps / bbb”),那么webapps / aaa启动就好了,但是当webapps / bbb启动时,一个错误,指出:
JCoreImpl NOT loaded java.lang.UnsatisfiedLinkError: Native Library E:\WebStation\binDebug\JCoreImpl.dll already loaded in another classloader
我需要为我的每个webapps有一个独立的本地库实例,因为每个实例都需要包含该webapp独有的数据。 我已经通过邮件存档search并阅读Craig McLanahan解释类加载器层次结构的电子邮件。 但我一直无法find任何具体的加载每个Web应用程序的本地库的唯一实例。
您不能加载相同的本机库两次。
把这个类放在/ lib /下的一个jar文件中,它将在所有的战争中共享。
在Tomcat HowTo wiki上使用Tomcat 下的JNI时,请参阅我遇到的类加载器问题 ( http://wiki.apache.org/tomcat/HowTo )
在加载它们之前,将DLL复制到临时目录中的临时文件。 完成后删除文件。 这样可以确保同一个DLL不会被加载两次。
我有这个问题,我解决了它:
问题:
问题是由于应用程序服务器的某些configuration导致创build多个war
或ear
文件,因此会创build多个已部署的文件。 这些已部署的文件试图对加载到静态块中的本机库进行并发访问。
解:
- 停止您的应用程序服务器并closuresIDEA
- 从任务pipe理器完成所有的
java
进程 - 转到您的应用程序服务器的这个地址:
jboss-eap-6.4.0\standalone\configuration
并打开standalone.xml
文件 - 在
standalone.xml
,删除所有deployments
标记(不要担心,当您重新运行应用程序服务器时,会插入此标记 - 转到您的应用服务器的这个地址:
jboss-eap-6.4.0\standalone\deployments
并删除所有部署的文件和war
文件。 (你可以备份你的战争文件) - 打开IntelliJ的想法,并转到:编辑configurationJBOSS – >部署选项卡
- 删除当前的部署并添加一个应该
exploded
的新部署