Issue calling JNI_GetCreatedJavaVMs in native code

2,807 views
Skip to first unread message

KK

unread,
Jan 13, 2010, 5:01:36 AM1/13/10
to android-ndk
Hi,

I have some native code which I am trying to port onto Android. At
one point I have to call a Java callback from my native code. This
code is being executed from a thread created in native layer itself.
So I am trying to call JNI_GetCreatedJavaVMs to get the VM reference.
But while compiling I am getting the following error

undefined reference to `JNI_GetCreatedJavaVMs'
collect2: ld returned 1 exit status
make: *** [out/apps/san-angeles//libsanangeles.so] Error 1


Please tell me what to do regarding this. I tried looking up for
libjvm.so, but could not find it in android.

Thanks
KK

fadden

unread,
Jan 13, 2010, 2:25:00 PM1/13/10
to android-ndk
On Jan 13, 2:01 am, KK <krishnakumar.ramachand...@gmail.com> wrote:
> undefined reference to `JNI_GetCreatedJavaVMs'
> collect2: ld returned 1 exit status
> make: *** [out/apps/san-angeles//libsanangeles.so] Error 1
>
> Please tell me what to do regarding this. I tried looking up for
> libjvm.so, but could not find it in android.

It's there, in libdvm.so.

% arm-eabi-nm out/target/product/*/symbols/system/lib/libdvm.so | grep
GetCreated
0003da00 T JNI_GetCreatedJavaVMs

David Turner

unread,
Jan 13, 2010, 5:21:19 PM1/13/10
to andro...@googlegroups.com
Note that libdvm is *not* exposed by the NDK.

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




Krishnakumar Ramachandran

unread,
Jan 13, 2010, 8:58:51 PM1/13/10
to andro...@googlegroups.com
So does that mean if I use libdvm.so in ndk, tommorrow there might be a change that breaks my code?

iblues

unread,
Jan 14, 2010, 3:04:20 AM1/14/10
to android-ndk
Hi KK,

I am sure that this is not the best way to code, but you can follow
the following crude approach :

declare a static instance of the JavaVM object in ur JNI code and pass
the same during the call JNI_CreateJavaVM(&mJavaVM, &env, &initArgs) .

Now you can use this instance during the callback directly. Just make
sure that you are releasing this instance object properly during de-
init.

Regards,
Syed

On Jan 14, 10:58 am, Krishnakumar Ramachandran


<krishnakumar.ramachand...@gmail.com> wrote:
> So does that mean if I use libdvm.so in ndk, tommorrow there might be a
> change that breaks my code?
>
>
>
> On Thu, Jan 14, 2010 at 3:51 AM, David Turner <di...@android.com> wrote:
> > Note that libdvm is *not* exposed by the NDK.
>
> > On Wed, Jan 13, 2010 at 11:25 AM, fadden <fad...@android.com> wrote:
>
> >> On Jan 13, 2:01 am, KK <krishnakumar.ramachand...@gmail.com> wrote:
> >> > undefined reference to `JNI_GetCreatedJavaVMs'
> >> > collect2: ld returned 1 exit status
> >> > make: *** [out/apps/san-angeles//libsanangeles.so] Error 1
>
> >> > Please tell me what to do regarding this. I tried looking up for
> >> > libjvm.so, but could not find it in android.
>
> >> It's there, in libdvm.so.
>
> >> % arm-eabi-nm out/target/product/*/symbols/system/lib/libdvm.so | grep
> >> GetCreated
> >> 0003da00 T JNI_GetCreatedJavaVMs
>
> >> --
> >> 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<android-ndk%2Bunsubscribe@googlegr oups.com>


> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/android-ndk?hl=en.
>
> > --
> > 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<android-ndk%2Bunsubscribe@googlegr oups.com>

Krishnakumar Ramachandran

unread,
Jan 14, 2010, 5:13:08 AM1/14/10
to andro...@googlegroups.com
Hi Syed,

  Thank You for the help. This approach works fine. But as you told I am not sure whether this is the right way to do it.

Thanks
KK

To unsubscribe from this group, send email to android-ndk...@googlegroups.com.

fadden

unread,
Jan 14, 2010, 4:50:49 PM1/14/10
to android-ndk
On Jan 13, 2:21 pm, David Turner <di...@android.com> wrote:
> Note that libdvm is *not* exposed by the NDK.

My understanding is:

(1) All JNI types, functions, and constants that are described by the
JNI spec, including JNI_GetCreatedJavaVMs, are part of the public
NDK. It's not actually called out in STABLE_APIS.TXT, but you're not
going to get very far without making any JNI calls.

(2) The fact that it happens to be implemented by libdvm.so is *not*
fixed and subject to change. So, explicitly linking against libdvm.so
to resolve the symbol may well break in the future.

Is that correct?

David Turner

unread,
Jan 14, 2010, 7:06:22 PM1/14/10
to andro...@googlegroups.com
Yes, actually <jni.h> only exposes three functions:

jint JNI_GetDefaultJavaVMInitArgs(void*);
jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);

and we do not support application code linking to them.

The reason is that a reference to libdvm.so would embedded in the corresponding
generated shared library, and the code would become unloadable the day we rename
the library (e.g. libdvmJit.so + libdvmInt.so or whatever).

If you *really* need to use these, you should hunt for /system/lib/libvdm.so with dlopen()
and find the symbol addresses with dlsym(), and be prepared to fail nicely if nothing is
found at the usual address.

All other "functions" are really calls through a function table pointer provided by the VM
so it's ok to use them.

Krishnakumar Ramachandran

unread,
Jan 14, 2010, 8:12:43 PM1/14/10
to andro...@googlegroups.com
Got it. Thanks David and fadden

Fergus Henderson

unread,
Mar 25, 2010, 9:00:55 PM3/25/10
to David Turner, andro...@googlegroups.com

Hmm... doing that doesn't conform to the official specification in
STABLE_APIS.TXT,
which doesn't mention anything about "-ldl", <dlfcn.h>, dlopen(), or
dlsym().

David Turner

unread,
Mar 25, 2010, 9:59:06 PM3/25/10
to Fergus Henderson, andro...@googlegroups.com
Actually, this is a bug in the documentation. -ldl should be supported for all API levels supported by the NDK.

andrej sarkic

unread,
Mar 26, 2010, 11:55:11 AM3/26/10
to android-ndk
David,

Thank you for clarifying. What about the hooks JNI_OnLoad and
JNI_OnUnload? That is a place where the JVM pointer can potentially be
cached.

Second, what about using the GetJavaVM call? Any issues with that?

Thanks,
Andrej

On Mar 25, 9:59 pm, David Turner <di...@android.com> wrote:
> Actually, this is a bug in the documentation. -ldl should be supported for
> all API levels supported by the NDK.
>
> On Thu, Mar 25, 2010 at 6:00 PM, Fergus Henderson <
>

fadden

unread,
Mar 26, 2010, 2:16:16 PM3/26/10
to android-ndk
On Mar 26, 8:55 am, andrej sarkic <andrej.sar...@gmail.com> wrote:
> Thank you for clarifying. What about the hooks JNI_OnLoad and
> JNI_OnUnload? That is a place where the JVM pointer can potentially be
> cached.

Supplying a JNI_OnLoad is a fine way to get the JavaVM* when your
shared library is loaded.

> Second, what about using the GetJavaVM call? Any issues with that?

It's one of the methods accessed through a function table pointer
(JNIEnv*), so it's fine. You do need a (thread-specific) JNIEnv*
first.

Karl Semich

unread,
Feb 12, 2021, 7:05:36 PM2/12/21
to android-ndk
To follow up a decade later,

On Thursday, January 14, 2010 at 7:06:22 PM UTC-5 Digit wrote:
jint JNI_GetDefaultJavaVMInitArgs(void*);
jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);

and we do not support application code linking to them.

The reason is that a reference to libdvm.so would embedded in the corresponding
generated shared library, and the code would become unloadable the day we rename
the library (e.g. libdvmJit.so + libdvmInt.so or whatever).

If you *really* need to use these, you should hunt for /system/lib/libvdm.so with dlopen()
and find the symbol addresses with dlsym(), and be prepared to fail nicely if nothing is
found at the usual address.

I tried doing this, and the symbol does load, but the resulting JNI_GetCreatedJavaVMs() is returning a completely empty array for me.   It's unfortunate that when porting libraries to android we have to alter the interface to let the user pass in a JNIEnv pointer, if android java functionality is used in the port.

I have not tried creating a new VM at this time.

Karl

unread,
Feb 16, 2021, 5:36:45 PM2/16/21
to android-ndk
Here's the up-to-date information: https://github.com/android/ndk/issues/1320
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "android-ndk" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/android-ndk/IVvYWu4CNIY/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> android-ndk...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/android-ndk/5907d1ba-26e8-4af8-a67c-ad3cc632f33fn%40googlegroups.com.
>
Reply all
Reply to author
Forward
0 new messages