/*
* Copyright ( C ) 2008 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 .
*/
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
/**
* A class loader with atypical behavior : we try to load a private
* class implementation before asking the system or boot loader . This
* is used to create multiple classes with identical names in a single VM .
*
* If DexFile is available , we use that ; if not , we assume we ' re not in
* Dalvik and instantiate the class with defineClass ( ) .
*
* The location of the DEX files and class data is dependent upon the
* test framework .
*/
public class FancyLoader extends ClassLoader {
/* this is where the "alternate" .class files live */
static final String CLASS_PATH = "classes-ex/" ;
/* this is the "alternate" DEX/Jar file */
static final String DEX_FILE = System.getenv("DEX_LOCATION" ) + "/068-classloader-ex.jar" ;
/* on Dalvik, this is a DexFile; otherwise, it's null */
private Class <?> mDexClass;
private Object mDexFile;
/**
* Construct FancyLoader , grabbing a reference to the DexFile class
* if we ' re running under Dalvik .
*/
public FancyLoader(ClassLoader parent) {
super (parent);
try {
mDexClass = parent.loadClass("dalvik.system.DexFile" );
} catch (ClassNotFoundException cnfe) {
// ignore -- not running Dalvik
}
}
/**
* Finds the class with the specified binary name .
*
* We search for a file in CLASS_PATH or pull an entry from DEX_FILE .
* If we don ' t find a match , we throw an exception .
*/
protected Class <?> findClass(String name) throws ClassNotFoundException
{
if (mDexClass != null ) {
return findClassDalvik(name);
} else {
return findClassNonDalvik(name);
}
}
/**
* Finds the class with the specified binary name , from a DEX file .
*/
private Class <?> findClassDalvik(String name)
throws ClassNotFoundException {
if (mDexFile == null ) {
synchronized (FancyLoader.class ) {
Constructor<?> ctor;
/*
* Construct a DexFile object through reflection .
*/
try {
ctor = mDexClass.getConstructor(String.class );
} catch (NoSuchMethodException nsme) {
throw new ClassNotFoundException("getConstructor failed" ,
nsme);
}
try {
mDexFile = ctor.newInstance(DEX_FILE);
} catch (InstantiationException ie) {
throw new ClassNotFoundException("newInstance failed" , ie);
} catch (IllegalAccessException iae) {
throw new ClassNotFoundException("newInstance failed" , iae);
} catch (InvocationTargetException ite) {
throw new ClassNotFoundException("newInstance failed" , ite);
}
}
}
/*
* Call DexFile . loadClass ( String , ClassLoader ) .
*/
Method meth;
try {
meth = mDexClass.getMethod("loadClass" , String.class , ClassLoader.class );
} catch (NoSuchMethodException nsme) {
throw new ClassNotFoundException("getMethod failed" , nsme);
}
try {
meth.invoke(mDexFile, name, this );
} catch (IllegalAccessException iae) {
throw new ClassNotFoundException("loadClass failed" , iae);
} catch (InvocationTargetException ite) {
throw new ClassNotFoundException("loadClass failed" ,
ite.getCause());
}
return null ;
}
/**
* Finds the class with the specified binary name , from . class files .
*/
private Class <?> findClassNonDalvik(String name)
throws ClassNotFoundException {
String pathName = CLASS_PATH + name + ".class" ;
//System.out.println("--- Fancy: looking for " + pathName);
File path = new File(pathName);
RandomAccessFile raf;
try {
raf = new RandomAccessFile(path, "r" );
} catch (FileNotFoundException fnfe) {
throw new ClassNotFoundException("Not found: " + pathName);
}
/* read the entire file in */
byte [] fileData;
try {
fileData = new byte [(int ) raf.length()];
raf.readFully(fileData);
} catch (IOException ioe) {
throw new ClassNotFoundException("Read error: " + pathName);
} finally {
try {
raf.close();
} catch (IOException ioe) {
// drop
}
}
/* create the class */
//System.out.println("--- Fancy: defining " + name);
try {
return defineClass(name, fileData, 0 , fileData.length);
} catch (Throwable th) {
throw new ClassNotFoundException("defineClass failed" , th);
}
}
/**
* Load a class .
*
* Normally a class loader wouldn ' t override this , but we want our
* version of the class to take precedence over an already - loaded
* version .
*
* We still want the system classes ( e . g . java . lang . Object ) from the
* bootstrap class loader .
*/
protected Class <?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
Class <?> res;
/*
* 1 . Invoke findLoadedClass ( String ) to check if the class has
* already been loaded .
*
* This doesn ' t change .
*/
res = findLoadedClass(name);
if (res != null ) {
System.out.println("FancyLoader.loadClass: "
+ name + " already loaded" );
if (resolve)
resolveClass(res);
return res;
}
/*
* 3 . Invoke the findClass ( String ) method to find the class .
*/
try {
res = findClass(name);
if (resolve)
resolveClass(res);
}
catch (ClassNotFoundException e) {
// we couldn't find it, so eat the exception and keep going
}
/*
* 2 . Invoke the loadClass method on the parent class loader . If
* the parent loader is null the class loader built - in to the
* virtual machine is used , instead .
*
* ( Since we ' re not in java . lang , we can ' t actually invoke the
* parent ' s loadClass ( ) method , but we passed our parent to the
* super - class which can take care of it for us . )
*/
res = super .loadClass(name, resolve); // returns class or throws
return res;
}
}
Messung V0.5 in Prozent C=87 H=98 G=92
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-06-29)
¤
*© Formatika GbR, Deutschland