1ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein/* 2ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * Copyright (C) 2011 The Android Open Source Project 3ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * 4ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * Licensed under the Apache License, Version 2.0 (the "License"); 5ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * you may not use this file except in compliance with the License. 6ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * You may obtain a copy of the License at 7ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * 8ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * http://www.apache.org/licenses/LICENSE-2.0 9ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * 10ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * Unless required by applicable law or agreed to in writing, software 11ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * distributed under the License is distributed on an "AS IS" BASIS, 12ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * See the License for the specific language governing permissions and 14ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * limitations under the License. 15ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein */ 16ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 17ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornsteinpackage dalvik.system; 18ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 19ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornsteinimport java.io.File; 20ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornsteinimport java.net.URL; 21ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornsteinimport java.util.Enumeration; 22ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 23ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein/** 24ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * Base class for common functionality between various dex-based 25ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * {@link ClassLoader} implementations. 26ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein */ 27ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornsteinpublic class BaseDexClassLoader extends ClassLoader { 28ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein /** originally specified path (just used for {@code toString()}) */ 29ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein private final String originalPath; 30ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 3175245fcfe3555e4dd06939b9bae366fd3e43b658Brian Carlstrom /** originally specified library path (just used for {@code toString()}) */ 3275245fcfe3555e4dd06939b9bae366fd3e43b658Brian Carlstrom private final String originalLibraryPath; 3375245fcfe3555e4dd06939b9bae366fd3e43b658Brian Carlstrom 34ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein /** structured lists of path elements */ 35ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein private final DexPathList pathList; 36ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 37ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein /** 38ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * Constructs an instance. 39ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * 40ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * @param dexPath the list of jar/apk files containing classes and 41ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * resources, delimited by {@code File.pathSeparator}, which 42ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * defaults to {@code ":"} on Android 43ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * @param optimizedDirectory directory where optimized dex files 44ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * should be written; may be {@code null} 45ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * @param libraryPath the list of directories containing native 46ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * libraries, delimited by {@code File.pathSeparator}; may be 47ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * {@code null} 48ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * @param parent the parent class loader 49ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein */ 50ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein public BaseDexClassLoader(String dexPath, File optimizedDirectory, 51ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein String libraryPath, ClassLoader parent) { 52ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein super(parent); 53ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 54ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein this.originalPath = dexPath; 5575245fcfe3555e4dd06939b9bae366fd3e43b658Brian Carlstrom this.originalLibraryPath = libraryPath; 56ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein this.pathList = 57ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein new DexPathList(this, dexPath, libraryPath, optimizedDirectory); 58ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein } 59ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 60ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein @Override 61ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein protected Class<?> findClass(String name) throws ClassNotFoundException { 62ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein Class clazz = pathList.findClass(name); 63ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 64ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein if (clazz == null) { 653bbe5318c343b1b7c945be717cc55b4ab15874f2Elliott Hughes throw new ClassNotFoundException("Didn't find class \"" + name + "\" on path: " + originalPath); 66ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein } 67ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 68ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein return clazz; 69ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein } 70ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 71ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein @Override 72ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein protected URL findResource(String name) { 73ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein return pathList.findResource(name); 74ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein } 75ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 76ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein @Override 77ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein protected Enumeration<URL> findResources(String name) { 78ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein return pathList.findResources(name); 79ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein } 80ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 81ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein @Override 82ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein public String findLibrary(String name) { 83ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein return pathList.findLibrary(name); 84ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein } 85ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 86ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein /** 87ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * Returns package information for the given package. 88ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * Unfortunately, instances of this class don't really have this 89ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * information, and as a non-secure {@code ClassLoader}, it isn't 90ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * even required to, according to the spec. Yet, we want to 91ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * provide it, in order to make all those hopeful callers of 92ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * {@code myClass.getPackage().getName()} happy. Thus we construct 93ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * a {@code Package} object the first time it is being requested 94ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * and fill most of the fields with dummy values. The {@code 95ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * Package} object is then put into the {@code ClassLoader}'s 96ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * package cache, so we see the same one next time. We don't 97ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * create {@code Package} objects for {@code null} arguments or 98ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * for the default package. 99ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * 100ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * <p>There is a limited chance that we end up with multiple 101ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * {@code Package} objects representing the same package: It can 102ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * happen when when a package is scattered across different JAR 103ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * files which were loaded by different {@code ClassLoader} 104ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * instances. This is rather unlikely, and given that this whole 105ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * thing is more or less a workaround, probably not worth the 106ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * effort to address. 107ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * 108ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * @param name the name of the class 109ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * @return the package information for the class, or {@code null} 110ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein * if there is no package information available for it 111ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein */ 112ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein @Override 113ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein protected synchronized Package getPackage(String name) { 114ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein if (name != null && !name.isEmpty()) { 115ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein Package pack = super.getPackage(name); 116ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 117ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein if (pack == null) { 118ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein pack = definePackage(name, "Unknown", "0.0", "Unknown", 119ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein "Unknown", "0.0", "Unknown", null); 120ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein } 121ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 122ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein return pack; 123ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein } 124ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 125ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein return null; 126ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein } 127ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein 128ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein @Override 129ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein public String toString() { 13075245fcfe3555e4dd06939b9bae366fd3e43b658Brian Carlstrom return getClass().getName() 13175245fcfe3555e4dd06939b9bae366fd3e43b658Brian Carlstrom + "[dexPath=" + originalPath + ",libraryPath=" + originalLibraryPath + "]"; 132ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein } 133ea52753a0f80fcd70acfe9150ecb854511ff38dbDan Bornstein} 134