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