diff options
| -rw-r--r-- | src/jni_internal.cc | 33 | ||||
| -rw-r--r-- | src/native/java_lang_Runtime.cc | 27 | ||||
| -rw-r--r-- | src/well_known_classes.cc | 2 |
3 files changed, 38 insertions, 24 deletions
diff --git a/src/jni_internal.cc b/src/jni_internal.cc index 8c0c1ec22c..84b5144a3a 100644 --- a/src/jni_internal.cc +++ b/src/jni_internal.cc @@ -57,17 +57,6 @@ static size_t gGlobalsMax = 51200; // Arbitrary sanity check. static const size_t kWeakGlobalsInitial = 16; // Arbitrary. static const size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check. -void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods, - size_t method_count) { - ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name)); - if (c.get() == NULL) { - LOG(FATAL) << "Couldn't find class: " << jni_class_name; - } - if (env->RegisterNatives(c.get(), methods, method_count) != JNI_OK) { - LOG(FATAL) << "Failed to register natives methods: " << jni_class_name; - } -} - void SetJniGlobalsMax(size_t max) { if (max != 0) { gGlobalsMax = max; @@ -2021,10 +2010,14 @@ class JNI { } static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods, jint method_count) { + return RegisterNativeMethods(env, java_class, methods, method_count, true); + } + + static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods, size_t method_count, bool return_errors) { ScopedObjectAccess soa(env); Class* c = soa.Decode<Class*>(java_class); - for (int i = 0; i < method_count; i++) { + for (size_t i = 0; i < method_count; ++i) { const char* name = methods[i].name; const char* sig = methods[i].signature; @@ -2038,11 +2031,14 @@ class JNI { m = c->FindVirtualMethod(name, sig); } if (m == NULL) { - LOG(INFO) << "Failed to register native method " << name << sig; + LOG(return_errors ? ERROR : FATAL) << "Failed to register native method " + << PrettyDescriptor(c) << "." << name << sig; ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static"); return JNI_ERR; } else if (!m->IsNative()) { - LOG(INFO) << "Failed to register non-native method " << name << sig << " as native"; + LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method " + << PrettyDescriptor(c) << "." << name << sig + << " as native"; ThrowNoSuchMethodError(soa, c, name, sig, "native"); return JNI_ERR; } @@ -2877,6 +2873,15 @@ void JavaVMExt::VisitRoots(Heap::RootVisitor* visitor, void* arg) { // The weak_globals table is visited by the GC itself (because it mutates the table). } +void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods, + size_t method_count) { + ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name)); + if (c.get() == NULL) { + LOG(FATAL) << "Couldn't find class: " << jni_class_name; + } + JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false); +} + } // namespace art std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) { diff --git a/src/native/java_lang_Runtime.cc b/src/native/java_lang_Runtime.cc index 6dc850e83f..d197b7340f 100644 --- a/src/native/java_lang_Runtime.cc +++ b/src/native/java_lang_Runtime.cc @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <dlfcn.h> #include <limits.h> #include <unistd.h> @@ -36,20 +37,28 @@ static void Runtime_nativeExit(JNIEnv*, jclass, jint status) { exit(status); } -/* - * static String nativeLoad(String filename, ClassLoader loader) - * - * Load the specified full path as a dynamic library filled with - * JNI-compatible methods. Returns null on success, or a failure - * message on failure. - */ -static jstring Runtime_nativeLoad(JNIEnv* env, jclass, jstring javaFilename, jobject javaLoader) { +static jstring Runtime_nativeLoad(JNIEnv* env, jclass, jstring javaFilename, jobject javaLoader, jstring javaLdLibraryPath) { ScopedObjectAccess soa(env); ScopedUtfChars filename(env, javaFilename); if (filename.c_str() == NULL) { return NULL; } + if (javaLdLibraryPath != NULL) { + ScopedUtfChars ldLibraryPath(env, javaLdLibraryPath); + if (ldLibraryPath.c_str() == NULL) { + return NULL; + } + void* sym = dlsym(RTLD_DEFAULT, "android_update_LD_LIBRARY_PATH"); + if (sym != NULL) { + typedef void (*Fn)(const char*); + Fn android_update_LD_LIBRARY_PATH = reinterpret_cast<Fn>(sym); + (*android_update_LD_LIBRARY_PATH)(ldLibraryPath.c_str()); + } else { + LOG(ERROR) << "android_update_LD_LIBRARY_PATH not found; .so dependencies will not work!"; + } + } + ClassLoader* classLoader = soa.Decode<ClassLoader*>(javaLoader); std::string detail; JavaVMExt* vm = Runtime::Current()->GetJavaVM(); @@ -78,7 +87,7 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Runtime, gc, "()V"), NATIVE_METHOD(Runtime, maxMemory, "()J"), NATIVE_METHOD(Runtime, nativeExit, "(I)V"), - NATIVE_METHOD(Runtime, nativeLoad, "(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String;"), + NATIVE_METHOD(Runtime, nativeLoad, "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/String;"), NATIVE_METHOD(Runtime, totalMemory, "()J"), }; diff --git a/src/well_known_classes.cc b/src/well_known_classes.cc index afe6dcd925..2c16be90d3 100644 --- a/src/well_known_classes.cc +++ b/src/well_known_classes.cc @@ -197,7 +197,7 @@ void WellKnownClasses::Init(JNIEnv* env) { void WellKnownClasses::LateInit(JNIEnv* env) { ScopedLocalRef<jclass> java_lang_Runtime(env, env->FindClass("java/lang/Runtime")); - java_lang_Runtime_nativeLoad = CacheMethod(env, java_lang_Runtime.get(), true, "nativeLoad", "(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String;"); + java_lang_Runtime_nativeLoad = CacheMethod(env, java_lang_Runtime.get(), true, "nativeLoad", "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/String;"); } Class* WellKnownClasses::ToClass(jclass global_jclass) { |