Saurabh Meshram
Saurabh Meshram

Reputation: 8416

Set value from JNI in Java : JNI java.lang.NoSuchFieldError

I'm trying to set a variable's value (variable in java) from JNI.
I'm using GetFieldID and SetIntField to do the same.

Following is my code.

main.c

JNIEXPORT void JNICALL Java_com_example_hello_MainActivity_samplefunc
(JNIEnv *env, jobject obj, jobject x)
{

    jclass class = (*env)->GetObjectClass(env, x);
    jfieldID fid = (*env)->GetFieldID(env, myclass,"a","I");
    (*env)->SetIntField(env, obj ,fid, 10);

    return;
}

MainActivity.java

 package com.example.hello;
 public class MainActivity extends ActionBarActivity 
 {
    int a = -1;

    /* Declaration of Native function &  Load JNI Library*/
    public static native void samplefunc(Class x);
    static {
        System.loadLibrary("hellojni");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Class x = this.getClass();
        Log.d("JNI", "Before : Value of Port: " + a);
        samplefunc(x);
        Log.d("JNI", "After  : Value of Port: " + a);
        return;
    }
 }

The expected Logcat output is:

D/JNI Before : Value of Port: -1
D/JNI After  : Value of Port: 10

But i get the following error:

D/JNI     (12607): Before : Value of Port: -1
W/dalvikvm(12607): JNI WARNING: JNI function SetIntField called with exception pending
W/dalvikvm(12607):              in Lcom/example/hello/MainActivity;.samplefunc:(Ljava/lang/Class;)V (SetIntField)
W/dalvikvm(12607): Pending exception is:
I/dalvikvm(12607): java.lang.NoSuchFieldError: no field with name='a' signature='I' in class Ljava/lang/Class;
I/dalvikvm(12607):  at com.example.hello.MainActivity.samplefunc(Native Method)

I guess this is a little basic but I'm new to JNI.
Any help on this would be greatly appreciated.

I have already seen this: JNI: NoSuchFieldError however it doesn't explain how a value of any variable is set.

Upvotes: 1

Views: 2490

Answers (1)

BluesSolo
BluesSolo

Reputation: 608

I/dalvikvm(12607): java.lang.NoSuchFieldError: no field with name='a' signature='I' in class Ljava/lang/Class;

This line tells you that it is looking for a field 'a' with signature 'I' in class Class and not in your class MainActivity. The problem is the following:

// 'x' is of type Class, since you called samplefunc(Class x)
// Therefore 'class' is set to Class and not MainActivity
jclass class = (*env)->GetObjectClass(env, x); 

// Here you try to access the field 'a' from class Class and not from your MainActivity. 
// Hence your error.
jfieldID fid = (*env)->GetFieldID(env, class,"a","I"); 

Edit:

An easy solution would be to change the samplefunc to

samplefunc(MainActivity x)

Then you can use the same code and you get the correct class as suggested by Rolf ツ

Upvotes: 1

Related Questions