JDK-4407211 : C++ exceptions from JNI code compiled with SunPro CC4.2 are no caught.
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.3.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_2.6,solaris_7
  • CPU: sparc
  • Submitted: 2001-01-23
  • Updated: 2012-11-02
  • Resolved: 2001-02-15
Related Reports
Duplicate :  
Description

Name: boT120536			Date: 01/23/2001



java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-RC)
Java HotSpot(TM) Client VM (build 1.3.0-RC, mixed mode)

/*

  // Compile this block of C++ up with CC 4.2
  // when the java code below is run it produces the error message
  //
  //     Run-time exception error; current exception: int
  //             No handler for exception.
  //     Abort (core dumped)
  //
  // I interpret this error to mean that it ran my code but did not
  // catch the exception. Note this code worked fine with an earlier
  // release of Jva 1.3 and Java 1.2.
  //
  // % CC -V
  // CC: WorkShop Compilers 4.2 18 Sep 1997 C++ 4.2 patch 104631-04
  //
  // % CC -I/usr/java1.2/include -I/usr/java1.2/include/solaris -G   // -o libxx.so xx.cc -lC

  #include <jni.h>
  #include <unistd.h>

  extern "C"
  void
  Java_MyTest_theMethod(JNIEnv* p_env, jobject p_this)
  {
      try
      {
	throw 1;
      }
      catch(...){}
      write(1, "Hello\n", 6);
  }

*/


public class MyTest
{
    static native void theMethod();

    static public void main(String[] args)
    {
      System.loadLibrary("xx");
      theMethod();
    }
}
(Review ID: 108826) 
======================================================================

Name: boT120536			Date: 01/23/2001


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)

In a C++ native function invoked from java an exception is thrown as follows

class   Bexception
{
public:
    Bexception(){};
    ~Bexception(){};
};

void
func()
{
    throw(Bexception());
}

JNIEXPORT jint JNICALL Java_jtest_sofunc(JNIEnv *jenv, jclass javathis, jint
intparm,jstring str)
{
    try
    {
        func();
    }
    catch(Bexception E)
    {
        printf("Got bexception\n");
    }
    catch(...)
    {
        printf("Got exception\n");
    }
    return(intparm*2);
}

when invoked the runtime message:-

Run-time exception error; current exception: Bexception
        No handler for exception.

is output.

This construct works fine on 1.2 and when invoked from a C++ program.
(Review ID: 110023)
======================================================================

Name: boT120536			Date: 01/30/2001


bcraig@devws91 [test]> uname -a
SunOS devws91 5.7 Generic_106541-14 sun4u sparc SUNW,Ultra-1

bcraig@devws91 [test]> java -version
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-beta_refresh)
Java HotSpot(TM) Client VM (build 1.3.0-beta_refresh, mixed mode)


Java code in file test.java ...

class test {

    static {
	System.out.println("Loading libnative");
	System.loadLibrary("native");
	System.out.println("libnative loaded");
    }

    native void foo();

    public test() {
	System.out.println("Before foo");
	foo();
	System.out.println("After foo");
    }

    public static void main(String[] args) {
	test t = new test();
    }
}

compiled with command

/nfs/fideriv/tools/unix/java/jdk1.3/bin/javac test.java

generated jni headers using

/nfs/fideriv/tools/unix/java/jdk1.3/bin/javah -classpath /home/bcraig/work/test
test

Native code in file native.cpp ...

#include <stdlib.h>
#include <iostream.h>
#include "test.h"
#include <jni.h>

void Java_test_foo   (JNIEnv *, jobject) {

  try {
    std::cerr << "Before throwing exception" << std::endl;

    throw 20;

   }
   catch (...) {
     std::cerr << "In foo, caught exception e" << std::endl;
   }

   std::cerr << "After try{} catch() {}" << endl;

}

compiling and linking using workshop 6.0 ...

bcraig@devws91 [test]> /apps/workshop6_u1/bin/CC -V
CC: Sun WorkShop 6 update 1 C++ 5.2 2000/09/11

compile native file using command ....

/apps/workshop6_u1/bin/CC -g -I/home/bcraig/work/test
-I/nfs/fideriv/tools/unix/java/jdk1.3/include
-I/nfs/fideriv/tools/unix/java/jdk1.3/include/solaris -KPIC -c native.cpp

build shared library using ...

/apps/workshop6_u1/bin/CC -g native.o -Bdynamic -G
-L/nfs/fideriv/tools/unix/java/jdk1.3/jre/lib/sparc -ljvm -lCrun -lCstd -o
libnative.so

ldd -r of libnative.so ...

bcraig@devws91 [test]> ldd -r libnative.so
        libjvm.so =>
/nfs/fideriv/tools/unix/java/jdk1.3/jre/lib/sparc/libjvm.so
        libCrun.so.1 =>  /usr/lib/libCrun.so.1
        libC.so.5 =>     /usr/lib/libC.so.5
        libdl.so.1 =>    /usr/lib/libdl.so.1
        libthread.so.1 =>        /usr/lib/libthread.so.1
        libsocket.so.1 =>        /usr/lib/libsocket.so.1
        libnsl.so.1 =>   /usr/lib/libnsl.so.1
        libm.so.1 =>     /usr/lib/libm.so.1
        libw.so.1 =>     /usr/lib/libw.so.1
        libc.so.1 =>     /usr/lib/libc.so.1
        libmp.so.2 =>    /usr/lib/libmp.so.2
        /usr/platform/SUNW,Ultra-1/lib/libc_psr.so.1

running with jvm

export LD_LIBRARY_PATH=.:/nfs/fideriv/tools/unix/java/jdk1.3/jre/lib/sparc

/nfs/fideriv/tools/unix/java/jdk1.3/bin/java -classpath /home/bcraig/work/test
test
Loading libnative
libnative loaded
Before foo
Before throwing exception
Abort

We have tried this on Solaris 2.6
using 1.2.2 jdk.

I can only currently get it to work using 1.2.1_04 jdk.

We also wrote a native piece of code that starts a JVM using jni, then loads and
calls test.main() this appears to work.
(Review ID: 116076)
======================================================================

Comments
EVALUATION Closing this bug as a duplicate of bug 4389172. I have also included some info from the javadocs and C++ docs that make references to compiling in standard mode versus compatibility mode. This is in the C++ compiler readme's Gary 2. New Compiler Options ======================= The following new options are now in place and apply to SPARC processors only; please refer to the CC.1 man page or C++ User's Guide for details: -compat The C++ compiler has two principal modes, one accepts ARM semantics and language defined by the 4.2 compiler (compatibility mode). The other accepts constructs according to the ANSI/ISO standard (standard mode). These two modes are incompatible with each other because the ANSI/ISO standard forces significant, incompatible changes in name mangling, vtable layout and other ABI details. These two modes are differentiated by the -compat option as follows: -compat -compat=4 Sets the compiler for compatibility with C++ 4.0.1, C++ 4.1, and C++ 4.2 compilers. (Specifying -compat is equivalent to specifying -compat=4.) -compat=5 Sets the compiler for compatibility with full C++ 5.0 features. The default is -compat=5. Here are some java docs that shed light on this. http://java.sun.com/j2se/1.3/docs/guide/jni/spec/design.doc.html goto site above and then look for mangling, the use of mangling implies the use of C++ conventions.
11-06-2004