1
votes

I have a DLL that provides access to Window's LoadLibrary and FreeLibrary (to get around Java not being able to unload it). I need this DLL to persist between each webapp as it cannot be loaded twice.

I've followed these steps:

http://wiki.apache.org/tomcat/HowTo#I.27m_encountering_classloader_problems_when_using_JNI_under_Tomcat

and placed a singleton class (as a jar) with the static { System.loadLibrary() } call under ${TOMCAT}/lib. When my Tomcat webapp accesses this Singleton, it still throws the error

UnsatisfiedLinkError: Native Library ${TOMCAT}\lib\Native.dll already loaded in another classloader

Is this wrong in thinking that Tomcat's common classloader is loading this class, instantiating it (as per: http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html) and then passing the reference to the webapp thus bypassing the webapp classloader?

Is there a way to tell Tomcat to instantiate my singleton (forcing the common classloader to do it) and then provide that instance to satisfy my webapp's dependency?

Any discussion much appreciated.

1
If you try to create the $CATALINA_HOME/shared/lib as in the link mentions and place the dll there do you also get the same problem?Also your class has only the static initializer, right? - Cratylus
So in that link they describe the shared/lib for Tomcat6 and below. Currently, in Tomcat7, this has just simply moved to $CATALINA_HOME/lib. In the config you can see the common.loader property includes this. And no, the class has the single access function instance(), as well as the define JNI native functions. - Danny A

1 Answers

0
votes

Follow this link to unload dll:

http://www.codethesis.com/blog/unload-java-jni-dll

(web archive version)

I tried it with my web application running on Tomcat, and it works!

Briefly, I call System.loadLibrary from the class which is loaded by my custom class loader using reflection. This class is then removed by garbage collector.