6
votes

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 Java EE 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!

1
Have you definitely specified the same java.library.path when running under Tomcat?Jon Skeet
Yes, Tomcat does has the library path. /usr/java/jdk1.6.0_01/jre/lib/i386/server: /usr/java/jdk1.6.0_01/jre/lib/i386: /usr/java/jdk1.6.0_01/jre/../lib/i386: /usr/lib/xulrunner-1.9: /usr/java/packages/lib/i386: /lib: /usr/libmouthu
I assume this is tomcat classpath, but do you pass -Djava.library.path=/usr/lib argument to JVM you are running tomcat on?Georgy Bolyuba
@Georgy Yes, I did but still got the same error message. Here is the full arguments to JVM I'm running tomcat on: -Dcatalina.base="/homes/mouthu/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0" -Dcatalina.home="/homes/mouthu/Desktop/apache-tomcat-6.0.26" -Dwtp.deploy="/homes/mouthu/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps" -Djava.endorsed.dirs="/homes/mouthu/Desktop/apache-tomcat-6.0.26/endorsed" -Djava.library.path="/usr/lib"mouthu
Can you clarify two things: 1. model.initModel(); where model comes from? and 2. what is in model.initModel(); (I assume it is a native method, so, can you show the C/C++/whatever method)?Georgy Bolyuba

1 Answers

2
votes

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.