问题
I have a webapp running under Tomcat 3.2.1 that needs to make JNI calls in
order to access data and methods in legacy C++ code. A servlet is loaded
on
startup of the webapp that, as part of its init method, causes a data set
specific to that webapp instance to be loaded into the C++ data
structures.
This Java code for this servlet contains the following:
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);
}
}
Things work fine if there is only one webapp (let\'s call it \"webapps/aaa\").
If I have a second webapp (\"webapps/bbb\") that is identical to webapps/aaa except for the data set used in the C++ data structures, then webapps/aaa starts up just fine, but when webapps/bbb is started I get an error stating that:
JCoreImpl NOT loaded java.lang.UnsatisfiedLinkError: Native Library
E:\\WebStation\\binDebug\\JCoreImpl.dll already loaded in another classloader
I need to have a separate instance of the native library for each of my webapps as each instance needs to contain data that is unique to that particular webapp. I have searched through the mail archives and read emails by Craig McLanahan explaining the classloader hierarchy. But I have not been able to find anything specific to loading a unique instance of a native library for each webapp.
回答1:
You can't load the same native library twice.
Put the class in a jar file under <tomcat>/lib/, it will be shared over all wars.
回答2:
See the section I'm encountering classloader problems when using JNI under Tomcat on the Tomcat HowTo wiki (http://wiki.apache.org/tomcat/HowTo)
回答3:
Copy the DLLs to temporary files in a temporary directory before loading them. Delete the files when you are done. This way you can ensure that the same DLL is not loaded twice.
回答4:
I had this problem and I solved it:
Problem:
The problem is due to some configurations of your application server which cause to create more than one war or ear files and consequently it creates more than one deployed files. These deployed files attempt to have a concurrent access to your native library which loaded in a static block.
Solution:
- Stop your Application Server and close the IDEA
- Finish all
javaprocesses from task manager - Go to this address of your App Server:
jboss-eap-6.4.0\standalone\configurationand openstandalone.xmlfile - In the
standalone.xml, delete all thedeploymentstag (Don't worry, when you rerun the application server, it inserts this tag - Go to this address of your App Server:
jboss-eap-6.4.0\standalone\deploymentsand delete all deployed files andwarfiles. (You can backup your war files) - Open IntelliJ Idea and go to: Edit Configuration JBOSS -> Deployment tab
- Delete current deployment and add a new one that should be
exploded
来源:https://stackoverflow.com/questions/1030792/dll-already-loaded-in-another-classloader