I recently wrote a webapp that leverages a proprietary application's api (in
the form of a JNI wrapper api, so it requires a jar file and a set of system
libraries/dlls) to allow interactions with this application using simple
http calls.

Running my web application alone (placing the api jar in my webapp's
WEB-INF/lib directory and the required system libraries somewhere in
java.library.path) on Tomcat initially caused no problems, however when I
attempt to run it alongside any web applications that also use the api I
have all kinds of JNI errors.

The first error I encountered occurred when I attempted to run my webapp
after calling a second webapp that used the same api libraries.  Depending
on which webapp was executed first, it locked one of the system libraries
and prevented the other from loading it (producing a
java.lang.UnsatisfiedLinkError: Native Library x already loaded in another
classloader).

After some quick research into how the Tomcat classloader hierarchy works I
was able to temporarily fix this by moving the api jar into shared/lib
instead of into each of the webapps WEB-INF/lib directories.  This ensures
that the classes are loaded by a classloader that both webapps have access
to.  However, this is not a perfect fix.

Firstly, on my "happycheck" page, I still obtain an UnsatisfiedLinkError
when I check for the presence of a system library.  My webapp still works,
but the check fails.  Currently I am just making a call to
System.loadLibrary and catching any errors.  Additionally, I would prefer to
not have to dictate that other webapps remove their copy of the api jar from
their WEB-INF lib directory.

After some relatively extensive research, I have come to the understanding
that the "java.lang.UnsatisfiedLinkError: Native Library x already loaded in
another classloader" message is also displayed when the current classloader
already has the system library loaded.  So that explains the behavior of my
happycheck page.  Is there another way for me to check for the presence of a
system library without just attempting to load it so that I can modify my
happycheck Servlet to provide more accurate results?

Also, is there a way that I can adjust my environment so that other webapps
aren't required to move their api jar?  I have tested and verified that the
proprietary api jar uses System.loadLibrary and does not provide a way to
specify an absolute path to the system libraries (if it did I could just
copy the system libraries into my webapp directory and set a configuration
item to describe where they are located).  Therefore, about the only thing
that I can think of is to somehow set the java.library.path for my webapp to
be different then the one used for the other webapps.  Is there a way to do
this without having multiple Tomcat instances running?

Other things that I tried include making calls to System.load for each of
the system libraries in my webapp before I make any calls to the api. 
Unfortunately the System.loadLibrary call in the api jar still attempts to
load the system library used by the other webapps.
-- 
View this message in context: 
http://www.nabble.com/Best-Practice-for-UnsatisfiedLinkError%3A-Already-loaded-in-another-classl-tf2419784.html#a6746361
Sent from the Tomcat - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to