diff options
| author | 2017-09-22 01:17:18 +0000 | |
|---|---|---|
| committer | 2017-09-22 01:17:18 +0000 | |
| commit | 594bccc1280408243d834c60ac1329b0a68bf0c2 (patch) | |
| tree | ccfc7222139cebbb1413e79ecdb434a133b4c89f /runtime/java_vm_ext.cc | |
| parent | f4ef5c6e2554c904ef9c088de9a63ae8b7c854e4 (diff) | |
| parent | fd03f1ef004b194a3408f52a8812e1f47b21b6cc (diff) | |
Merge "ART: Improve double-JNI-load exception message"
Diffstat (limited to 'runtime/java_vm_ext.cc')
| -rw-r--r-- | runtime/java_vm_ext.cc | 38 | 
1 files changed, 36 insertions, 2 deletions
| diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc index 1593577625..c0d1861a8e 100644 --- a/runtime/java_vm_ext.cc +++ b/runtime/java_vm_ext.cc @@ -35,6 +35,7 @@  #include "mirror/class_loader.h"  #include "nativebridge/native_bridge.h"  #include "nativehelper/ScopedLocalRef.h" +#include "nativehelper/ScopedUtfChars.h"  #include "nativeloader/native_loader.h"  #include "object_callbacks.h"  #include "parsed_options.h" @@ -833,9 +834,42 @@ bool JavaVMExt::LoadNativeLibrary(JNIEnv* env,        // The library will be associated with class_loader. The JNI        // spec says we can't load the same library into more than one        // class loader. +      // +      // This isn't very common. So spend some time to get a readable message. +      auto call_to_string = [&](jobject obj) -> std::string { +        if (obj == nullptr) { +          return "null"; +        } +        // Handle jweaks. Ignore double local-ref. +        ScopedLocalRef<jobject> local_ref(env, env->NewLocalRef(obj)); +        if (local_ref != nullptr) { +          ScopedLocalRef<jclass> local_class(env, env->GetObjectClass(local_ref.get())); +          jmethodID to_string = env->GetMethodID(local_class.get(), +                                                 "toString", +                                                 "()Ljava/lang/String;"); +          DCHECK(to_string != nullptr); +          ScopedLocalRef<jobject> local_string(env, +                                               env->CallObjectMethod(local_ref.get(), to_string)); +          if (local_string != nullptr) { +            ScopedUtfChars utf(env, reinterpret_cast<jstring>(local_string.get())); +            if (utf.c_str() != nullptr) { +              return utf.c_str(); +            } +          } +          env->ExceptionClear(); +          return "(Error calling toString)"; +        } +        return "null"; +      }; +      std::string old_class_loader = call_to_string(library->GetClassLoader()); +      std::string new_class_loader = call_to_string(class_loader);        StringAppendF(error_msg, "Shared library \"%s\" already opened by " -          "ClassLoader %p; can't open in ClassLoader %p", -          path.c_str(), library->GetClassLoader(), class_loader); +          "ClassLoader %p(%s); can't open in ClassLoader %p(%s)", +          path.c_str(), +          library->GetClassLoader(), +          old_class_loader.c_str(), +          class_loader, +          new_class_loader.c_str());        LOG(WARNING) << *error_msg;        return false;      } |