Is this not possible or am I doing it wrong?
I want a native method of a class to create an instance of an inner class.
/* A class with an inner class */
public final class A {
public B method_X() {
...
return new B(y, p, o);
}
public B method_Y() {
...
return native_I(...)
}
private native B native_I(...);
public final class B {
// some members
private B(String y, int p, boolean o) {
....
}
}
}
JNIEXPORT ....native_I(JNIEnv *env, jobject obj, ...) {
...
jclass cls = (*env)->FindClass(env, "com/..../A.B);
jmethodid mid = (*env)->GetMethodID(env, cls, "<init>",
"(Ljava/lang/String;IZ)V");
...
}
The FindClass is throwing NoClassDefFoundError
Is that
a. because it cannot handle inner classes
b. because I have written the name wrong
c. I don't know what I am talking about
d. ...
TIA

Signature
Bill Medland
Chris Uppal - 20 Jul 2006 08:50 GMT
> jclass cls = (*env)->FindClass(env, "com/..../A.B);
This is wrong -- the name of the class will be something like com/.../A$B.
Look in your filesystem and/or JAR file to find the real name.
It's helpful to keep in mind that there are no such things as nested,
anonymous, or inner classes in real Java -- they are just faked by the compiler
which creates proper top-level classes from what look like nested classes.
> jmethodid mid = (*env)->GetMethodID(env, cls, "<init>",
> "(Ljava/lang/String;IZ)V");
This is also wrong. Because A$B is not static, it has an extra (supplied by
the compiler) field which points to its "outer", and it uses that field (plus
extra synthetic methods if necessary) to implement its privileged access to
that object. (More fakery by the compiler). Of course that field has to be
initialised, and so the compiler adds an extra argument to each constructor. I
forget whether it's the first or last, but javap on the A$B.class classfile
will tell you.
BTW, don't take my repeated use of the word "wrong" as criticising you -- if
there is any fault here it is in the people who came up with the absurd idea of
faking semantics in the compiler.
-- chris