views:

72

answers:

1

I have a java class (eval.java) that invokes a native method in an so file (libmodel.so). I can use System.loadLibrary() to load the libmodel.so without any error (-Djava.library.path=/usr/lib), and the native method initModel() works fine.

However, when I deploy it as a web service (tomcat 6.0.26 + axis2 1.5.1 + eclipse jee helios) to call the native method, I got the following error (the first line means the .so was successfully loaded):

Load library successfully
[ERROR] com.model.modelJNI.initModel()V
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.java:194)
    at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:102)
    at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
    at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:114)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:173)
    at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:167)
    at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:142)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.UnsatisfiedLinkError: com.model.modelJNI.initModel()V
    at com.model.modelJNI.initModel(Native Method)
    at com.model.model.initModel(model.java:13)
    at com.webservice.run(EvalVita.java:763)
    ... 25 more

Below is the body of Eval.java

import com.model.*;

public class Eval {
  static void loadModel() {
    try {
        System.loadLibrary("model");
        System.out.println("Load library successfully");
    } catch (UnsatisfiedLinkError e) {
        System.err.println("Native code library failed to load." + e);
    }
  }
  public void run() {
    loadModel();
    model.initModel();
  }
}

Am I missing anything here? Any input is appreciated!

A: 

This probably means that the library was loaded successfully, but the individual function needed by JNI could not be found (or was not declared properly). Here is an example of what your C code should look like:

/*
 * Class:     com_model_modelJNI
 * Method:    initModel
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_model_modelJNI_initModel
  (JNIEnv * env, jclass jclazz)
{
  // etc.
}

I've never used Swig before, so I'm not sure how it works with JNI. But you might want to try using javah and seeing what it outputs, to compare.

Matt Solnit
Thanks, Matt. I checked the wrapper code generated by SWIG and it did have the similar thing you posted:<pre>JNIEXPORT void JNICALL Java_com_model_modelJNI_initModel(JNIEnv *jenv, jclass jcls) { (void)jenv; (void)jcls; initModel();}</pre>I was just wondering why it works for standalone app but not for deployed webservice.
mouthu
Is it possible that the `libmodel.so` file being loaded from the Tomcat JVM is not the same as the one loaded from your standalone test?
Matt Solnit