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
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.");
        }
    }

}
#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;
}
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)

Reply via email to