| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package dalvik.system; |
| |
| import java.io.File; |
| import java.net.URL; |
| import java.util.Enumeration; |
| |
| /** |
| * Base class for common functionality between various dex-based |
| * {@link ClassLoader} implementations. |
| */ |
| public class BaseDexClassLoader extends ClassLoader { |
| private final DexPathList pathList; |
| |
| /** |
| * Constructs an instance. |
| * |
| * @param dexPath the list of jar/apk files containing classes and |
| * resources, delimited by {@code File.pathSeparator}, which |
| * defaults to {@code ":"} on Android |
| * @param optimizedDirectory directory where optimized dex files |
| * should be written; may be {@code null} |
| * @param libraryPath the list of directories containing native |
| * libraries, delimited by {@code File.pathSeparator}; may be |
| * {@code null} |
| * @param parent the parent class loader |
| */ |
| public BaseDexClassLoader(String dexPath, File optimizedDirectory, |
| String libraryPath, ClassLoader parent) { |
| super(parent); |
| this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory); |
| } |
| |
| @Override |
| protected Class<?> findClass(String name) throws ClassNotFoundException { |
| Class c = pathList.findClass(name); |
| if (c == null) { |
| throw new ClassNotFoundException("Didn't find class \"" + name + "\" on path: " + pathList); |
| } |
| return c; |
| } |
| |
| @Override |
| protected URL findResource(String name) { |
| return pathList.findResource(name); |
| } |
| |
| @Override |
| protected Enumeration<URL> findResources(String name) { |
| return pathList.findResources(name); |
| } |
| |
| @Override |
| public String findLibrary(String name) { |
| return pathList.findLibrary(name); |
| } |
| |
| /** |
| * Returns package information for the given package. |
| * Unfortunately, instances of this class don't really have this |
| * information, and as a non-secure {@code ClassLoader}, it isn't |
| * even required to, according to the spec. Yet, we want to |
| * provide it, in order to make all those hopeful callers of |
| * {@code myClass.getPackage().getName()} happy. Thus we construct |
| * a {@code Package} object the first time it is being requested |
| * and fill most of the fields with dummy values. The {@code |
| * Package} object is then put into the {@code ClassLoader}'s |
| * package cache, so we see the same one next time. We don't |
| * create {@code Package} objects for {@code null} arguments or |
| * for the default package. |
| * |
| * <p>There is a limited chance that we end up with multiple |
| * {@code Package} objects representing the same package: It can |
| * happen when when a package is scattered across different JAR |
| * files which were loaded by different {@code ClassLoader} |
| * instances. This is rather unlikely, and given that this whole |
| * thing is more or less a workaround, probably not worth the |
| * effort to address. |
| * |
| * @param name the name of the class |
| * @return the package information for the class, or {@code null} |
| * if there is no package information available for it |
| */ |
| @Override |
| protected synchronized Package getPackage(String name) { |
| if (name != null && !name.isEmpty()) { |
| Package pack = super.getPackage(name); |
| |
| if (pack == null) { |
| pack = definePackage(name, "Unknown", "0.0", "Unknown", |
| "Unknown", "0.0", "Unknown", null); |
| } |
| |
| return pack; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * @hide |
| */ |
| public String getLdLibraryPath() { |
| StringBuilder result = new StringBuilder(); |
| for (File directory : pathList.getNativeLibraryDirectories()) { |
| if (result.length() > 0) { |
| result.append(':'); |
| } |
| result.append(directory); |
| } |
| return result.toString(); |
| } |
| |
| @Override public String toString() { |
| return getClass().getName() + "[" + pathList + "]"; |
| } |
| } |