vignesh
vignesh

Reputation: 568

How to resolve a Bad global or local ref passed to JNI error when calling a java method from native code

i searched through many answers for this problem but none of the seemed to match my case.I could not figure out where i am making the mistake.I create a native method in java and call it through jni.In the native method i get the reference of a java class method and call it from there

My java class is as follows:

import java.util.ArrayList ; 
import java.util.LinkedHashMap ; 

public class WmiClientClassJson {

    static {
        System.load("C:\\Users\\vignesh-pt1616\\Desktop\\WmiClientLibraryJson\\Debug\\WmiClientLibraryJson.dll");
    }

    public native void createConnection(String query , LinkedHashMap<String,Object> map , ArrayList<LinkedHashMap<String,Object>> list);

    public static void main(String[] args)
    {
        WmiClientClassJson obj = new WmiClientClassJson(); 
        LinkedHashMap<String , Object> map = new LinkedHashMap<String , Object>(); 
        ArrayList<LinkedHashMap<String , Object>> list= new ArrayList<LinkedHashMap<String , Object>>();
        obj.createConnection("String" , map , list );
    }

    public void indexToEs()
    {
        System.out.println("index method called");
    }
}

I have generated the dll library which is placed in the specified directory.My native method implementation is as follows .

JNIEXPORT void JNICALL Java_WmiClientClassJson_createConnection(JNIEnv *env, jobject classobj , jstring query , jobject mmapobj , jobject listobj )
{

    //Getting ListClass reference
    jclass ListClass = env->GetObjectClass(listobj);
    if( ListClass == NULL )
    {
        cout << "ListClass null " << endl ; 
        return ;
    }

    jmethodID listConstructor = env->GetMethodID(ListClass,"<init>","()V");
    if(listConstructor == NULL)
    {
        cout << "mapconstructor null "<< endl ; 
        return ; 
    }
    cout<< "list constructor found" << endl ; 

    //Getting ArrayList add method 
    jmethodID addMethod = env->GetMethodID(ListClass , "add" , "(Ljava/lang/Object;)Z");
    if(addMethod == NULL)
    {
        cout << "addMethod null "<< endl ; 
        return ; 
    }
    //cout << "add method found " << endl ; 

    jmethodID sizeMethod = env->GetMethodID(ListClass , "size" , "()I");
    if(sizeMethod == NULL )
    {
        cout << "sizeMethod null" << endl ; 
        return ; 
    }
    cout << "size method found" << endl ; 

    jclass callingClass = env->GetObjectClass(classobj);
    if( callingClass = NULL )
    {
        cout << "Calling class null " << endl ; 
        return ; 
    }
    else cout << "calling class found" << endl ;

    jmethodID indexMethod = env->GetMethodID(callingClass , "indexToEs" , "()V"); // the code throws an error at this point
    if( indexMethod == NULL )
    {
        cout << "index method not found" << endl ;
        return ;  
    }
    else cout << "index method found" << endl ;
}

when i try to get the method id of the indexToEs method i am getting the Bad global or local ref passed to JNI error

WARNING: JNI local refs: zu, exceeds capacity: zu
        at java.lang.System.initProperties(Native Method)
        at java.lang.System.initializeSystemClass(Unknown Source)
WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethod
list constructor found
size method found
calling class found
FATAL ERROR in native method: Bad global or local ref passed to JNI
        at WmiClientClassJson.createConnection(Native Method)
        at WmiClientClassJson.main(WmiClientClassJson.java:17)

please help me out with this thing.Thanks in advance.

Upvotes: 1

Views: 1471

Answers (1)

Alex Cohn
Alex Cohn

Reputation: 57173

if( callingClass = NULL )

will take the class reference and change it to 0.

You should pay more attention to compiler warnings, usually C++ compilers remind you to never write

if ( something = 0 )

The fix is to write

if( callingClass == NULL )

Upvotes: 1

Related Questions