Advanced JNI Problems on ARM
Miriam Busch
kaffe@rufus.w3.org
Thu, 12 Jul 2001 14:43:20 +0200
--rwEMma7ioTxnRzrJ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hi,
I'm having advanced JNI problems which only occur on StrongARM (Linux),
not on x86.
If native code calls Java via CallStaticObjectMethod and a Java object is
returned to the native side, it is somehow broken arriving at the native side.
A small test programm which reproduces the Bug is attached.
My KaffeVM is (almost) current CVS version, jit3, unix-pthreads.
Any idea what might be the problem?
Thank you,
Miriam Busch
--rwEMma7ioTxnRzrJ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="JNISandwich.java"
package jni;
/** Java calls native code who calls Java code
*/
public class JNISandwich{
static{
System.loadLibrary("sandwich");
}
private String anything;
public static int aStaticField = 1;
public int aField = 2;
public JNISandwich(){
anything="Done";
System.out.println("JNISandwich constructed.");
}
public String toString(){
return "JNISandwich "+anything;
}
public void touch(){
System.out.println("JNISandwich is touched.");
}
public static native JNISandwich getSandwichNative();
// to be called via native
public static JNISandwich createSandwich(){
JNISandwich s = new JNISandwich();
System.out.println("Java is going to return "+s+" to the native side.");
return s;
}
public static void main(String[] argv){
System.out.println("Before native call.");
JNISandwich s = getSandwichNative();
if (s!=null){
System.out.println("Got Sandwich: ");
System.out.println(s.toString());
System.out.println("If you see this, everything went fine.");
} else{
System.out.println("getSandwichNative returned null.");
}
}
}
--rwEMma7ioTxnRzrJ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sandwich.c"
#include <jni.h>
#include <stdio.h>
JNIEXPORT jobject JNICALL
Java_jni_JNISandwich_getSandwichNative(JNIEnv* env, jclass clazz) {
jmethodID methodId;
jobject obj;
jfieldID fieldId, staticFieldId;
methodId = (*env)->GetStaticMethodID(env, clazz, "createSandwich", "()Ljni/JNISandwich;");
if (!methodId)
printf("Method not found\n");
printf("Performing native call...\n");
obj = (*env)->CallStaticObjectMethod( env,
clazz,
methodId
);
printf("Native side: Touching the Java object: \n");
staticFieldId = (*env)->GetStaticFieldID(env, clazz, "aStaticField", "I");
if (!staticFieldId)
printf("Field not found!\n");
printf("Accessing static field: %d\n", (*env)->GetStaticIntField(env, clazz, staticFieldId));
fieldId = (*env)->GetFieldID(env, clazz, "aField", "I");
if (!fieldId)
printf("Field not found!\n");
printf("Accessing field: %d\n", (*env)->GetIntField(env, obj, fieldId));
methodId = (*env)->GetMethodID(env, clazz, "touch", "()V");
if (!methodId)
printf("Method not found\n");
(*env)->CallVoidMethod(env, obj, methodId);
return obj;
}
--rwEMma7ioTxnRzrJ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="jnisandwich.out"
Output x86
----------
Before native call.
Performing native call...
JNISandwich constructed.
Java is going to return JNISandwich Done to the native side.
Native side: Touching the Java object:
Accessing static field: 1
Accessing field: 2
JNISandwich is touched.
Got Sandwich:
JNISandwich Done
If you see this, everything went fine.
Output ARM
----------
Before native call.
Performing native call...
JNISandwich constructed.
Java is going to return JNISandwich Done to the native side.
Native side: Touching the Java object:
Accessing static field: 1
Accessing field: 0
java.lang.NullPointerException
at jni.JNISandwich.getSandwichNative(JNISandwich.java:native)
at jni.JNISandwich.main(JNISandwich.java:39)
--rwEMma7ioTxnRzrJ--