0

I am trying to deploy a web service which uses a JNI library to Tomcat 6 on Windows and have run into the undesirable UnsatisfiedLinkError issue (already loaded in another classloader) when the app is restarted within Tomcat Manager.

I see the best practice for solving this is to load the JNI library from another class, specified in a jar file and placed into $(TOMCAT_HOME)/lib. When I do this, I am unable to call any JNI methods, yet I can see that the JNI library is loaded.

This snippet works:

package com.mywebservice;

import javax.jws.WebService;
import javax.annotation.PostConstruct;

@WebService
class MyWebServiceImpl implements MyWebService {

    static {
        System.loadLibrary ("MyJNILibrary");
    }

    @PostConstruct
    public native void Start ();
}

The Start function is defined in the JNI library as Java_com_mywebservice_MyWebServiceImpl_Start and gets called.

The code below doesn't work for me. First, the loader class which goes into $(TOMCAT_HOME)/lib as MyLoader.jar.

package com.myloader;

public class MyLoader {

    static {
        System.loadLibrary ("MyJNILibrary");
        System.out.println ("Library loaded");
    }

    public static void main(String[] args) {}
}

Second, the modified web service to load the library via the loader, still as a war file under webapps:

package com.mywebservice;

import javax.jws.WebService;
import javax.annotation.PostConstruct;

@WebService
class MyWebServiceImpl implements MyWebService {

    static {

        try {
            Class.forName ("com.myloader.MyLoader");
            System.out.println ("Class found");
        }

        catch (ClassNotFoundException e) {
            System.out.println ("Class not found");
        }
    }

    @PostConstruct
    public native void Start ();
}

With this code, I see an error when an attempt is made to call the Start method:

Caused by: java.lang.UnsatisfiedLinkError: com.mywebservice.MyWebServiceImpl.Start()V

Using the diagnostics I can see that the MyLoader class was found and that the JNI library was loaded (and locked). So I'm puzzled why this isn't working.

Using Tomcat 6.0.43 on Windows 2003 Server, JDK 6u45, Eclipse Kepler.

Is this how it is supposed to work and I am just missing something? If so, what is the point of this project: https://code.google.com/p/static-dll-bootstrapper/, which simply loads DLL's specified in a properties file?

rushman
  • 532
  • 2
  • 8
  • Tried also with Tomcat 8, Windows 8.1, JDK 8u45. Same problem. The library loads but the JNI functions are not found. – rushman Apr 17 '15 at 12:36

1 Answers1

0

The class contain the native method should load its own library. Anything else is inviting this problem. There's no good reason to separate this function.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Yes, but if I do that then I have to restart the entire Tomcat service if I want to restart just my web service, due to my JNI library being loaded by multiple classloaders. Hence why I need to separate the library loading into a separate class. – rushman Apr 17 '15 at 10:00