Hello all- I am working on an application that uses the JNI to talk between native code written in C++ and Java. When native code called through the JNI throws an exception, the stack will be unwound past a valid catch statement, resulting in a call to __default_terminate() and finally to abort(). When the same native code is called from a pure C++ program, the error is not seen. Additionally, the same code works without error on Solaris and Windows NT. I am using Sun's jdk 1.3.1 and gcc 2.95.3 and libc 2.2-9 on a machine with Mandrake 7.1 installed. I have written some toy code to reproduce the error (attached). Please examine it and let me know if anyone has encountered a similar problem / what workarounds were used. thanks, Paul /************************************************************* * Paul Morie | "insert amusing quote here" * *--------------------+--------------------------------------* * guy who checks | Please list me as not receiving html * * this account | e-mail. I use a real mail reader. * *************************************************************/
class HelloWorld { private native void print(); public static void main(String[] args) { new HelloWorld().print(); } static { System.loadLibrary("HelloWorld"); } }
#include <jni.h> #include <iostream> #include "MyException.h" #include "NativeMethods.h" #include "Utility.h" #include "HelloWorld.h" JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj) { cout << "Hello, World. I'm going to call an exception now" << endl; try { cout << "inside try block" << endl; throw_it(); cout << "after throw_it() in try " << endl; } catch ( MyException& E ) { throw_jni(env, "MyException", E); } return; }
class MyException extends Exception { MyException() { super(); } }
#ifndef _MY_EXCEPTION_H_ #define _MY_EXCEPTION_H_ #include <iostream> #include <string> #include <stdexcept> class MyException : public std::runtime_error { public: MyException(const char* str) : std::runtime_error(str) { cout << "Running constructor" << endl; } MyException(const std::string& str) : std::runtime_error(str.c_str()) { cout << "Running constructor" << endl; } }; #endif
#ifndef _TEST_UTILITY_H_ #define _TEST_UTILITY_H_ #include <jni.h> #include <iostream> #include "MyException.h" void throw_jni(JNIEnv* env, const char* name, const MyException E); #endif
#include "Utility.h" void throw_jni(JNIEnv* env, const char* name, const MyException E) { jclass cls = env->FindClass(name); if (!cls) { return; } env->ThrowNew(cls, E.what()); }
#ifndef _NATIVE_METHODS_H_ #define _NATIVE_METHODS_H_ #include <iostream> #include "MyException.h" void throw_it() { cout << "inside throw_it() " << endl; throw MyException("test"); cout << "nothrow" << endl; return; } #endif