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