2 messages in net.java.dev.jna.usersRe: [jna-users] exception after redep...
FromSent OnAttachments
Petr VacekJun 12, 2009 12:47 pm 
Timothy WallJun 12, 2009 1:10 pm 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:Re: [jna-users] exception after redeploying webservice to Glassfish v2.1 : libjnidispatch.so already loaded in another classloaderActions...
From:Timothy Wall (twal@dev.java.net)
Date:Jun 12, 2009 1:10:47 pm
List:net.java.dev.jna.users

On Jun 12, 2009, at 3:48 PM, Petr Vacek wrote:

Greetings, I had assembled ffmpeg-java (which uses JNA) functions into webservice (.war, stateless) deployed into Glassfish v2.1 on Linux (64bit), it works fine until I modify the code and redeploy it (through Netbeans 6.5) , then it stops working until I restart/reload whole Glassfish :-( .

I get exception that some JNI library is already loaded in another classloader, but I beleive that when I redeploy webservice into glassfish, the old classloader is gone, so how can I get through ? I don't unfortunately don't know much about Classloaders andor JNA/ JNI ...

Thanks in advance for any information or pointer towards right place to find a solution :-)

While the classloader may be gone, it's not until it's been finalized that any native libraries it's loaded are closed.

Check out the most recent JNA in SVN, notably JNAUnloadTest. It verifies that the jnidispatch library can be loaded in a classloader, and re-loaded providing that the classloader and com.sun.jna.Native class gets GC'd.

There's another Sun bug
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5041014 having to do with URLClassLoader never closing an open Jar file that might also be applicable; I originally saw it referenced here:
http://jira.rhq-project.org/browse/RHQ-1399 , which incidently has run into similar issues properly disposing of a classloader used to load JNA.

In your specific case, you should determine a) what class loader is the first to load jnidispatch and b) what class loader is the subsequent one to attempt the load.

The two should probably be the same type of class loader (some sort of module loader for glassfish). If so, then you have to determine why the first one is still extant and/or hasn't disposed of the loaded native library.

There might also be some other glassfish module using JNA, in which case you'd need to figure out how to make JNA shared between them.

There might be some way to configure GlassFish to load JNA in the root class loader, then it would be available to all modules and you'd not need to worry about unloading it.

exception stack trace part (from glassfish domain server.log) : [#|2009-06-12T21:29:43.084+0200|SEVERE|sun-appserver2.1| com.sun.xml.ws.server.sei.EndpointMethodHandler|_ThreadID=19; _ThreadName=httpSSLWorkerThread-8080-4;_RequestID=3aa94d48- c8fd-4402-867b-bc328c459396;| Native Library /opt/glassfish/domains/domain1/generated/jsp/j2ee- modules/ffmpegapi/loader/com/sun/jna/linux-amd64/libjnidispatch.so already loaded in another classloader java.lang.UnsatisfiedLinkError: Native Library /opt/glassfish/domains/domain1/generated/jsp/j2ee-modules/ffmpegapi/ loader/com/sun/jna/linux-amd64/libjnidispatch.so already loaded in another classloader at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1716) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1647) at java.lang.Runtime.load0(Runtime.java:770) at java.lang.System.load(System.java:1005) at com.sun.jna.Native.loadNativeLibraryFromJar(Native.java:633) at com.sun.jna.Native.loadNativeLibrary(Native.java:574) at com.sun.jna.Native.<clinit>(Native.java:104) at net.sf.ffmpeg_java.AVFormatLibrary.<clinit>(AVFormatLibrary.java: 18) at gnvn.earth.avclink.wsl.ffmpeg.FFmpegFile.<init>(FFmpegFile.java: 39) <<-- webservice code

the FFmpegFile.java:39 line : final AVFormatLibrary AVFORMAT = AVFormatLibrary.INSTANCE;

which goes down to this code : public interface AVFormatLibrary extends FFMPEGLibrary { public static final AVFormatLibrary INSTANCE = (AVFormatLibrary) Native.loadLibrary( System.getProperty("os.name").startsWith("Windows") ? "avformat-51" : "avformat", AVFormatLibrary.class); .... }