weili
weili

Reputation: 51

FATAL ERROR in native method: Bad global or local ref passed to JNI

I have gotten this error when setting the -Xcheck:jni option, and calling my native method.

The error is : FATAL ERROR in native method: Bad global or local ref passed to JNI

I shall paste the native method (C code) here, hope that anybody who knows what is wrong with this piece of code, will enlighten me. Thank you.

    #include <stdio.h>  
    #include <stdlib.h>  
    #include <string.h>  
    #include "fns_data.h"  
    #include "fns_client.h"  
    #include "sockRW.h"  
    #include "/usr/local/include/jni.h"  
    #include "JNIiSearchLib.h"  
    #include "com_eds_wise_util_JNIiSearchLib.h"  

    JNIEXPORT jstring JNICALL  
    Java_com_eds_wise_util_JNIiSearchLib_jniFNSSearchClient (  
        JNIEnv *env, jobject obj, jstring jip_addr, jint jport_number,  
        jstring jfield, jstring jquery_str, jint jhitnum)  
    {  
        HitIds           *hit_list   = NULL;  
        hitListPktStruct *hitPkt     = NULL;  
        int               hit_number = 0;  
        int               i          = 0;  
        int               fnsErrno   = 0;  
        char             *result_str = NULL;  
        jstring          *rslt_str   = NULL;  
        const char       *cip_addr   = NULL;  
        const char       *cquery_str = NULL;  
        char              errbuf[1024];  

        cip_addr   = (*env)->GetStringUTFChars(env, jip_addr, 0);  
        if (cip_addr == NULL) {  
            return ((* env)->NewStringUTF (env, "Error: Cannot get IP address."));  
        }  

        cquery_str = (*env)->GetStringUTFChars(env, jquery_str, 0);  
        if (cquery_str == NULL) {  
            (*env)->ReleaseStringUTFChars (env, jip_addr, cip_addr);  
            (*env)->DeleteLocalRef(env, cip_addr);  
            return ((* env)->NewStringUTF (env, "Error: Cannot get query string."));  
        }  
        printf ("[Java_JNILib_jniFNSSearchClient] ipaddress[%s] portnumber[%d]"  
                " querystr[%s]\n\n", cip_addr, jport_number, cquery_str);  

        /* Search and get back the handler & total hits 
         */  
        hit_list = fns_search_client0 (cip_addr, jport_number,  
                                       "PN", cquery_str, &hit_number);  


        /* Display total hits 
         */  
        printf ("Total hits = %d\n", hit_number);  


        /* Enumerate every item in the result list and display them. 
         * The results are returned as a string to Java in the following manner: 
         * 
         * "[hitresult1|hitresult2|hitresult3|..|hitresultN]\0" 
         * 
         *     where hitresultN = 94-byte record 
         * 
         * [+string94+|+string94]+stringTerminator  
         */  
        printf ("malloc[%d]\n", (hit_number * 95) + 3);  

        result_str = malloc (((hit_number * 95)+3) * sizeof(char));  
        if (result_str == NULL) {  
            printf ("Out of memory, unable to malloc\n");  
            rslt_str = (* env)->NewStringUTF (env, "Error: Out of memory, unable to malloc");  

            if (hit_list) {  
                FREE_STRING (hit_list);  
            }  
            if (hitPkt) {  
                FREE_HITLIST_STRUCT (hitPkt);  
            }  
            (*env)->ReleaseStringUTFChars (env, jip_addr, cip_addr);  
            (*env)->ReleaseStringUTFChars (env, jquery_str, cquery_str);  
            (*env)->DeleteLocalRef(env, cip_addr);  
            (*env)->DeleteLocalRef(env, cquery_str);  

            fflush(stdout);  
            return (rslt_str);  
        }  

        sprintf (result_str, "[");  
        for (i = 0; i < hit_number; i++) {  
            strcat (result_str, hitPkt->docNameList[i]);  
            if (i != (hit_number - 1)) {  
                strcat (result_str, "|");  
            }  
        }  
        strcat (result_str, "]");  

        printf ("\n\nFNS search result:[From Library]\n");  
        printf ("%s\n\n",result_str);  

        /* free the handler 
         */  
        if (hit_list) {  
            FREE_STRING (hit_list);  
        }  

        /* free the result lists 
         */  
        if (hitPkt) {  
            FREE_HITLIST_STRUCT (hitPkt);  
        }  

        /* prepare stuff for Java 
         */  
        rslt_str = (* env)->NewStringUTF (env, result_str);  

        /* free our memory 
         */  
        if (result_str) {  
            free (result_str);  
        }  
        (*env)->ReleaseStringUTFChars (env, jip_addr, cip_addr);  
        (*env)->ReleaseStringUTFChars (env, jquery_str, cquery_str);  
        (*env)->DeleteLocalRef(env, cip_addr);  
        (*env)->DeleteLocalRef(env, cquery_str);  

        fflush(stdout);  
        return (rslt_str);  
    }  

Upvotes: 1

Views: 1326

Answers (1)

Pavel Zdenek
Pavel Zdenek

Reputation: 7278

I wonder how this even compiles. jstring is a pointer type already, so yours

jstring          *rslt_str   = NULL;

is a pointer to pointer, and i wonder how the compiler can take it as retval for GetStringUTFChars and returning it from your native method altogether.

Upvotes: 1

Related Questions