native methods in inner classes (long)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <stdio.h>


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;
}

Attachment: pgpi2zB77EBzb.pgp
Description: PGP signature


[Index of Archives]     [Linux Kernel]     [Linux Cryptography]     [Fedora]     [Fedora Directory]     [Red Hat Development]

  Powered by Linux