Java Forum / General / October 2005
JNI C calling java with String gets null pointer in Java
xingshan_he@hotmail.com - 19 Oct 2005 00:47 GMT I have a c program that calls a java method. When trying to access the string parms passed into the jave pointer, I get null pointer exception.
Here is part of the code:
char *urlChar = "http://this_host/service"; char *userChar = "tester"; char *passwordChar = "tester"; char *phoneNumberChar = "1234567890";
jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getPhoneMessage", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); if (mid == NULL) { printf("unable to get method getPhoneMessage()..."); return; }
jobject result = (*env)->CallStaticObjectMethod( env, cls, mid, phoneNumberChar, urlChar, userChar, passwordChar);
--- java class ---
public class IVRPhoneUtil { public static String getPhoneMessage(String phoneNumber, String url, String userID, String password) throws Exception { System.out.println("java getPhoneMessage()"); if (url == null) { System.out.println("url is null"); } else { System.out.println("length " + url.length()); System.out.println("url is " + url); } return "test message"; } }
-- error / stack trace --- Exception in thread "main" java.lang.NullPointerException at java.io.Writer.write(Writer.java:126) at java.io.PrintStream.write(PrintStream.java:303) at java.io.PrintStream.print(PrintStream.java:448) at java.io.PrintStream.println(PrintStream.java:585) at com.interop.ivr.IVRPhoneUtil.getPhoneMessage(IVRPhoneUtil.java:21) Segmentation fault (core dumped)
The line that's causing the null pointer is where I tried to print out the length of the string.
Any idea what's going wrong here?
Thanks.
XS
Roedy Green - 19 Oct 2005 04:04 GMT On 18 Oct 2005 16:47:15 -0700, xingshan_he@hotmail.com wrote or quoted
>jmethodID mid = (*env)->GetStaticMethodID(env, You are a glutton for punishment with code like this. Do the Javaesque stuff like reflection in Java and the Cesque stuff in C.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Chris Uppal - 19 Oct 2005 08:42 GMT > char *urlChar = "http://this_host/service"; > char *userChar = "tester"; > char *passwordChar = "tester"; > char *phoneNumberChar = "1234567890"; [...]
> jobject result = (*env)->CallStaticObjectMethod( > env, cls, mid, phoneNumberChar, urlChar, userChar, passwordChar); You are passing four pointers to a nul-terminated array of 8-byte characters when the function is expecting 4 references to objects of type java.lang.String. These things are not even remotely similar.
Create four java.lang.Strings from your char*s and pass those.
-- chris
xingshan_he@hotmail.com - 19 Oct 2005 20:06 GMT This is a great group with great programmers! Using advice given here, I got my stuff to work. Here is the change to get it working:
Instead of doing this: jobject result = (*env)->CallStaticObjectMethod( env, cls, mid, phoneNumberChar, urlChar, userChar, passwordChar);
I need to do this:
jobject result = (*env)->CallStaticObjectMethod( env, cls, mid, (*env)->NewStringUTF(env, phoneNumberChar), (*env)->NewStringUTF(env, urlChar), (*env)->NewStringUTF(env, userChar), (*env)->NewStringUTF(env, passwordChar));
It works great now. My c program calls a java program that does SOAP to a Tomcat server.
Thanks alot folks!
XS
xingshan_he@hotmail.com - 19 Oct 2005 23:46 GMT I tried a different way of creating jstring from char* and the result is very different:
This works as it successfully returns from Java method, but then it get segmentation fault when I tried to get char* from the jstring:
jstring result = (jstring)(*env)->CallStaticObjectMethod( env, cls, mid, //I have seen people calling this method without the 'env' here??? (*env)->NewStringUTF(env, phoneNumberChar), (*env)->NewStringUTF(env, urlChar), (*env)->NewStringUTF(env, userChar), (*env)->NewStringUTF(env, passwordChar)); if (result != NULL) { const char *str = (*env)->GetStringUTFChars(env, result, 0); //here I get segmentation fault printf("message returned is %s\n", str);
}
While this causes segmentation fault when calling the java method:
jstring phoneNumber = (jstring)(*env)->NewStringUTF(env, phoneNumberChar); jstring url = (jstring)(*env)->NewStringUTF(env, urlChar); jstring user = (jstring)(*env)->NewStringUTF(env, userChar); jstring password = (jstring)(*env)->NewStringUTF(env, passwordChar);
jstring result = (jstring)(*env)->CallStaticObjectMethod( env, cls, mid, phoneNumber, url, user, password);
Can anyone explain why this is happening? What's the correct way of doing this?
Thanks, XS
Gordon Beaton - 20 Oct 2005 09:24 GMT > I tried a different way of creating jstring from char* and the result > is very different: [quoted text clipped - 5 lines] > env, cls, mid, //I have seen people calling this method without the > 'env' here??? In C++ env is automatically passed to the function. In C you need to pass it explicitly.
> (*env)->NewStringUTF(env, phoneNumberChar), > (*env)->NewStringUTF(env, urlChar), > (*env)->NewStringUTF(env, userChar), > (*env)->NewStringUTF(env, passwordChar)); > if (result != NULL) { > const char *str = (*env)->GetStringUTFChars(env, result, 0);
> //here I get segmentation fault > printf("message returned is %s\n", str); If str is NULL after calling GetStringUTFChars(), you can't pass it to printf(). You should check first, and determine whether GetStringUTFChars() raised an exception before proceeding.
Note that every call to GetStringUTFChars() should be matched with a call to ReleaseStringUTFChars(). If you are calling this method repeatedly it will ultimately fail otherwise.
> While this causes segmentation fault when calling the java method: > [quoted text clipped - 9 lines] > Can anyone explain why this is happening? What's the correct way of > doing this? None of the casts to (jstring) should be necessary, and the use of explicit typecasts should be considered a warning flag. Otherwise I can't see anything obviously wrong with the code you've posted,
Your results seem a little erratic, so I wonder if you haven't done something wrong elsewhere in the native code. Check for array bounds errors, stray pointers, unitialized variables, unchecked return values and things like that.
To help determine the location of the segmentation fault more accurately, use fprintf(stderr) rather than printf().
/gordon
 Signature [ do not email me copies of your followups ] g o r d o n + n e w s @ b a l d e r 1 3 . s e
Gordon Beaton - 19 Oct 2005 08:56 GMT > I have a c program that calls a java method. When trying to access the > string parms passed into the jave pointer, I get null pointer > exception. [...]
> char *urlChar = "http://this_host/service"; > char *userChar = "tester"; > char *passwordChar = "tester"; > char *phoneNumberChar = "1234567890"; [...]
> jobject result = (*env)->CallStaticObjectMethod( > env, cls, mid, phoneNumberChar, urlChar, userChar, passwordChar); You can't pass a char* where a java String is required. Use NewString() or NewStringUTF to create the necessary objects.
/gordon
 Signature [ do not email me copies of your followups ] g o r d o n + n e w s @ b a l d e r 1 3 . s e
Free MagazinesGet 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 ...
|
|
|