Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / February 2008

Tip: Looking for answers? Try searching our database.

JNI and Web Services

Thread view: 
hogcia - 15 Feb 2008 08:34 GMT
I have a *BIG* problem concerning callin a C++ .so library function
from a java Web Service (I am using JNI). Every time I start the Web
Service client I get a following error:

javax.xml.ws.soap.SOAPFaultException: Unknown fault type:class
java.lang.UnsatisfiedLinkError
       at
com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:
171)
       at
com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:
94)
       at
com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:
240)
       at
com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:
210)
       at
com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:103)
       at $Proxy28.p(Unknown Source)
       at p_versionclient.Main.main(Main.java:31)

as if the function wasn't there! And it is!
Not to mention that when I call the function from a regular java
program (with a main function) OR a C program - it works! I have no
idea what's going on...
The regular java program looks like this:

//Web_Serwis.java
│public class Web_Serwis
{

│    public native String
p();

│    public static void main(String[] args)
{
│    System.load("/u/agata/ala/
libmy.so");
│    Web_Serwis serwis = new
Web_Serwis();

│    String version =
serwis.p();

│    System.out.println("wersja=" +
version);
│    }
│}

This is the header file:

//Web_Serwis.h
│/* DO NOT EDIT THIS FILE - it is machine generated
*/

│#include
<jni.h>
│/* Header for class Web_Serwis
*/
│char
*p_version_c();
│#ifndef
_Included_Web_Serwis
│#define
_Included_Web_Serwis
│#ifdef
__cplusplus
│extern
"C" {
│#endif

│/
*
│ * Class:
Web_Serwis
│ * Method:
p
│ * Signature: ()Ljava/lang/
String;

*/
│JNIEXPORT jstring JNICALL
Java_Web_1Serwis_p
│  (JNIEnv *,
jobject);

│#ifdef
__cplusplus
│}
│#endif
│#endif

And this is the C++ program (p_version_c() is a function from another
library that I link to this one):
//Web_Serwis.cc
│#include
"Web_Serwis.h"
│#include
<string>

│JNIEXPORT jstring JNICALL
Java_Web_1Serwis_p
│  (JNIEnv *env, jobject
obj)
│{
│       const char *str =
p_version_c();
│       if(str ==
NULL)

{
│             return (*env).NewStringUTF("ERROR: p_version_c()
returned NULL")
│       }
│       return
(*env).NewStringUTF(str);
│}

Oh, and this is how I compile and run the program:
│g++ -shared -m32 -c -g3 -gdwarf-2 -I/opt/SDK/jdk/include/linux -I/opt/
SDK/jdk/include -o Web_Serwis.o Web_Serwis.cc
│g++ -shared -m32 -o libmy.so Web_Serwis.o /u/adm/bin.pg8.2/o/za/kk.o /
u/adm/bin.pg8.2/o/za/m_action.o /u/adm/bin.pg8.2/ar/k
│/opt/jdk1.6/bin/java Web_Serwis

So far it works. Now I make a similar Web Service, exposing the call
to the library function (p() calls p_version_c()):

//p_versionSerwer.java
package ws;

import javax.jws.WebMethod;
import javax.jws.WebService;

/**
*
* @author agata
*/
@WebService()
public class p_versionSerwer {
         static
         {
             try {

                 System.out.println ("loading library...");
                 System.load("/u/agata/ws/libp.so");
             }
             catch (Exception e) {
                 System.out.println ("Can't load library!!!");
                 e.printStackTrace();
             }
             catch (Error err) {
                 System.out.println ("ERROR:  Can't load
library!!!");
                 err.printStackTrace();
             }
         }
   /**
    * Web service operation
    */
   @WebMethod
   public native String p();
}

I create a header file:
//p_version.h
│/* DO NOT EDIT THIS FILE - it is machine generated
*/
│#include
<jni.h>
│/* Header for class ws_p_versionSerwer
*/
│char *
p_version_c();
│#ifndef
_Included_ws_p_versionSerwer
│#define
_Included_ws_p_versionSerwer
│#ifdef
__cplusplus
│extern
"C" {
│#endif
│/
*
│ * Class:
ws_p_versionSerwer
│  * Method:
p
│   * Signature: ()Ljava/lang/
String;

*/
│    JNIEXPORT jstring JNICALL
Java_ws_p_1versionSerwer_p
│      (JNIEnv *,
jobject);

│      #ifdef
__cplusplus
│      }

#endif
│      #endif

And a C++ file that calls p_version_c():
// p_version.cc
#include
"p_version.h"
│#include
<string>

│JNIEXPORT jstring JNICALL
Java_ws_p_1versionSerwer_p
│  (JNIEnv * env, jobject
obj)
│{
│    const char *str =
p_version_c();

if(str==NULL)
│Ireturn (*env).NewStringUTF("ERROR: funkcja p_version_c zwrocila
NULL");                                                   │
│    return
(*env).NewStringUTF(str);
│}

Finally I compile the files with other library files into libp.so:
g++ -shared -m32 -g3 -gdwarf-2 -I/opt/SDK/jdk/include/linux -I/opt/SDK/
jdk/include -o p_version.o p_version.cc
g++ -shared -m32 -o libp.so p_version.o /u/adm/bin.pg8.2/o/za/kk.o /u/
adm/bin.pg8.2/o/za/m_action.o /u/adm/bin.pg8.2/ar/k

And run a simple client:
//Main.java
package p_versionclient;

/**
*
* @author agata
*/
public class Main {

   /** Creates a new instance of Main */
   public Main() {
   }

   /**
    * @param args the command line arguments
    */
   public static void main(String[] args) {

       try { // Call Web Service Operation
           cli.PVersionSerwerService service = new
cli.PVersionSerwerService();
           cli.PVersionSerwer port = service.getPVersionSerwerPort();
           // TODO process result here
           java.lang.String result = port.p();
           System.out.println("Result = "+result);
       } catch (Exception ex) {
           ex.printStackTrace();
       }
   }

}

And that's when I get the error message... I've been trying to get
this to work for a week now, so I would really appreciate some help
(maybe a way to check where's the problem or a way to get an error
message, that actually SAYS something) .
I'm running this Web Service on a remote server, if that's of any
significance.

Thanks in advance! :)
Lothar Kimmeringer - 15 Feb 2008 11:51 GMT
>     /**
>      * Web service operation
>      */
>     @WebMethod
>     public native String p();

personally I would do the following:

@WebMethod
public String callP(){
  return p();
}

private native String p();

I'm not sure how JWS behaves but if the native-declaration is
kept in the ServerPort you receive on the client-side, the
WebService-Client will try to call a native method on the
client side that must fail unless you don't have the same
JNI-Library installed there.

>             cli.PVersionSerwerService service = new
> cli.PVersionSerwerService();
>             cli.PVersionSerwer port = service.getPVersionSerwerPort();
>             // TODO process result here
>             java.lang.String result = port.p();

Instead of the above line, you would use
String result = port.callP();

Regards, Lothar
Signature

Lothar Kimmeringer                E-Mail: spamfang@kimmeringer.de
              PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
                questions!

Roedy Green - 16 Feb 2008 22:26 GMT
>java.lang.UnsatisfiedLinkError

see
http://mindprod.com/jgloss/runerrormessages.html#UNSATISFIEDLINKERROR
--

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.