Skip to Main Content

Java HotSpot Virtual Machine

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

JNI freeing local references

843829Jul 6 2004 — edited Jul 8 2004
We're using JNI to receive data from a native callback function. The native side creates local references, but does not use the DeleteLocalRef function. This works fine with the SUN JRE.
However, the IBM JRE gets a stack overflow exception.
According to IBM, we should delete the local references, but this requires a total rewrite of our program.
Unfortunately, the JNI documentation is not very clear on this topic. In our understanding, the local references are being released automatically once they are out of scope.
Is it really necessary to delete the local references or is there a bug in the IBM JRE ?

Sample program :
==============
// JNITest.java

interface INativeNotification
{
public void nativeCallBack();
}

class JNITest implements INativeNotification
{
private long counter;
public native void nativeInitialize(INativeNotification callbackNotification);

static {
System.loadLibrary("JNITest");
}

public void nativeCallBack() {
System.out.println("JNITest CallBack " + counter++);
}

public void run() {

nativeInitialize(this);

counter = 0;

while(true)
{
try {
Thread.sleep(1000);
} catch(Exception e) {
}
}
}

public static void main(String[] args) {

JNITest jnitest = new JNITest();

jnitest.run();
}
}

// JNITest.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "JNITest.h"

static DWORD dwThreadId;
static HANDLE hThread;
static HANDLE volatile hInitCompleteEvent;
static bool volatile bLoop = true;
static JavaVM *jvm = NULL;
static jobject nativeNotification;

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
return TRUE;
}

bool DoNativeCall(JNIEnv *env)
/****************************/
{
jclass cls = env->GetObjectClass(nativeNotification);
jmethodID callbackMethod = env->GetMethodID(cls, "nativeCallBack", "()V");
env->CallVoidMethod(nativeNotification, callbackMethod);
if ( env->ExceptionOccurred() )
{
env->ExceptionDescribe();
env->ExceptionClear();
printf("Native code got exception calling nativeCallBack\n");
return(false);
}
return(true);
}

DWORD WINAPI JNIThread( LPVOID lpParam )
/**************************************/
{
JNIEnv *env = NULL;
jvm->AttachCurrentThread((void**)&env,NULL);
SetEvent(hInitCompleteEvent);
while (bLoop)
{
if (!DoNativeCall(env))
{
bLoop = false;
}
Sleep(1);
}
env->DeleteGlobalRef(nativeNotification);
jvm->DetachCurrentThread();
return 0;
}

/*
* Class: JNITest
* Method: nativeInitialize
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_JNITest_nativeInitialize(JNIEnv *env, jobject object, jobject _nativeNotification)
/************************************************************************************************************/
{
DWORD dwThrdParam = 0;
env->GetJavaVM(&jvm);
nativeNotification = env->NewGlobalRef(_nativeNotification);
hInitCompleteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
hThread = CreateThread( NULL, 0, JNIThread, &dwThrdParam, 0, &dwThreadId );
if (hThread == NULL)
{
env->DeleteGlobalRef(nativeNotification);
return;
}
WaitForSingleObject(hInitCompleteEvent, INFINITE);
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Aug 5 2004
Added on Jul 6 2004
7 comments
1,788 views