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!

write/create listener/callback on a C library

843829Apr 19 2008 — edited Apr 22 2008
Can anyone point what's the problem on my code?

I'm writing a DLL, with a thread that will monitor the print spooler and call a java method when a job is added or deleted on a printer.

1) run java main
2) main calls a native method (addJobListener)
3) native method creates a native thread (ThreadProc)
4) native thread (ThreadProc) attaches to jvm
5) (addJobListener) returns
6) PROBLEM: since addJobListener returns, all further jni calls on ThreadProc crashes the code
7) I put a Sleep(9999999) on addJobListener, just as a test, then jni calls on ThreadProc works fine

/* ListenerImpl.java */
public class ListenerImpl implements Listener{
public void metodo() {
System.out.println("ListenerImpl.metodo()");
}
}

/* Teste.java */
public class Teste {
static{
System.loadLibrary("testelib");
}

public static void main(String[] args) throws Exception{
ListenerImpl l = new ListenerImpl();
Teste t = new Teste();
t.addListener(l);
}

public native void addListener(Listener l);
}

/* dllmain.c */
struct param_java{
JavaVM *vm;
jobject obj;
HANDLE h;
};

JNIEXPORT void JNICALL Java_Teste_addListener
(JNIEnv *env, jobject obj, jobject listener){

HANDLE h;//make sure the new thread will be created before this function returns
DWORD threadId;
struct param_java *p;//params for the new thread

(*env)->NewGlobalRef(env, listener);//intend to prevent garbage collect the object when this function returns

JavaVM *vm = NULL;
(*env)->GetJavaVM(env, &vm); //get the JavaVM to attach the new thread

h = CreateEvent(NULL, FALSE, FALSE, NULL);

p = (struct param_java *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct param_java));
p->vm = vm;
p->obj = listener;
p->h = h;

printf("starting new thread\n");
_beginthread(ThreadProc, 0, (void *)p);

WaitForSingleObject(h, INFINITE);
CloseHandle(h);
printf("retuned from addJobListener\n");
//Sleep(9999999);//if I take if off, the jni calls on the thread crashes - wierd!!! It's like JNIEnv I got on the new thread (AttachCurrentThread) is been cleaned or point to same address as the JNIEnv on this function
}

DWORD WINAPI ThreadProc(LPVOID lpParameter){
HANDLE signal;
HANDLE printer;
DWORD change = 0;
int i = 0;
struct parametros_java param = (struct param_java )lpParameter;

JNIEnv *env = NULL;
JavaVM *vm = param->vm;
jobject listener = param->obj;

jmethodID metodo;

JavaVMAttachArgs args;
args.version = JNI_VERSION_1_4;
args.name = NULL;
args.group = NULL;

(*vm)->AttachCurrentThread(vm, (void **)&env, &args);

OpenPrinter("HP DeskJet 690C", &printer, NULL);
signal = FindFirstPrinterChangeNotification(printer, PRINTER_CHANGE_ADD_JOB | PRINTER_CHANGE_DELETE_JOB, 0, NULL);

SetEvent(param->h);//notifies the thread on addJobListener the this thread has been started and attached to jvm. That's what it looks like...

for(i = 0; i < 4; i++){
jclass listenerClass = (*env)->GetObjectClass(env, listener);//this code crashed if I take the Sleep(9999999) from the addJobListener
WaitForSingleObject(signal, INFINITE);

FindNextPrinterChangeNotification(signal, &change, NULL, NULL);
if((change & PRINTER_CHANGE_ADD_JOB) == PRINTER_CHANGE_ADD_JOB){
printf("DLL got job\n");
}

if((change & PRINTER_CHANGE_DELETE_JOB) == PRINTER_CHANGE_DELETE_JOB){
printf("DLL lost job\n");
}

metodo = (*env)->GetMethodID(env, listenerClass, "metodo", "()V");//this code crashed if I take the Sleep(9999999) from the addJobListener
(*env)->CallVoidMethod(env, listener, metodo);//this code crashed if I take the Sleep(9999999) from the addJobListener
}

HeapFree(GetProcessHeap(), 0, param);
FindClosePrinterChangeNotification(signal);
ClosePrinter(printer);
(*env)->DeleteGlobalRef(env, listener);
(*vm)->DetachCurrentThread(vm);
}

Edited by: naosbsb on Apr 19, 2008 7:38 PM
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on May 20 2008
Added on Apr 19 2008
2 comments
530 views