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

Reply via email to