📄 classloader.java
字号:
package de.fub.bytecode.util;import java.util.*;import java.io.*;import java.util.zip.*;import de.fub.bytecode.*;import de.fub.bytecode.classfile.*;import de.fub.bytecode.generic.*;/** * <p>Drop in replacement for the standard class loader of the JVM. You can use it * in conjunction with the JavaWrapper to dynamically modify/create classes * as they're requested.</p> * * <p>This class loader recognizes special requests in a distinct * format, i.e., when the name of the requested class contains with * "$$BCEL$$" it calls the createClass() method with that name * (everything bevor the $$BCEL$$ is considered to be the package * name. You can subclass the class loader and override that * method. "Normal" classes class can be modified by overriding the * modifyClass() method which is called just before defineClass().</p> * * <p>There may be a number of packages where you have to use the default * class loader (which may also be faster). You can define the set of packages * where to use the system class loader in the constructor. The default value contains * "java.", "sun.", "javax."</p> * * @version $Id: ClassLoader.java,v 1.6 2001/09/03 09:30:25 dahm Exp $ * @author <A HREF="http://www.berlin.de/~markus.dahm/">M. Dahm</A> * @see JavaWrapper * @see ClassPath */public class ClassLoader extends java.lang.ClassLoader { private Hashtable classes = new Hashtable(); // Hashtable is synchronized luckily private String[] ignored_packages = { "java.", "javax.", "sun." }; public ClassLoader() { } /** @param ignored_packages classes contained in these packages will be loaded * with the system class loader */ public ClassLoader(String[] ignored_packages) { String[] new_p = new String[ignored_packages.length + this.ignored_packages.length]; System.arraycopy(this.ignored_packages, 0, new_p, 0, this.ignored_packages.length); System.arraycopy(ignored_packages, 0, new_p, this.ignored_packages.length, ignored_packages.length); this.ignored_packages = new_p; } protected Class loadClass(String class_name, boolean resolve) throws ClassNotFoundException { Class cl = null; /* First try: lookup hash table. */ if((cl=(Class)classes.get(class_name)) == null) { /* Second try: Load system class using system class loader. You better * don't mess around with them. */ for(int i=0; i < ignored_packages.length; i++) { if(class_name.startsWith(ignored_packages[i])) { cl = Class.forName(class_name); break; } } if(cl == null) { JavaClass clazz = null; /* Third try: Special request? */ if(class_name.indexOf("$$BCEL$$") >= 0) clazz = createClass(class_name); else // Fourth try: Load classes via repository clazz = modifyClass(Repository.lookupClass(class_name)); if(clazz != null) { byte[] bytes = clazz.getBytes(); cl = defineClass(class_name, bytes, 0, bytes.length); } else // Fourth try: Use default class loader cl = Class.forName(class_name); } if(resolve) resolveClass(cl); } classes.put(class_name, cl); return cl; } /** Override this method if you want to alter a class before it gets actually * loaded. Does nothing by default. */ protected JavaClass modifyClass(JavaClass clazz) { return clazz; } /** * Override this method to create you own classes on the fly. The * name contains the special token $$BCEL$$. Everything before that * token is consddered to be a package name. You can encode you own * arguments into the subsequent string. You must regard however not * to use any "illegal" characters, i.e., characters that may not * appear in a Java class name too<br> * * The default implementation interprets the string as a encoded compressed * Java class, unpacks and decodes it with the Utility.decode() method, and * parses thee resulting byte array and returns the resulting JavaClass object. * * @param class_name compressed byte code with "$$BCEL$$" in it */ protected JavaClass createClass(String class_name) { int index = class_name.indexOf("$$BCEL$$"); String real_name = class_name.substring(index + 8); JavaClass clazz = null; try { byte[] bytes = Utility.decode(real_name, true); ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), "foo"); clazz = parser.parse(); } catch(Throwable e) { e.printStackTrace(); return null; } // Adapt the class name to the passed value ConstantPool cp = clazz.getConstantPool(); ConstantClass cl = (ConstantClass)cp.getConstant(clazz.getClassNameIndex(), Constants.CONSTANT_Class); ConstantUtf8 name = (ConstantUtf8)cp.getConstant(cl.getNameIndex(), Constants.CONSTANT_Utf8); name.setBytes(class_name.replace('.', '/')); return clazz; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -