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 1764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes#include "class_linker.h" 1864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes#include "jni_internal.h" 192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h" 204f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "mirror/object-inl.h" 2100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 2264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes#include "ScopedUtfChars.h" 2364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes#include "zip_archive.h" 2464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 2564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughesnamespace art { 2664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 270512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jclass VMClassLoader_findLoadedClass(JNIEnv* env, jclass, jobject javaLoader, jstring javaName) { 2800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* loader = soa.Decode<mirror::ClassLoader*>(javaLoader); 3064bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes ScopedUtfChars name(env, javaName); 3164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes if (name.c_str() == NULL) { 3264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes return NULL; 3364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes } 3464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 35f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom std::string descriptor(DotToDescriptor(name.c_str())); 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* c = Runtime::Current()->GetClassLinker()->LookupClass(descriptor.c_str(), loader); 37be125a931c8cf7274345c69b2bf35fb6e66e4001Ian Rogers if (c != NULL && c->IsResolved()) { 3800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jclass>(c); 39be125a931c8cf7274345c69b2bf35fb6e66e4001Ian Rogers } else { 40be125a931c8cf7274345c69b2bf35fb6e66e4001Ian Rogers // Class wasn't resolved so it may be erroneous or not yet ready, force the caller to go into 41be125a931c8cf7274345c69b2bf35fb6e66e4001Ian Rogers // the regular loadClass code. 42be125a931c8cf7274345c69b2bf35fb6e66e4001Ian Rogers return NULL; 43be125a931c8cf7274345c69b2bf35fb6e66e4001Ian Rogers } 4464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes} 4564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 461bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesstatic jint VMClassLoader_getBootClassPathSize(JNIEnv*, jclass) { 4764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes return Runtime::Current()->GetClassLinker()->GetBootClassPath().size(); 4864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes} 4964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 5064bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes/* 5164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * Returns a string URL for a resource with the specified 'javaName' in 5264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * entry 'index' of the boot class path. 5364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * 5464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * We return a newly-allocated String in the following form: 5564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * 5664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * jar:file://path!/name 5764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * 5864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * Where "path" is the bootstrap class path entry and "name" is the string 5964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * passed into this method. "path" needs to be an absolute path (starting 6064bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * with '/'); if it's not we'd need to make it absolute as part of forming 6164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes * the URL string. 6264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes */ 630512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jstring VMClassLoader_getBootClassPathResource(JNIEnv* env, jclass, jstring javaName, jint index) { 6464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes ScopedUtfChars name(env, javaName); 6564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes if (name.c_str() == NULL) { 6664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes return NULL; 6764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes } 6864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 6964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes const std::vector<const DexFile*>& path = Runtime::Current()->GetClassLinker()->GetBootClassPath(); 7064bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes if (index < 0 || size_t(index) >= path.size()) { 7164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes return NULL; 7264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes } 7364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes const DexFile* dex_file = path[index]; 7464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes const std::string& location(dex_file->GetLocation()); 7564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes UniquePtr<ZipArchive> zip_archive(ZipArchive::Open(location)); 7664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes if (zip_archive.get() == NULL) { 7764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes return NULL; 7864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes } 7964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes UniquePtr<ZipEntry> zip_entry(zip_archive->Find(name.c_str())); 8064bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes if (zip_entry.get() == NULL) { 8164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes return NULL; 8264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes } 8364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 8464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes std::string url; 8564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes StringAppendF(&url, "jar:file://%s!/%s", location.c_str(), name.c_str()); 8664bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes return env->NewStringUTF(url.c_str()); 8764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes} 8864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 8964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughesstatic JNINativeMethod gMethods[] = { 9064bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes NATIVE_METHOD(VMClassLoader, findLoadedClass, "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;"), 9164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes NATIVE_METHOD(VMClassLoader, getBootClassPathResource, "(Ljava/lang/String;I)Ljava/lang/String;"), 9264bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes NATIVE_METHOD(VMClassLoader, getBootClassPathSize, "()I"), 9364bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes}; 9464bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 9564bf5a33d55aa779ef452552a466943002d39e4fElliott Hughesvoid register_java_lang_VMClassLoader(JNIEnv* env) { 96eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("java/lang/VMClassLoader"); 9764bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes} 9864bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes 9964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes} // namespace art 100