Multi threaded callback from native code to java

2,275 views
Skip to first unread message

z0r

unread,
Oct 6, 2010, 7:20:43 AM10/6/10
to android-ndk
Hi all,

I'm building an android application with some native code. This native
code is called from trough JNI.
Now in my native c++ code on the same thread I call:

jclass g_jClazz = env->FindClass("Test/service/TestJni"); // Find
class
jmethodID g_jMID = env->GetStaticMethodID(g_jClazz, "DoSomething",
"()V"); // Find static method
env->CallStaticVoidMethod(g_jClazz, g_jMID); // call static method.

Now this code works just fine. The function DoSomehting(); is called
in Java.

The trouble starts when I do the same from a separate thread:

jint result = jvm->AttachCurrentThread(&env, NULL); // Pointer to jvm
is valid
jclass g_jClazz = env->FindClass("Test/service/TestJni"); // Find
class <-- here it cannot find the class

(jvm is set on the JNI_OnLoad() call)
When retrieving the env via AttachCurrentThread(), the context is
somehow different and it cannot find the class.

Exception:
java.lang.NoClassDefFoundError: [generic]
at dalvik.system.NativeStart.main(Native Method)

How do I make a native callback from an other thread to Java in the
correct way?

Thanks in advance,

Michiel.

Prakash Iyer

unread,
Oct 6, 2010, 8:43:22 AM10/6/10
to andro...@googlegroups.com

Are the two cases same otherwise, ie the same way of loading the library and such? Looks like you have the default class loader in the second case.  think you would benefit by reading up on the JNI doc on the Oracle site which deals with this specific issue.

On Oct 6, 2010 7:58 AM, "z0r" <michiel...@gmail.com> wrote:

Christian Linne

unread,
Oct 6, 2010, 12:33:22 PM10/6/10
to andro...@googlegroups.com
Two issues:
(1)
jint result = jvm->AttachCurrentThread(&env, NULL);

What's the value of  "result"? And what is "env" afterwards?

(2)

jclass g_jClazz = env->FindClass("Test/service/TestJni");
How did you store your "env"? Normally, its validity is lost (or points just somewhere you do not want it does) when you change to another thread, so you may request a new, valid one using
jvm->GetEnv(&env, JNI_VERSION_1_6);
The second effect of that statement is that you will recognize if the VM already knows about your thread. If it does, you do not need to attach the current thread manually (same with detaching, either).

 
2010/10/6 Prakash Iyer <the...@gmail.com>

Are the two cases same otherwise, ie the same way of loading the library and such? Looks like you have the default class loader in the second case.  think you would benefit by reading up on the JNI doc on the Oracle site which deals with this specific issue.

On Oct 6, 2010 7:58 AM, "z0r" <michiel...@gmail.com> wrote:

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.



--
_________
Mit freundlichen Grüßen
Yours sincerely

Christian Linne

Mail (private): linn...@aol.com
Mail (official): Christi...@googlemail.com,
ICQ: 293253013

провод

unread,
Oct 6, 2010, 12:56:59 PM10/6/10
to andro...@googlegroups.com
This is a known problem if your thread was created in native code
(i.e. using pthread_create, not using a Java Thread class).
More info, for example, here:
http://groups.google.com/group/android-ndk/browse_thread/thread/da092bd665ca9ff1

2010/10/6 z0r <michiel...@gmail.com>:

Michiel

unread,
Oct 7, 2010, 7:41:20 AM10/7/10
to andro...@googlegroups.com
The result of the AttachCurrentThread is JNI_OK.
According the JNI doc, GetEnv and AttachCurrentThread return the same env if the thread is connected.
from the JNI docs: ( http://download.oracle.com/javase/1.4.2/docs/guide/jni/spec/invocation.html#wp16436 )
When a thread is attached to the VM, the context class loader is the bootstrap loader.

For what I know the bootstrap loader does NOT load other classes. So how do I tell the VM that I want a particular class to be loader?

Saving an other env pointer is no option as you cannot call function from an other thread on that env context.
--
Michiel Gijbels
www.necrosoft.nl

Clapfoot

unread,
Oct 7, 2010, 11:05:02 AM10/7/10
to android-ndk
Is your routine thread safe? Specifically, when you get the current
env from AttachCurrentThread and then using it in find class is there
the possibility that another thread can come in and execute the same
code? This could cause problems especially if AttachCurrentThread
isn't thread safe (is it?).

Christian Linne

unread,
Oct 7, 2010, 12:48:04 PM10/7/10
to andro...@googlegroups.com
if AttachCurrentThread
isn't thread safe (is it?).

In most cases, yes.


So how do I tell the VM that I want a particular class to be loader?

May this might be of any help, even if it appears a little... obscure in its explanations.

Anyway, you may already take references to the classes you want to work with on JNI_OnLoad and store them for later usage. As long as you create a NewGlobalRef for any of them, they remain valid, even crossing along multiple threads (I've also solved my problems that way, and it worked fine).

2010/10/7 Clapfoot <mark...@gmail.com>
--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.




--

fadden

unread,
Oct 7, 2010, 1:58:26 PM10/7/10
to android-ndk
> For what I know the bootstrap loader does NOT load other classes. So how do
> I tell the VM that I want a particular class to be loader?

A few messages back there's a link to another android-ndk thread that
discusses this.

Olivier Guilyardi

unread,
Oct 8, 2010, 6:11:23 AM10/8/10
to andro...@googlegroups.com

I assume you mean:
http://groups.google.com/group/android-ndk/browse_thread/thread/da092bd665ca9ff1

In this thread you mention a "FAQ: FindClass didn't find my class".

But I cannot find this section in the JNI tips doc on Dalvik git:
http://android.git.kernel.org/?p=platform/dalvik.git;a=blob_plain;f=docs/jni-tips.html;hb=HEAD

Where is the most up-to-date JNI Tips document?

--
Olivier


fadden

unread,
Oct 8, 2010, 4:05:07 PM10/8/10
to android-ndk
On Oct 8, 3:11 am, Olivier Guilyardi <l...@samalyse.com> wrote:
> In this thread you mention a "FAQ: FindClass didn't find my class".
>
> But I cannot find this section in the JNI tips doc on Dalvik git:http://android.git.kernel.org/?p=platform/dalvik.git;a=blob_plain;f=d...

The new version isn't published yet. The bit pasted into the article
is still current.

FWIW, the doc will have three FAQ entries:

FAQ: UnsatisfiedLinkError
FAQ: FindClass didn't find my class
FAQ: Sharing raw data with native code

These seem to be the issues that keep recurring here.
Reply all
Reply to author
Forward
0 new messages