Discussion:
Issue calling JNI_GetCreatedJavaVMs in native code
KK
2010-01-13 10:01:36 UTC
Permalink
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
2010-01-13 19:25:00 UTC
Permalink
Post by KK
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
2010-01-13 22:21:19 UTC
Permalink
Note that libdvm is *not* exposed by the NDK.
Post by fadden
Post by KK
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 unsubscribe from this group, send email to
.
For more options, visit this group at
http://groups.google.com/group/android-ndk?hl=en.
Krishnakumar Ramachandran
2010-01-14 01:58:51 UTC
Permalink
So does that mean if I use libdvm.so in ndk, tommorrow there might be a
change that breaks my code?
Post by David Turner
Note that libdvm is *not* exposed by the NDK.
Post by fadden
Post by KK
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 unsubscribe from this group, send email to
.
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 unsubscribe from this group, send email to
.
For more options, visit this group at
http://groups.google.com/group/android-ndk?hl=en.
iblues
2010-01-14 08:04:20 UTC
Permalink
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
Post by Krishnakumar Ramachandran
So does that mean if I use libdvm.so in ndk, tommorrow there might be a
change that breaks my code?
Post by David Turner
Note that libdvm is *not* exposed by the NDK.
Post by fadden
Post by KK
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 unsubscribe from this group, send email to
.
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 unsubscribe from this group, send email to
.
For more options, visit this group at
http://groups.google.com/group/android-ndk?hl=en.
Krishnakumar Ramachandran
2010-01-14 10:13:08 UTC
Permalink
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
Post by iblues
Hi KK,
I am sure that this is not the best way to code, but you can follow
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
Post by Krishnakumar Ramachandran
So does that mean if I use libdvm.so in ndk, tommorrow there might be a
change that breaks my code?
Post by David Turner
Note that libdvm is *not* exposed by the NDK.
Post by fadden
Post by KK
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
Post by Krishnakumar Ramachandran
Post by David Turner
Post by fadden
"android-ndk" group.
To unsubscribe from this group, send email to
.
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
Post by Krishnakumar Ramachandran
Post by David Turner
"android-ndk" group.
To unsubscribe from this group, send email to
.
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 unsubscribe from this group, send email to
.
For more options, visit this group at
http://groups.google.com/group/android-ndk?hl=en.
fadden
2010-01-14 21:50:49 UTC
Permalink
Post by David Turner
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
2010-01-15 00:06:22 UTC
Permalink
Post by fadden
Post by David Turner
Note that libdvm is *not* exposed by the NDK.
(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?
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.
Post by fadden
--
You received this message because you are subscribed to the Google Groups
"android-ndk" group.
To unsubscribe from this group, send email to
.
For more options, visit this group at
http://groups.google.com/group/android-ndk?hl=en.
Krishnakumar Ramachandran
2010-01-15 01:12:43 UTC
Permalink
Got it. Thanks David and fadden
Post by David Turner
Post by fadden
Post by David Turner
Note that libdvm is *not* exposed by the NDK.
(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?
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.
Post by fadden
--
You received this message because you are subscribed to the Google Groups
"android-ndk" group.
To unsubscribe from this group, send email to
.
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 unsubscribe from this group, send email to
.
For more options, visit this group at
http://groups.google.com/group/android-ndk?hl=en.
Fergus Henderson
2010-03-26 01:00:55 UTC
Permalink
Post by David Turner
Post by fadden
Post by David Turner
Note that libdvm is *not* exposed by the NDK.
(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?
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.
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().
--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to android-***@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.
David Turner
2010-03-26 01:59:06 UTC
Permalink
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 <
Post by David Turner
Post by David Turner
Post by fadden
Post by David Turner
Note that libdvm is *not* exposed by the NDK.
(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?
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
Post by David Turner
with dlopen()
and find the symbol addresses with dlsym(), and be prepared to fail
nicely
Post by David Turner
if nothing is found at the usual address.
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().
--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to android-***@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.
andrej sarkic
2010-03-26 15:55:11 UTC
Permalink
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
Post by David Turner
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 <
Post by David Turner
Post by David Turner
Post by fadden
Post by David Turner
Note that libdvm is *not* exposed by the NDK.
(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?
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
Post by David Turner
with dlopen()
and find the symbol addresses with dlsym(), and be prepared to fail
nicely
Post by David Turner
if nothing is found at the usual address.
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().
--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to android-***@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
2010-03-26 18:16:16 UTC
Permalink
Post by andrej sarkic
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.
Post by andrej sarkic
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.
--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to android-***@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.
Loading...