164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes/* 264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * Copyright (C) 2008 The Android Open Source Project 364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * 464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * you may not use this file except in compliance with the License. 664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * You may obtain a copy of the License at 764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * 864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * 1064bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * Unless required by applicable law or agreed to in writing, software 1164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 1264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * See the License for the specific language governing permissions and 1464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * limitations under the License. 1564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes */ 1664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 17277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe#include "java_lang_VMClassLoader.h" 18277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe 1964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes#include "class_linker.h" 20b2ec9f5c128673c43f776cbe12c8eeb0a6884ebbDavid Sehr#include "dex/descriptors_names.h" 219e734c7ab4599d7747a05db0dc73c7b668cb6683David Sehr#include "dex/dex_file_loader.h" 2264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes#include "jni_internal.h" 232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h" 244f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "mirror/object-inl.h" 2587583b3de6e811e141f8c97c1f796eb516e8a751Andreas Gampe#include "native_util.h" 26e431e2758d62cf56f7f347f5a8c9d79e41b6dcd7Steven Moreland#include "nativehelper/jni_macros.h" 27373a9b5c718a45ac484afcf4fe6ce84f4bb562b3Andreas Gampe#include "nativehelper/scoped_local_ref.h" 28373a9b5c718a45ac484afcf4fe6ce84f4bb562b3Andreas Gampe#include "nativehelper/scoped_utf_chars.h" 2934ee6842a283afe107f0c1df941393f955323b52Andreas Gampe#include "obj_ptr.h" 300795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_fast_native_object_access-inl.h" 31a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "well_known_classes.h" 3264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes#include "zip_archive.h" 3364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 3464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughesnamespace art { 3564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 3634ee6842a283afe107f0c1df941393f955323b52Andreas Gampe// A class so we can be friends with ClassLinker and access internal methods. 3734ee6842a283afe107f0c1df941393f955323b52Andreas Gampeclass VMClassLoader { 3834ee6842a283afe107f0c1df941393f955323b52Andreas Gampe public: 3934ee6842a283afe107f0c1df941393f955323b52Andreas Gampe static mirror::Class* LookupClass(ClassLinker* cl, 4034ee6842a283afe107f0c1df941393f955323b52Andreas Gampe Thread* self, 4134ee6842a283afe107f0c1df941393f955323b52Andreas Gampe const char* descriptor, 4234ee6842a283afe107f0c1df941393f955323b52Andreas Gampe size_t hash, 4334ee6842a283afe107f0c1df941393f955323b52Andreas Gampe ObjPtr<mirror::ClassLoader> class_loader) 4434ee6842a283afe107f0c1df941393f955323b52Andreas Gampe REQUIRES(!Locks::classlinker_classes_lock_) 4534ee6842a283afe107f0c1df941393f955323b52Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 4634ee6842a283afe107f0c1df941393f955323b52Andreas Gampe return cl->LookupClass(self, descriptor, hash, class_loader); 4734ee6842a283afe107f0c1df941393f955323b52Andreas Gampe } 4834ee6842a283afe107f0c1df941393f955323b52Andreas Gampe 4934ee6842a283afe107f0c1df941393f955323b52Andreas Gampe static ObjPtr<mirror::Class> FindClassInPathClassLoader(ClassLinker* cl, 5034ee6842a283afe107f0c1df941393f955323b52Andreas Gampe ScopedObjectAccessAlreadyRunnable& soa, 5134ee6842a283afe107f0c1df941393f955323b52Andreas Gampe Thread* self, 5234ee6842a283afe107f0c1df941393f955323b52Andreas Gampe const char* descriptor, 5334ee6842a283afe107f0c1df941393f955323b52Andreas Gampe size_t hash, 5434ee6842a283afe107f0c1df941393f955323b52Andreas Gampe Handle<mirror::ClassLoader> class_loader) 5534ee6842a283afe107f0c1df941393f955323b52Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 5634ee6842a283afe107f0c1df941393f955323b52Andreas Gampe ObjPtr<mirror::Class> result; 577d8d8ff0727a7aa9d11c738f13a7e06d3c4c3d68Nicolas Geoffray if (cl->FindClassInBaseDexClassLoader(soa, self, descriptor, hash, class_loader, &result)) { 5834ee6842a283afe107f0c1df941393f955323b52Andreas Gampe return result; 5934ee6842a283afe107f0c1df941393f955323b52Andreas Gampe } 6034ee6842a283afe107f0c1df941393f955323b52Andreas Gampe return nullptr; 6134ee6842a283afe107f0c1df941393f955323b52Andreas Gampe } 6234ee6842a283afe107f0c1df941393f955323b52Andreas Gampe}; 6334ee6842a283afe107f0c1df941393f955323b52Andreas Gampe 647b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogersstatic jclass VMClassLoader_findLoadedClass(JNIEnv* env, jclass, jobject javaLoader, 657b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers jstring javaName) { 6653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ScopedFastNativeObjectAccess soa(env); 670795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier ObjPtr<mirror::ClassLoader> loader = soa.Decode<mirror::ClassLoader>(javaLoader); 6864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes ScopedUtfChars name(env, javaName); 697b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers if (name.c_str() == nullptr) { 707b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers return nullptr; 7164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes } 72ab0ed82ff64ba5a751dcc0a38d0e0c41c53dc923Mathieu Chartier ClassLinker* cl = Runtime::Current()->GetClassLinker(); 7334ee6842a283afe107f0c1df941393f955323b52Andreas Gampe 7434ee6842a283afe107f0c1df941393f955323b52Andreas Gampe // Compute hash once. 75f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom std::string descriptor(DotToDescriptor(name.c_str())); 76e7c9a8c2b8481aafbc6af4ce6229bd361ba24742Mathieu Chartier const size_t descriptor_hash = ComputeModifiedUtf8Hash(descriptor.c_str()); 7734ee6842a283afe107f0c1df941393f955323b52Andreas Gampe 7834ee6842a283afe107f0c1df941393f955323b52Andreas Gampe ObjPtr<mirror::Class> c = VMClassLoader::LookupClass(cl, 7934ee6842a283afe107f0c1df941393f955323b52Andreas Gampe soa.Self(), 8034ee6842a283afe107f0c1df941393f955323b52Andreas Gampe descriptor.c_str(), 8134ee6842a283afe107f0c1df941393f955323b52Andreas Gampe descriptor_hash, 8234ee6842a283afe107f0c1df941393f955323b52Andreas Gampe loader); 837b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers if (c != nullptr && c->IsResolved()) { 8400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jclass>(c); 85be125a931c8cf7274345c69b2bf35fb6e66e4001Ian Rogers } 867c8aa8357196781c811a73d2eb66aaaa1681ce36Jeff Hao // If class is erroneous, throw the earlier failure, wrapped in certain cases. See b/28787733. 877c8aa8357196781c811a73d2eb66aaaa1681ce36Jeff Hao if (c != nullptr && c->IsErroneous()) { 88bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier cl->ThrowEarlierClassFailure(c.Ptr()); 897c8aa8357196781c811a73d2eb66aaaa1681ce36Jeff Hao Thread* self = soa.Self(); 90bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier ObjPtr<mirror::Class> iae_class = 917c8aa8357196781c811a73d2eb66aaaa1681ce36Jeff Hao self->DecodeJObject(WellKnownClasses::java_lang_IllegalAccessError)->AsClass(); 92bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier ObjPtr<mirror::Class> ncdfe_class = 937c8aa8357196781c811a73d2eb66aaaa1681ce36Jeff Hao self->DecodeJObject(WellKnownClasses::java_lang_NoClassDefFoundError)->AsClass(); 94bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier ObjPtr<mirror::Class> exception = self->GetException()->GetClass(); 9572ab684871f870aead76b23cb67deb046107b380Vladimir Marko if (exception == iae_class || exception == ncdfe_class) { 967c8aa8357196781c811a73d2eb66aaaa1681ce36Jeff Hao self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;", 97709b070044354d9f47641f273edacaeeb0240ab7David Sehr c->PrettyDescriptor().c_str()); 987c8aa8357196781c811a73d2eb66aaaa1681ce36Jeff Hao } 997c8aa8357196781c811a73d2eb66aaaa1681ce36Jeff Hao return nullptr; 1007c8aa8357196781c811a73d2eb66aaaa1681ce36Jeff Hao } 10134ee6842a283afe107f0c1df941393f955323b52Andreas Gampe 10234ee6842a283afe107f0c1df941393f955323b52Andreas Gampe // Hard-coded performance optimization: We know that all failed libcore calls to findLoadedClass 10334ee6842a283afe107f0c1df941393f955323b52Andreas Gampe // are followed by a call to the the classloader to actually 10434ee6842a283afe107f0c1df941393f955323b52Andreas Gampe // load the class. 105ab0ed82ff64ba5a751dcc0a38d0e0c41c53dc923Mathieu Chartier if (loader != nullptr) { 106ab0ed82ff64ba5a751dcc0a38d0e0c41c53dc923Mathieu Chartier // Try the common case. 107ab0ed82ff64ba5a751dcc0a38d0e0c41c53dc923Mathieu Chartier StackHandleScope<1> hs(soa.Self()); 10834ee6842a283afe107f0c1df941393f955323b52Andreas Gampe c = VMClassLoader::FindClassInPathClassLoader(cl, 10934ee6842a283afe107f0c1df941393f955323b52Andreas Gampe soa, 11034ee6842a283afe107f0c1df941393f955323b52Andreas Gampe soa.Self(), 11134ee6842a283afe107f0c1df941393f955323b52Andreas Gampe descriptor.c_str(), 11234ee6842a283afe107f0c1df941393f955323b52Andreas Gampe descriptor_hash, 11334ee6842a283afe107f0c1df941393f955323b52Andreas Gampe hs.NewHandle(loader)); 114ab0ed82ff64ba5a751dcc0a38d0e0c41c53dc923Mathieu Chartier if (c != nullptr) { 115ab0ed82ff64ba5a751dcc0a38d0e0c41c53dc923Mathieu Chartier return soa.AddLocalReference<jclass>(c); 116ab0ed82ff64ba5a751dcc0a38d0e0c41c53dc923Mathieu Chartier } 117ab0ed82ff64ba5a751dcc0a38d0e0c41c53dc923Mathieu Chartier } 11834ee6842a283afe107f0c1df941393f955323b52Andreas Gampe 11934ee6842a283afe107f0c1df941393f955323b52Andreas Gampe // The class wasn't loaded, yet, and our fast-path did not apply (e.g., we didn't understand the 12034ee6842a283afe107f0c1df941393f955323b52Andreas Gampe // classloader chain). 1217b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers return nullptr; 12264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes} 12364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 12464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes/* 125ef486052f89f088dfc3fe31f6dce974c8f4ce522Neil Fuller * Returns an array of entries from the boot classpath that could contain resources. 12664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes */ 127ef486052f89f088dfc3fe31f6dce974c8f4ce522Neil Fullerstatic jobjectArray VMClassLoader_getBootClassPathEntries(JNIEnv* env, jclass) { 1287b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers const std::vector<const DexFile*>& path = 1297b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers Runtime::Current()->GetClassLinker()->GetBootClassPath(); 1304b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko jobjectArray array = 1314b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko env->NewObjectArray(path.size(), WellKnownClasses::java_lang_String, nullptr); 1324b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko if (array == nullptr) { 1334b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko DCHECK(env->ExceptionCheck()); 1344b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko return nullptr; 1354b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko } 136ef486052f89f088dfc3fe31f6dce974c8f4ce522Neil Fuller for (size_t i = 0; i < path.size(); ++i) { 137ef486052f89f088dfc3fe31f6dce974c8f4ce522Neil Fuller const DexFile* dex_file = path[i]; 138cb8f9e8a2941971c049b26745ea713c859342d9bAndreas Gampe 139a308a327884920cbb1e3e62964c4b5a01c29af8cCalin Juravle // For multidex locations, e.g., x.jar!classes2.dex, we want to look into x.jar. 14079c87da9d4698ec58ece65af0065eebd55a1cfe0Mathieu Chartier const std::string location(DexFileLoader::GetBaseLocation(dex_file->GetLocation())); 141cb8f9e8a2941971c049b26745ea713c859342d9bAndreas Gampe 1424b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko ScopedLocalRef<jstring> javaPath(env, env->NewStringUTF(location.c_str())); 1434b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko if (javaPath.get() == nullptr) { 1444b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko DCHECK(env->ExceptionCheck()); 1454b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko return nullptr; 1464b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko } 1474b3d690c37dbea09906acd4a05f59c7674f9a2d0Vladimir Marko env->SetObjectArrayElement(array, i, javaPath.get()); 14864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes } 149ef486052f89f088dfc3fe31f6dce974c8f4ce522Neil Fuller return array; 15064bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes} 15164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 15264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughesstatic JNINativeMethod gMethods[] = { 1533b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(VMClassLoader, findLoadedClass, "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;"), 154ef486052f89f088dfc3fe31f6dce974c8f4ce522Neil Fuller NATIVE_METHOD(VMClassLoader, getBootClassPathEntries, "()[Ljava/lang/String;"), 15564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes}; 15664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 15764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughesvoid register_java_lang_VMClassLoader(JNIEnv* env) { 158eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("java/lang/VMClassLoader"); 15964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes} 16064bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 16164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes} // namespace art 162