Symbian
Symbian OS Library

FAQ-0429 Why does my application panic when I try to use the CleanupStack in JNI code?

[Index][spacer] [Previous] [Next]



 

Classification: Java Category: JNI
Created: 11/02/99 Modified: 09/11/2002
Number: FAQ-0429
Platform: Not Applicable

Question:
If in JNI code I try to use the CleanupStack or call another method which does, my app panics with E32USER-CBase 66. Why is this?

Answer:
The JNI environment provides a CleanupStack by default, but does not provide a TRAP harness to tell the system where processing should continue from if the CleanupStack should be unwound due to something leaving while the CleanupStack is in use. This must be provided by the user.

The best way to do this is to convert your JNI method into a proxy for an ordinary C-style function which does the real work. The JNI method then merely provides a TRAP harness, from which that function can be launched, and a TRAP handler to deal with error cases.

For example, in the code below (distilled from the ToolbarFrame example project on the Symbian Developer Network Website, the JNI method DisplayTaskList() becomes a proxy driving the function DisplayTaskListL() which does the real work. (The trailing L is an EPOC convention indicating that the function can leave so should only be launched from within a TRAP harness.) In this case the error handling consists of performing some additional cleanup after the method leaves and reporting the error code back to the Java side for further processing. If cleanup should fail for DisplayTaskListL(), even with the additional cleanup applied in the case of an error condition being returned to the TRAP handler, the __UHEAP_MARKEND macro will cause the application to panic - and the VM to be closed. Such use of MARK/MARKEND macros is advisable to protect against the possibility of unforeseen memory leaks.

void DisplayTaskListL(JNIEnv* /*aJNI*/,jobject /*aThis*/)
{
//Do something useful that uses the CleanupStack and/or can leave
return;
}

JNIEXPORT jint JNICALL Java_Toolbar_DisplayTaskList
 (JNIEnv* aEnv, jclass aThis)
{
__UHEAP_MARK;
TRAPD(error, DisplayTaskListL(aEnv,aThis));
if(error)
{
// do any aditional cleanup here
}
__UHEAP_MARKEND;
return error; // a negative integer whose interpretation can be found in e32std.h
}