⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
字号:
/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License.  Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */package javassist;import java.io.*;import java.util.Hashtable;import java.util.Vector;import java.security.ProtectionDomain;/** * The class loader for Javassist. * * <p>This is a sample class loader using <code>ClassPool</code>. * Unlike a regular class loader, this class loader obtains bytecode * from a <code>ClassPool</code>. * * <p>Note that Javassist can be used without this class loader; programmers * can define their own versions of class loader.  They can run * a program even without any user-defined class loader if that program * is statically translated with Javassist. * This class loader is just provided as a utility class. * * <p>Suppose that an instance of <code>MyTranslator</code> implementing * the interface <code>Translator</code> is responsible for modifying * class files. * The startup program of an application using <code>MyTranslator</code> * should be something like this: * * <ul><pre> * import javassist.*; * * public class Main { *   public static void main(String[] args) throws Throwable { *     MyTranslator myTrans = new MyTranslator(); *     ClassPool cp = ClassPool.getDefault(); *     Loader cl = new Loader(cp); *     cl.addTranslator(cp, myTrans); *     cl.run("MyApp", args); *   } * } * </pre></ul> * * <p>Class <code>MyApp</code> is the main program of the application. * * <p>This program should be executed as follows: * * <ul><pre> * % java Main <i>arg1</i> <i>arg2</i>... * </pre></ul> * * <p>It modifies the class <code>MyApp</code> with a <code>MyTranslator</code> * object before the JVM loads it. * Then it calls <code>main()</code> in <code>MyApp</code> with arguments * <i>arg1</i>, <i>arg2</i>, ... * * <p>This program execution is equivalent to: * * <ul><pre> * % java MyApp <i>arg1</i> <i>arg2</i>... * </pre></ul> * * <p>except that classes are translated by <code>MyTranslator</code> * at load time. * * <p>If only a particular class must be modified when it is loaded, * the startup program can be simpler; <code>MyTranslator</code> is * unnecessary.  For example, if only a class <code>test.Rectangle</code> * is modified, the <code>main()</code> method above will be the following: * * <ul><pre> * ClassPool cp = ClassPool.getDefault(); * Loader cl = new Loader(cp); * CtClass ct = cp.get("test.Rectangle"); * ct.setSuperclass(cp.get("test.Point")); * cl.run("MyApp", args);</pre></ul> * * <p>This program changes the super class of the <code>test.Rectangle</code> * class. * * <p><b>Note 1:</b> * * <p>This class loader does not allow the users to intercept the loading * of <code>java.*</code> and <code>javax.*</code> classes (and * <code>sun.*</code>, <code>org.xml.*</code>, ...) unless * <code>Loader.doDelegation</code> is <code>false</code>.  This is because * the JVM prohibits a user class loader from loading a system class. * Also see Note 2. * If this behavior is not appropriate, a subclass of <code>Loader</code> * must be defined and <code>loadClassByDelegation()</code> must be overridden. * * <p><b>Note 2:</b> * * <p>If classes are loaded with different class loaders, they belong to * separate name spaces.  If class <code>C</code> is loaded by a class * loader <code>CL</code>, all classes that the class <code>C</code> * refers to are also loaded by <code>CL</code>.  However, if <code>CL</code> * delegates the loading of the class <code>C</code> to <code>CL'</code>, * then those classes that the class <code>C</code> refers to * are loaded by a parent class loader <code>CL'</code> * instead of <code>CL</code>. * * <p>If an object of class <code>C</code> is assigned * to a variable of class <code>C</code> belonging to a different name * space, then a <code>ClassCastException</code> is thrown. * * <p>Because of the fact above, this loader delegates only the loading of * <code>javassist.Loader</code> * and classes included in package <code>java.*</code> and * <code>javax.*</code> to the parent class * loader.  Other classes are directly loaded by this loader. * * <p>For example, suppose that <code>java.lang.String</code> would be loaded * by this loader while <code>java.io.File</code> is loaded by the parent * class loader.  If the constructor of <code>java.io.File</code> is called * with an instance of <code>java.lang.String</code>, then it may throw * an exception since it accepts an instance of only the * <code>java.lang.String</code> loaded by the parent class loader. * * @see javassist.ClassPool * @see javassist.Translator */public class Loader extends ClassLoader {    private Hashtable notDefinedHere; // must be atomic.    private Vector notDefinedPackages; // must be atomic.    private ClassPool source;    private Translator translator;    private ProtectionDomain domain;     /**     * Specifies the algorithm of class loading.     *     * <p>This class loader uses the parent class loader for     * <code>java.*</code> and <code>javax.*</code> classes.     * If this variable <code>doDelegation</code>     * is <code>false</code>, this class loader does not delegate those     * classes to the parent class loader.     *     * <p>The default value is <code>true</code>.     */    public boolean doDelegation = true;    /**     * Creates a new class loader.     */    public Loader() {        this(null);    }    /**     * Creates a new class loader.     *     * @param cp        the source of class files.     */    public Loader(ClassPool cp) {        init(cp);    }    /**     * Creates a new class loader     * using the specified parent class loader for delegation.     *     * @param parent    the parent class loader.     * @param cp        the source of class files.     */    public Loader(ClassLoader parent, ClassPool cp) {        super(parent);        init(cp);    }    private void init(ClassPool cp) {        notDefinedHere = new Hashtable();        notDefinedPackages = new Vector();        source = cp;        translator = null;        domain = null;        delegateLoadingOf("javassist.Loader");    }    /**     * Records a class so that the loading of that class is delegated     * to the parent class loader.     *     * <p>If the given class name ends with <code>.</code> (dot), then     * that name is interpreted as a package name.  All the classes     * in that package and the sub packages are delegated.     */    public void delegateLoadingOf(String classname) {        if (classname.endsWith("."))            notDefinedPackages.addElement(classname);        else            notDefinedHere.put(classname, this);    }    /**     * Sets the protection domain for the classes handled by this class     * loader.  Without registering an appropriate protection domain,     * the program loaded by this loader will not work with a security     * manager or a signed jar file.     */    public void setDomain(ProtectionDomain d) {        domain = d;    }    /**     * Sets the soruce <code>ClassPool</code>.     */    public void setClassPool(ClassPool cp) {        source = cp;    }    /**     * Adds a translator, which is called whenever a class is loaded.     *     * @param cp        the <code>ClassPool</code> object for obtaining     *                  a class file.     * @param t         a translator.     * @throws NotFoundException        if <code>t.start()</code> throws an exception.     * @throws CannotCompileException   if <code>t.start()</code> throws an exception.     */    public void addTranslator(ClassPool cp, Translator t)        throws NotFoundException, CannotCompileException {        source = cp;        translator = t;        t.start(cp);    }    /**     * Loads a class with an instance of <code>Loader</code>     * and calls <code>main()</code> of that class.     *     * <p>This method calls <code>run()</code>.     *     * @param args              command line parameters.     * <ul>     * <code>args[0]</code> is the class name to be loaded.     * <br><code>args[1..n]</code> are parameters passed     *                      to the target <code>main()</code>.     * </ul>     *     * @see javassist.Loader#run(String[])     */    public static void main(String[] args) throws Throwable {        Loader cl = new Loader();        cl.run(args);    }    /**     * Loads a class and calls <code>main()</code> in that class.     *     * @param args              command line parameters.     * <ul>     * <code>args[0]</code> is the class name to be loaded.     * <br><code>args[1..n]</code> are parameters passed     *                      to the target <code>main()</code>.     * </ul>     */    public void run(String[] args) throws Throwable {        int n = args.length - 1;        if (n >= 0) {            String[] args2 = new String[n];            for (int i = 0; i < n; ++i)                args2[i] = args[i + 1];            run(args[0], args2);        }    }    /**     * Loads a class and calls <code>main()</code> in that class.     *     * @param classname         the loaded class.     * @param args              parameters passed to <code>main()</code>.     */    public void run(String classname, String[] args) throws Throwable {        Class c = loadClass(classname);        try {            c.getDeclaredMethod("main", new Class[] { String[].class }).invoke(                null,                new Object[] { args });        }        catch (java.lang.reflect.InvocationTargetException e) {            throw e.getTargetException();        }    }    /**     * Requests the class loader to load a class.     */    protected Class loadClass(String name, boolean resolve)        throws ClassFormatError, ClassNotFoundException {        name = name.intern();        synchronized (name) {            Class c = findLoadedClass(name);            if (c == null)                c = loadClassByDelegation(name);            if (c == null)                c = findClass(name);            if (c == null)                c = delegateToParent(name);            if (resolve)                resolveClass(c);            return c;        }    }    /**     * Finds the specified class using <code>ClassPath</code>.     * If the source throws an exception, this returns null.     *     * <p>This method can be overridden by a subclass of     * <code>Loader</code>.  Note that the overridden method must not throw     * an exception when it just fails to find a class file.     *     * @return      null if the specified class could not be found.     * @throws ClassNotFoundException   if an exception is thrown while     *                                  obtaining a class file.     */    protected Class findClass(String name) throws ClassNotFoundException {        byte[] classfile;        try {            if (source != null) {                if (translator != null)                    translator.onLoad(source, name);                try {                    classfile = source.get(name).toBytecode();                }                catch (NotFoundException e) {                    return null;                }            }            else {                String jarname = "/" + name.replace('.', '/') + ".class";                InputStream in = this.getClass().getResourceAsStream(jarname);                if (in == null)                    return null;                classfile = ClassPoolTail.readStream(in);            }        }        catch (Exception e) {            throw new ClassNotFoundException(                "caught an exception while obtaining a class file for "                + name, e);        }        int i = name.lastIndexOf('.');        if (i != -1) {            String pname = name.substring(0, i);            if (getPackage(pname) == null)                try {                    definePackage(                        pname, null, null, null, null, null, null, null);                }                catch (IllegalArgumentException e) {                    // ignore.  maybe the package object for the same                    // name has been created just right away.                }        }        if (domain == null)            return defineClass(name, classfile, 0, classfile.length);        else            return defineClass(name, classfile, 0, classfile.length, domain);    }    protected Class loadClassByDelegation(String name)        throws ClassNotFoundException    {        /* The swing components must be loaded by a system         * class loader.         * javax.swing.UIManager loads a (concrete) subclass         * of LookAndFeel by a system class loader and cast         * an instance of the class to LookAndFeel for         * (maybe) a security reason.  To avoid failure of         * type conversion, LookAndFeel must not be loaded         * by this class loader.         */        Class c = null;        if (doDelegation)            if (name.startsWith("java.")                || name.startsWith("javax.")                || name.startsWith("sun.")                || name.startsWith("com.sun.")                || name.startsWith("org.w3c.")                || name.startsWith("org.xml.")                || notDelegated(name))                c = delegateToParent(name);        return c;    }    private boolean notDelegated(String name) {        if (notDefinedHere.get(name) != null)            return true;        int n = notDefinedPackages.size();        for (int i = 0; i < n; ++i)            if (name.startsWith((String)notDefinedPackages.elementAt(i)))                return true;        return false;    }    protected Class delegateToParent(String classname)        throws ClassNotFoundException    {        ClassLoader cl = getParent();        if (cl != null)            return cl.loadClass(classname);        else            return findSystemClass(classname);    }    protected Package getPackage(String name) {        return super.getPackage(name);    }    /*        // Package p = super.getPackage(name);        Package p = null;        if (p == null)            return definePackage(name, null, null, null,                                 null, null, null, null);        else            return p;    }    */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -