You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@axis.apache.org by Deepak S Patwardhan <cs...@cse.iitd.ac.in> on 2005/04/24 19:05:38 UTC

Calling JNI code

Hi all,

I am trying to write a web service in which some of the functionality will 
be implemented in C++, and hence I'll need JNI. However, I have not been 
able to make it work.

So, I decided to make a toy web service to understand how things will 
work. The toy web service will have one operation which tell whether a 
number is prime. And I'll implement this prime checking function in C++. I 
did the following stuff and hoped things would work, but they didn't.

Here is the wsdl file :
----------------------------------------------------
<?xml version="1.0" ?>

<definitions name="PrimeDef"
         targetNamespace="http://iitd/csd99440/ws5/"
         xmlns:tns="http://iitd/csd99440/ws5/"
         xmlns:xsd="http://www.w3.org/1999/XMLSchema"
         xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
         xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
         xmlns="http://schemas.xmlsoap.org/wsdl/">

     <message name="aNumber">
         <part name="num" type="xsd:int"/>
     </message>

     <message name="aBool">
         <part name="boo" type="xsd:boolean"/>
     </message>

     <portType name="Prime">
         <!-- Tell if a given number is prime -->
         <operation name="isPrime">
             <input message="tns:aNumber"/>
             <output message="tns:aBool"/>
         </operation>
     </portType>

     <binding name="PrimeSOAPBinding" type="tns:Prime">
         <soap:binding style="rpc"
                 transport="http://schemas.xmlsoap.org/soap/http"/>

         <operation name="isPrime">
             <soap:operation soapAction=""/>
             <input>
                 <soap:body use="encoded" encodingStyle="soap-enc"/>
             </input>
             <output>
                 <soap:body use="encoded" encodingStyle="soap-enc"/>
             </output>
         </operation>

    </binding>

     <!-- Service declaration -->
     <service name="Primality">
         <port name="Prime" binding="tns:PrimeSOAPBinding">
             <soap:address location="http://localhost:9440/axis/services/Prime"/>
         </port>
     </service>

</definitions>
-----------------------------------------
(Please change the namespace and port number if you experiment with this.)

I generate the server side code by WSDL2Java, and in the file 
PrimeSOAPBindingImpl, I do the following :

     public boolean isPrime(int num) throws java.rmi.RemoteException {
         return is_prime(num);
     }

     public native boolean is_prime(int x);

     static {
         System.loadLibrary("libMyPrime.so");
     }

I then compiled the code. To the compiled class, I do the following, to 
generate the header file.

javah iitd.csd99440.ws5.PrimeSOAPBindingImpl

The header file is generated and I implement the required functionality 
in a file checkPrime.cpp :
----------------------------
#include <jni.h>
#include "iitd_csd99440_ws5_PrimeSOAPBindingImpl.h"
#include <math.h>

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jboolean JNICALL 
Java_iitd_csd99440_ws5_PrimeSOAPBindingImpl_is_1prime
   (JNIEnv *env, jobject job, jint jx) {

     int jxRoot2 = (int)(sqrt(jx));
     for (int i = 2; i <= jxRoot2; ++ i) {
         if ((jx % i) == 0)
             return false;
     }

     return true;
}

#ifdef __cplusplus
}
#endif
----------------------------------------

After this I compiled the program with the command

g++ -lm -shared checkPrime.cpp -o libMyPrime.so

Then I placed the shared object file in $HOME/lib, this directory is 
present in my LD_LIBRARY_PATH.

At this point I expected the service to work. But, it isn't working. When 
I click on the link "View the list of deployed web services", I get a 
blank page.

Can anybody tell me what's happening here ? I am sure the problem is 
simple : Either Axis or Tomcat isn't picking up the shared library. What 
else I have to do to make this thing running ?

thanks,
Deepak S Patwardhan.

Re: Calling JNI code

Posted by Anne Thomas Manes <at...@gmail.com>.
Deepak,

You must specify the proper URI for your encoding style in the
<soap:body> definitions. You also should specify a namespace:

  <soap:body use="encoded" 
       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
       namespace="http://iitd/csd99440/ws5/" />

Have you considered exposing your C++ functions directly as a web
service using something like Axis C++? Then you wouldn't need to use
JNI.

Anne

On 4/24/05, Deepak S Patwardhan <cs...@cse.iitd.ac.in> wrote:
> 
> Hi all,
> 
> I am trying to write a web service in which some of the functionality will
> be implemented in C++, and hence I'll need JNI. However, I have not been
> able to make it work.
> 
> So, I decided to make a toy web service to understand how things will
> work. The toy web service will have one operation which tell whether a
> number is prime. And I'll implement this prime checking function in C++. I
> did the following stuff and hoped things would work, but they didn't.
> 
> Here is the wsdl file :
> ----------------------------------------------------
> <?xml version="1.0" ?>
> 
> <definitions name="PrimeDef"
>          targetNamespace="http://iitd/csd99440/ws5/"
>          xmlns:tns="http://iitd/csd99440/ws5/"
>          xmlns:xsd="http://www.w3.org/1999/XMLSchema"
>          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
>          xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
>          xmlns="http://schemas.xmlsoap.org/wsdl/">
> 
>      <message name="aNumber">
>          <part name="num" type="xsd:int"/>
>      </message>
> 
>      <message name="aBool">
>          <part name="boo" type="xsd:boolean"/>
>      </message>
> 
>      <portType name="Prime">
>          <!-- Tell if a given number is prime -->
>          <operation name="isPrime">
>              <input message="tns:aNumber"/>
>              <output message="tns:aBool"/>
>          </operation>
>      </portType>
> 
>      <binding name="PrimeSOAPBinding" type="tns:Prime">
>          <soap:binding style="rpc"
>                  transport="http://schemas.xmlsoap.org/soap/http"/>
> 
>          <operation name="isPrime">
>              <soap:operation soapAction=""/>
>              <input>
>                  <soap:body use="encoded" encodingStyle="soap-enc"/>
>              </input>
>              <output>
>                  <soap:body use="encoded" encodingStyle="soap-enc"/>
>              </output>
>          </operation>
> 
>     </binding>
> 
>      <!-- Service declaration -->
>      <service name="Primality">
>          <port name="Prime" binding="tns:PrimeSOAPBinding">
>              <soap:address location="http://localhost:9440/axis/services/Prime"/>
>          </port>
>      </service>
> 
> </definitions>
> -----------------------------------------
> (Please change the namespace and port number if you experiment with this.)
> 
> I generate the server side code by WSDL2Java, and in the file
> PrimeSOAPBindingImpl, I do the following :
> 
>      public boolean isPrime(int num) throws java.rmi.RemoteException {
>          return is_prime(num);
>      }
> 
>      public native boolean is_prime(int x);
> 
>      static {
>          System.loadLibrary("libMyPrime.so");
>      }
> 
> I then compiled the code. To the compiled class, I do the following, to
> generate the header file.
> 
> javah iitd.csd99440.ws5.PrimeSOAPBindingImpl
> 
> The header file is generated and I implement the required functionality
> in a file checkPrime.cpp :
> ----------------------------
> #include <jni.h>
> #include "iitd_csd99440_ws5_PrimeSOAPBindingImpl.h"
> #include <math.h>
> 
> #ifdef __cplusplus
> extern "C" {
> #endif
> 
> JNIEXPORT jboolean JNICALL
> Java_iitd_csd99440_ws5_PrimeSOAPBindingImpl_is_1prime
>    (JNIEnv *env, jobject job, jint jx) {
> 
>      int jxRoot2 = (int)(sqrt(jx));
>      for (int i = 2; i <= jxRoot2; ++ i) {
>          if ((jx % i) == 0)
>              return false;
>      }
> 
>      return true;
> }
> 
> #ifdef __cplusplus
> }
> #endif
> ----------------------------------------
> 
> After this I compiled the program with the command
> 
> g++ -lm -shared checkPrime.cpp -o libMyPrime.so
> 
> Then I placed the shared object file in $HOME/lib, this directory is
> present in my LD_LIBRARY_PATH.
> 
> At this point I expected the service to work. But, it isn't working. When
> I click on the link "View the list of deployed web services", I get a
> blank page.
> 
> Can anybody tell me what's happening here ? I am sure the problem is
> simple : Either Axis or Tomcat isn't picking up the shared library. What
> else I have to do to make this thing running ?
> 
> thanks,
> Deepak S Patwardhan.
>