views:

391

answers:

2

Hi all,

Technical summary: I'm developing a Java web service deployed on GlassFish v3, running on CentOS 5.

My web service uses functionality provided by a native library (.so) . The native library works fine, however I am not having much luck in configuring the environment correctly to load the native library yet not be affected by web app re-deployment, without restart the app server.

What I've done so far is:

Initially I loaded the library (static {System.load(path/to/libabc.so)};) in the web service code, all paths set correctly, and it works fine, until I re-deploy the application and it complains that the library is loaded by another ClassLoader. I found out that native libs are only loaded once.

To try and solve this I then removed the library-loading code from the web application, created a Singleton class, wrapped it into a Lifecyle module, deployed it to GlassFish shared lib folder and then configured GlassFish to run the wrapper when it starts up. The idea being that now all web applications would be able to reference it since it is not tied to one particular web app and loaded by a ClassLoader higher in the hierarchy.

When GlassFish starts up the native library is loaded successfully ( linux> lsof | grep libabc.so ). However, the web service code fails with a UnsatisfiedLinkError when executing the native method in my web service Java code. It seems to me that code in the web application does not have access to the library loaded at start-up.

Can anyone tell me what I'm doing wrong?

Thanks in advance.

+1  A: 

I can't say much about "Lifecyle module" (I don't know if they are supposed to be "visible" to applications deployed to GlassFish) but...

I would indeed put the JNI library and the class that calls System.loadLibrary(String), for example a singleton, outside the webapp and deploy this code in domain/lib or domain/lib/applibs (see File Layout in V3 and this thread for more background on them).

This should make the code visible to your application and your application resistant to redeployment.

Pascal Thivent
Pascal, thanks for replying.Instead of using the Lifecyle module, I placed the Singleton class in a jar in /domain/lib .In the webapp, I dynamically load the class like so:Class<?> c = Class.forName("com.name.utils.SingletonClass", true, this.getClass().getClassLoader());....Then I deploy: asadmin deploy –libraries MyLib.jar /path/to/web_app.war.When I run the web app, the native library loads successfully, but I still get the UnsatisfiedLinkError.Does this look like a ClassLoader issue?
water-sparks
@water-sparks Where is the .so? In the jar next to the singleton? As a side note, you don't need to load the class dynamically (but this is not the root cause here, `UnsatisfiedLinkError` means the native library is not found).
Pascal Thivent
@Pascal, no, the .so is in /usr/local/lib. by the way, if i don't dynamically load the class how does the .so get loaded?
water-sparks
@water-sparks Oh, I didn't notice you were using `System.load` which takes indeed a full path as parameter, I thought you were using `System.loadLibrary` which is more portable but requires the native library to be on the library path (either in LD_LIBRARY_PATH or in `-Djava.library.path` or in *Configurartion > JVM Settings > Path Settings > Native Library Path Suffix* in the GlassFish console). About the second part, the loading of the .so is done in a static block so instantiating the class once is enough.
Pascal Thivent
@Pascal, I indeed use `System.load`, sorry about formatting. Initially did not know about the Native Library Suffix, added it later. At the moment i instantiate the Singleton (loading .so) dynamically from the same webapp which also uses the native methods.Given the library-loading class is in `/domain/lib` where ought i instantiate it from so that a webapp can use the native lib?Cheers
water-sparks
A: 

solved!

Finally,i put the pieces together.

missing piece Added the JNI library (e.g. jni_wrapper_for_libabc.jar) to GF shared folder domains/domain1/lib and it worked. The native lib is loaded by a Singleton class in a Lifecycle Module which is called when GF starts up.

Thank you very much Pascal, great help mate!!

Cheers

water-sparks