martin
martin

Reputation:

JNI signatures for nested classes?

I'm trying to use JNI on WindowsXP, java version:

java version "1.6.0_13" Java(TM) SE Runtime Environment (build 1.6.0_13-b03) Java HotSpot(TM) Client VM (build 11.3-b02, mixed mode, sharing)

When trying to get jclass for a nested class

jclass c = env->FindClass ("A$B"); assert (c);

the second line asserts, The same thing works ok on Linux with slightly different version of Java (1.5... IIRC).

I've tried several permutations like

LA$B; A.B LA.B;

but to no avail.

Any advice will be highly appreciated.

Martin

Upvotes: 4

Views: 7950

Answers (2)

Iskren Ivov Chernev
Iskren Ivov Chernev

Reputation: 311

OK, I had a similar experience on Native Android, env->FindClass() would not find a nested class with A$B syntax. I moved stuff around and it wouldn't find even a non-nested class.

What turned out to be the issue is that Java->C++ JNI call can find classes, but if you have pure C++ thread, with jvm->GetEnv / jvm->AttachCurrentThread, this thread can do JNI stuff but not FindClass for some reason.

So my suggestion is if you hit weird FindClass behavior on Android, try to move it to a Java stack (i.e Java calling native method), it might help. Note that you might need NewGlobalRef for the jclass esp if it would be used later from another thread.

P.S. A$B is the correct way to refer to nested classes.

Upvotes: 2

Ronald Blaschke
Ronald Blaschke

Reputation: 4184

Seems like the issue was resolved in this thread.

Update: Oracle moved the the forums, the new location is Signature for nested class?

Here's how the issue was resolved:

Ok, I've finally found the problem. The nested class is compiled into a separate java class object (A$B.class) - a bit unexpecte for C/C++ programmer. I haven't packeged the file thus the class was reported as 'not found'. Interesting it worked on Linux though. Thanks for your help!

Another hint from me: In case FindClass returns null don't just assert and guess. At the very least call env->ExceptionDescribe() to get a stacktrace on stderr. Better still, use env->ExceptionOccurred() to check for the Java exception being thrown, just like you would on any other Java method you call.

Upvotes: 0

Related Questions