169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License. Alternatively, the contents of this file may be used under 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later. 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis, 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License. 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.*; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Hashtable; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Vector; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.security.ProtectionDomain; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The class loader for Javassist. 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This is a sample class loader using <code>ClassPool</code>. 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Unlike a regular class loader, this class loader obtains bytecode 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * from a <code>ClassPool</code>. 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Note that Javassist can be used without this class loader; programmers 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * can define their own versions of class loader. They can run 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * a program even without any user-defined class loader if that program 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * is statically translated with Javassist. 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * This class loader is just provided as a utility class. 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Suppose that an instance of <code>MyTranslator</code> implementing 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the interface <code>Translator</code> is responsible for modifying 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class files. 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The startup program of an application using <code>MyTranslator</code> 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * should be something like this: 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre> 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * import javassist.*; 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public class Main { 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public static void main(String[] args) throws Throwable { 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * MyTranslator myTrans = new MyTranslator(); 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ClassPool cp = ClassPool.getDefault(); 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Loader cl = new Loader(cp); 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * cl.addTranslator(cp, myTrans); 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * cl.run("MyApp", args); 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul> 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Class <code>MyApp</code> is the main program of the application. 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This program should be executed as follows: 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre> 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * % java Main <i>arg1</i> <i>arg2</i>... 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul> 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>It modifies the class <code>MyApp</code> with a <code>MyTranslator</code> 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * object before the JVM loads it. 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Then it calls <code>main()</code> in <code>MyApp</code> with arguments 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <i>arg1</i>, <i>arg2</i>, ... 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This program execution is equivalent to: 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre> 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * % java MyApp <i>arg1</i> <i>arg2</i>... 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul> 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>except that classes are translated by <code>MyTranslator</code> 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * at load time. 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>If only a particular class must be modified when it is loaded, 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the startup program can be simpler; <code>MyTranslator</code> is 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * unnecessary. For example, if only a class <code>test.Rectangle</code> 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * is modified, the <code>main()</code> method above will be the following: 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre> 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ClassPool cp = ClassPool.getDefault(); 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Loader cl = new Loader(cp); 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * CtClass ct = cp.get("test.Rectangle"); 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ct.setSuperclass(cp.get("test.Point")); 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * cl.run("MyApp", args);</pre></ul> 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This program changes the super class of the <code>test.Rectangle</code> 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class. 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><b>Note 1:</b> 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This class loader does not allow the users to intercept the loading 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * of <code>java.*</code> and <code>javax.*</code> classes (and 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>sun.*</code>, <code>org.xml.*</code>, ...) unless 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>Loader.doDelegation</code> is <code>false</code>. This is because 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the JVM prohibits a user class loader from loading a system class. 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Also see Note 2. 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If this behavior is not appropriate, a subclass of <code>Loader</code> 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * must be defined and <code>loadClassByDelegation()</code> must be overridden. 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><b>Note 2:</b> 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>If classes are loaded with different class loaders, they belong to 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * separate name spaces. If class <code>C</code> is loaded by a class 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * loader <code>CL</code>, all classes that the class <code>C</code> 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * refers to are also loaded by <code>CL</code>. However, if <code>CL</code> 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * delegates the loading of the class <code>C</code> to <code>CL'</code>, 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * then those classes that the class <code>C</code> refers to 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * are loaded by a parent class loader <code>CL'</code> 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * instead of <code>CL</code>. 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>If an object of class <code>C</code> is assigned 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to a variable of class <code>C</code> belonging to a different name 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * space, then a <code>ClassCastException</code> is thrown. 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Because of the fact above, this loader delegates only the loading of 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>javassist.Loader</code> 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * and classes included in package <code>java.*</code> and 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>javax.*</code> to the parent class 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * loader. Other classes are directly loaded by this loader. 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>For example, suppose that <code>java.lang.String</code> would be loaded 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * by this loader while <code>java.io.File</code> is loaded by the parent 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class loader. If the constructor of <code>java.io.File</code> is called 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * with an instance of <code>java.lang.String</code>, then it may throw 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * an exception since it accepts an instance of only the 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>java.lang.String</code> loaded by the parent class loader. 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.ClassPool 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.Translator 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class Loader extends ClassLoader { 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private Hashtable notDefinedHere; // must be atomic. 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private Vector notDefinedPackages; // must be atomic. 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private ClassPool source; 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private Translator translator; 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private ProtectionDomain domain; 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Specifies the algorithm of class loading. 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This class loader uses the parent class loader for 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>java.*</code> and <code>javax.*</code> classes. 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If this variable <code>doDelegation</code> 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * is <code>false</code>, this class loader does not delegate those 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * classes to the parent class loader. 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>The default value is <code>true</code>. 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean doDelegation = true; 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Creates a new class loader. 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Loader() { 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this(null); 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Creates a new class loader. 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param cp the source of class files. 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Loader(ClassPool cp) { 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal init(cp); 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Creates a new class loader 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * using the specified parent class loader for delegation. 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param parent the parent class loader. 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param cp the source of class files. 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Loader(ClassLoader parent, ClassPool cp) { 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(parent); 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal init(cp); 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void init(ClassPool cp) { 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal notDefinedHere = new Hashtable(); 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal notDefinedPackages = new Vector(); 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal source = cp; 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal translator = null; 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal domain = null; 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal delegateLoadingOf("javassist.Loader"); 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Records a class so that the loading of that class is delegated 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to the parent class loader. 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>If the given class name ends with <code>.</code> (dot), then 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * that name is interpreted as a package name. All the classes 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * in that package and the sub packages are delegated. 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void delegateLoadingOf(String classname) { 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (classname.endsWith(".")) 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal notDefinedPackages.addElement(classname); 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal notDefinedHere.put(classname, this); 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets the protection domain for the classes handled by this class 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * loader. Without registering an appropriate protection domain, 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the program loaded by this loader will not work with a security 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * manager or a signed jar file. 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setDomain(ProtectionDomain d) { 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal domain = d; 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets the soruce <code>ClassPool</code>. 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setClassPool(ClassPool cp) { 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal source = cp; 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a translator, which is called whenever a class is loaded. 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param cp the <code>ClassPool</code> object for obtaining 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * a class file. 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param t a translator. 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws NotFoundException if <code>t.start()</code> throws an exception. 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws CannotCompileException if <code>t.start()</code> throws an exception. 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void addTranslator(ClassPool cp, Translator t) 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws NotFoundException, CannotCompileException { 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal source = cp; 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal translator = t; 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal t.start(cp); 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Loads a class with an instance of <code>Loader</code> 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * and calls <code>main()</code> of that class. 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This method calls <code>run()</code>. 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param args command line parameters. 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul> 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>args[0]</code> is the class name to be loaded. 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <br><code>args[1..n]</code> are parameters passed 25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to the target <code>main()</code>. 25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </ul> 25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.Loader#run(String[]) 25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static void main(String[] args) throws Throwable { 25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Loader cl = new Loader(); 25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cl.run(args); 25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Loads a class and calls <code>main()</code> in that class. 26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param args command line parameters. 26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul> 26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>args[0]</code> is the class name to be loaded. 26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <br><code>args[1..n]</code> are parameters passed 26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to the target <code>main()</code>. 26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </ul> 26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void run(String[] args) throws Throwable { 27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = args.length - 1; 27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (n >= 0) { 27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String[] args2 = new String[n]; 27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; ++i) 27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal args2[i] = args[i + 1]; 27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal run(args[0], args2); 27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Loads a class and calls <code>main()</code> in that class. 28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param classname the loaded class. 28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param args parameters passed to <code>main()</code>. 28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void run(String classname, String[] args) throws Throwable { 28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Class c = loadClass(classname); 28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c.getDeclaredMethod("main", new Class[] { String[].class }).invoke( 29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal null, 29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal new Object[] { args }); 29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (java.lang.reflect.InvocationTargetException e) { 29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw e.getTargetException(); 29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Requests the class loader to load a class. 30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected Class loadClass(String name, boolean resolve) 30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws ClassFormatError, ClassNotFoundException { 30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal name = name.intern(); 30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal synchronized (name) { 30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Class c = findLoadedClass(name); 30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (c == null) 30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c = loadClassByDelegation(name); 30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (c == null) 31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c = findClass(name); 31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (c == null) 31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c = delegateToParent(name); 31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (resolve) 31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal resolveClass(c); 31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return c; 32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Finds the specified class using <code>ClassPath</code>. 32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If the source throws an exception, this returns null. 32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This method can be overridden by a subclass of 32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>Loader</code>. Note that the overridden method must not throw 32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * an exception when it just fails to find a class file. 33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return null if the specified class could not be found. 33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws ClassNotFoundException if an exception is thrown while 33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * obtaining a class file. 33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected Class findClass(String name) throws ClassNotFoundException { 33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] classfile; 33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (source != null) { 33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (translator != null) 34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal translator.onLoad(source, name); 34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal classfile = source.get(name).toBytecode(); 34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (NotFoundException e) { 34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String jarname = "/" + name.replace('.', '/') + ".class"; 35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal InputStream in = this.getClass().getResourceAsStream(jarname); 35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (in == null) 35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal classfile = ClassPoolTail.readStream(in); 35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (Exception e) { 35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new ClassNotFoundException( 36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal "caught an exception while obtaining a class file for " 36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + name, e); 36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i = name.lastIndexOf('.'); 36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i != -1) { 36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String pname = name.substring(0, i); 36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (getPackage(pname) == null) 36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal definePackage( 37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal pname, null, null, null, null, null, null, null); 37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (IllegalArgumentException e) { 37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // ignore. maybe the package object for the same 37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // name has been created just right away. 37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (domain == null) 37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return defineClass(name, classfile, 0, classfile.length); 38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return defineClass(name, classfile, 0, classfile.length, domain); 38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected Class loadClassByDelegation(String name) 38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws ClassNotFoundException 38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* The swing components must be loaded by a system 38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class loader. 38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * javax.swing.UIManager loads a (concrete) subclass 39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * of LookAndFeel by a system class loader and cast 39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * an instance of the class to LookAndFeel for 39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * (maybe) a security reason. To avoid failure of 39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * type conversion, LookAndFeel must not be loaded 39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * by this class loader. 39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Class c = null; 39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (doDelegation) 39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (name.startsWith("java.") 40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal || name.startsWith("javax.") 40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal || name.startsWith("sun.") 40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal || name.startsWith("com.sun.") 40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal || name.startsWith("org.w3c.") 40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal || name.startsWith("org.xml.") 40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal || notDelegated(name)) 40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c = delegateToParent(name); 40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return c; 40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private boolean notDelegated(String name) { 41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (notDefinedHere.get(name) != null) 41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = notDefinedPackages.size(); 41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; ++i) 41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (name.startsWith((String)notDefinedPackages.elementAt(i))) 41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected Class delegateToParent(String classname) 42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws ClassNotFoundException 42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassLoader cl = getParent(); 42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (cl != null) 42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return cl.loadClass(classname); 42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return findSystemClass(classname); 43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected Package getPackage(String name) { 43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return super.getPackage(name); 43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* 43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // Package p = super.getPackage(name); 43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Package p = null; 43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (p == null) 44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return definePackage(name, null, null, null, 44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal null, null, null, null); 44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return p; 44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 447