native methods in inner classes (long)
hello all, (this concerns VM implementers so i'm posting it here since it may relate to VMs other than the two i use for my testing) since Jeroen F.'s comments on my recent BigInteger/GMP patch, i've been playing with having an inner class in BigInteger which has all the native methods. the pattern is similar to the class OC (attached). having thought i overcame a bug in how our gjavah generates the header files, i tried running the resulting code with both cacao and jamvm but i kept getting an UnsatisfiedLinkError. i then tried the same code with both RIs 1.4 (1.4.2_12) and 1.5 (1.5.0_08) using a rudimentary Makefile (attached). the results are interesting: * the header file generated by the RI-1.5 emits a signature for the native method of an inner class that looks like so: JNIEXPORT void JNICALL Java_OC_IC_natInit * the one for RI-1.4 looks like so: JNIEXPORT void JNICALL Java_OC_00024IC_natInit * coding the native code (.c file attached) with the first signature and generating the .so library cause an UnsatisfiedLinkError with both RIs. * coding with the second signature etc... works OK! * with both cacao and jamvm, even with the second signature, running the code causes an UnsatisfiedLinkError to be raised. * i haven't tried with ikvm, but an email from JF (http://sourceforge.net/mailarchive/message.php?msg_id=20565848) suggests that ikvm knows how to mangle the names before calling native methods of inner classes. my questions are: 1. do VMs handle differently native method names depending on whether they are defined in an inner class or not? 2. should VMs handle native method calls for inner classes the same way as the RI? TIA + cheers; rsn public class OC { static { System.loadLibrary("dummy"); System.out.println("*** Loaded native library..."); } transient IC _ic; OC() { super(); _ic = new IC(); } public static final void main(String[] args) { new OC(); } private static final class IC { int np; IC() { super(); natInit(); } native void natInit(); } } JAVA_HOME=/opt/j2sdk1.4.2_12 #JAVA_HOME=/opt/jdk1.5.0_08 JAVA=${JAVA_HOME}/bin/java JAVAC=${JAVA_HOME}/bin/javac JAVAH=${JAVA_HOME}/bin/javah JAVA_LIBRARY_PATH=${JAVA_HOME}/jre/lib/i386/server:${JAVA_HOME}/jre/lib/i386:${JAVA_HOME}/lib/i386 CACAO=/data/workspace/cvs/classpath/install/bin/cacao JAMVM=/data/workspace/cvs/classpath/install/bin/jamvm class: ${JAVAC} -classpath . OC.java ## with jdk 1.4 this has to be done on the command line; i.e. ## # /opt/j2sdk1.4.2_12/bin/javah -classpath . -o OC_IC.h OC\$IC jni: ${JAVAH} -classpath . -o OC_IC.h OC$$IC # ${JAVAH} -classpath . -d . OC$$IC lib: gcc -fPIC -g -c -Wall OC_IC.c gcc -I/usr/local/java/include -I/usr/local/java/include/linux -shared -Wl,-soname,libdummy.so -o libdummy.so OC_IC.o -lc run: ${JAVA} -classpath . -Djava.library.path=.:${JAVA_LIBRARY_PATH} OC # ${CACAO} -classpath . -Djava.library.path=.:${JAVA_LIBRARY_PATH} OC # ${JAMVM} -classpath . -Djava.library.path=.:${JAVA_LIBRARY_PATH} OC #include "OC_IC.h" #include JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm __attribute__ ((__unused__)), void *reserved __attribute__ ((__unused__))) { fprintf(stderr, "*** Loading dummy native library...\n"); return (JNI_VERSION_1_2); } /* Java_OC_IC_natInit(JNIEnv *env __attribute__ ((__unused__)), jobject this __attribute__ ((__unused__))) */ JNIEXPORT void JNICALL Java_OC_00024IC_natInit(JNIEnv *env __attribute__ ((__unused__)), jobject this __attribute__ ((__unused__))) { printf("*** ...natInit() not implemented\n"); return; } pgpLCeVWQbuP1.pgp Description: PGP signature
Re: native methods in inner classes (long)
On Wed, 2006-09-20 at 06:02 +1000, Raif S. Naffah wrote: > * with both cacao and jamvm, even with the second signature, running the code > causes an UnsatisfiedLinkError to be raised. That's completely right. gcj can handle it correctly, AFAICT. I'm currently fixing this. > > my questions are: > > 1. do VMs handle differently native method names depending on whether they > are > defined in an inner class or not? No. > > 2. should VMs handle native method calls for inner classes the same way as > the > RI? I'd say, yes. - twisti
Re: native methods in inner classes (long)
On Tue, 2006-09-19 at 23:08 +0200, Christian Thalinger wrote: > On Wed, 2006-09-20 at 06:02 +1000, Raif S. Naffah wrote: > > * with both cacao and jamvm, even with the second signature, running the > > code > > causes an UnsatisfiedLinkError to be raised. > > That's completely right. gcj can handle it correctly, AFAICT. I'm > currently fixing this. Ok, I've commited a patch (thanks go to gcj). - twisti
RE: native methods in inner classes (long)
Raif S. Naffah wrote: > * the header file generated by the RI-1.5 emits a signature > for the native method of an inner class that looks like so: > >JNIEXPORT void JNICALL Java_OC_IC_natInit This looks like a bug in javah. [1] claims they fixed it. > my questions are: > > 1. do VMs handle differently native method names depending on > whether they are defined in an inner class or not? No, at the VM and JNI level there is no difference between inner and outer classes. It is simply a matter of name mangling, which is fully defined in the JNI specification. It really is kind of embarassing that we've all had the same bugs in this ;-) Regards, Jeroen [1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6257087
Re: native methods in inner classes (long)
Hi, On 9/20/06, Jeroen Frijters <[EMAIL PROTECTED]> wrote: Raif S. Naffah wrote: > 1. do VMs handle differently native method names depending on > whether they are defined in an inner class or not? No, at the VM and JNI level there is no difference between inner and outer classes. It is simply a matter of name mangling, which is fully defined in the JNI specification. It really is kind of embarassing that we've all had the same bugs in this ;-) Yes, it is embarassing, especially as I thought I'd implemented that part of the JNI spec pretty well :) Looking at it again shows it specifically mentions handling of underscore (_), semi-colon, open bracket ([) and forward-slash, and the escape sequence for general unicode characters. It doesn't explicitly state the need to handle $, which is probably why we all missed it... Anyway, I'll check a patch in for JamVM tonight. Thanks, Rob. Regards, Jeroen [1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6257087
Re: native methods in inner classes (long)
On Wednesday 20 September 2006 07:36, Christian Thalinger wrote: > On Tue, 2006-09-19 at 23:08 +0200, Christian Thalinger wrote: > > On Wed, 2006-09-20 at 06:02 +1000, Raif S. Naffah wrote: > > > * with both cacao and jamvm, even with the second signature, running > > > the code causes an UnsatisfiedLinkError to be raised. > > > > That's completely right. gcj can handle it correctly, AFAICT. I'm > > currently fixing this. > > Ok, I've commited a patch (thanks go to gcj). works like a charm! thanks + cheers; rsn pgp9wvNmmYQ4G.pgp Description: PGP signature
Re: native methods in inner classes (long)
> "Jeroen" == Jeroen Frijters <[EMAIL PROTECTED]> writes: >> JNIEXPORT void JNICALL Java_OC_IC_natInit Jeroen> This looks like a bug in javah. [1] claims they fixed it. Thanks for finding this. I was worried that I'd have to change everything to check the InnerClasses attribute before doing JNI name mangling... would've been gross. Tom
Re: native methods in inner classes (long)
On Thursday 21 September 2006 06:43, Robert Lougher wrote: > On 9/20/06, Robert Lougher <[EMAIL PROTECTED]> wrote: > > Anyway, I'll check a patch in for JamVM tonight. > > Committed... and it works! thanks + cheers; rsn pgpuQR8oHuNjo.pgp Description: PGP signature
Re: Re: native methods in inner classes (long)
On 9/20/06, Robert Lougher <[EMAIL PROTECTED]> wrote: Anyway, I'll check a patch in for JamVM tonight. Committed... Rob.