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.tools.reflect; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CannotCompileException; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.NotFoundException; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.ClassPool; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A class loader for reflection. 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>To run a program, say <code>MyApp</code>, 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * including a reflective class, 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * you must write a start-up program as follows: 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre> 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public class Main { 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public static void main(String[] args) throws Throwable { 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * javassist.tools.reflect.Loader cl 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * = (javassist.tools.reflect.Loader)Main.class.getClassLoader(); 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * cl.makeReflective("Person", "MyMetaobject", 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * "javassist.tools.reflect.ClassMetaobject"); 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * cl.run("MyApp", args); 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul> 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Then run this program as follows: 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>% java javassist.tools.reflect.Loader Main arg1, ...</pre></ul> 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This command runs <code>Main.main()</code> with <code>arg1</code>, ... 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * and <code>Main.main()</code> runs <code>MyApp.main()</code> with 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>arg1</code>, ... 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The <code>Person</code> class is modified 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to be a reflective class. Method calls on a <code>Person</code> 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * object are intercepted by an instance of <code>MyMetaobject</code>. 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Also, you can run <code>MyApp</code> in a slightly different way: 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre> 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public class Main2 { 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public static void main(String[] args) throws Throwable { 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * javassist.tools.reflect.Loader cl = new javassist.tools.reflect.Loader(); 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * cl.makeReflective("Person", "MyMetaobject", 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * "javassist.tools.reflect.ClassMetaobject"); 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * cl.run("MyApp", args); 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul> 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This program is run as follows: 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>% java Main2 arg1, ...</pre></ul> 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>The difference from the former one is that the class <code>Main</code> 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * is loaded by <code>javassist.tools.reflect.Loader</code> whereas the class 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>Main2</code> is not. Thus, <code>Main</code> belongs 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to the same name space (security domain) as <code>MyApp</code> 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * whereas <code>Main2</code> does not; <code>Main2</code> belongs 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to the same name space as <code>javassist.tools.reflect.Loader</code>. 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * For more details, 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * see the notes in the manual page of <code>javassist.Loader</code>. 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>The class <code>Main2</code> is equivalent to this class: 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre> 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public class Main3 { 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public static void main(String[] args) throws Throwable { 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Reflection reflection = new Reflection(); 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * javassist.Loader cl 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * = new javassist.Loader(ClassPool.getDefault(reflection)); 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * reflection.makeReflective("Person", "MyMetaobject", 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * "javassist.tools.reflect.ClassMetaobject"); 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * cl.run("MyApp", args); 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul> 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><b>Note:</b> 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><code>javassist.tools.reflect.Loader</code> does not make a class reflective 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * if that class is in a <code>java.*</code> or 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>javax.*</code> pacakge because of the specifications 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * on the class loading algorithm of Java. The JVM does not allow to 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * load such a system class with a user class loader. 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>To avoid this limitation, those classes should be statically 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * modified with <code>javassist.tools.reflect.Compiler</code> and the original 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class files should be replaced. 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.tools.reflect.Reflection 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.tools.reflect.Compiler 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.Loader 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class Loader extends javassist.Loader { 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected Reflection reflection; 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Loads a class with an instance of <code>Loader</code> 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * and calls <code>main()</code> in that class. 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param args command line parameters. 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul> 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>args[0]</code> is the class name to be loaded. 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <br><code>args[1..n]</code> are parameters passed 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to the target <code>main()</code>. 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </ul> 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static void main(String[] args) throws Throwable { 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Loader cl = new Loader(); 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cl.run(args); 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constructs a new class loader. 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Loader() throws CannotCompileException, NotFoundException { 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(); 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal delegateLoadingOf("javassist.tools.reflect.Loader"); 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal reflection = new Reflection(); 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassPool pool = ClassPool.getDefault(); 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal addTranslator(pool, reflection); 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Produces a reflective class. 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If the super class is also made reflective, it must be done 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * before the sub class. 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param clazz the reflective class. 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param metaobject the class of metaobjects. 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It must be a subclass of 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>Metaobject</code>. 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param metaclass the class of the class metaobject. 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It must be a subclass of 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>ClassMetaobject</code>. 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return <code>false</code> if the class is already reflective. 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.tools.reflect.Metaobject 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.tools.reflect.ClassMetaobject 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean makeReflective(String clazz, 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String metaobject, String metaclass) 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CannotCompileException, NotFoundException 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return reflection.makeReflective(clazz, metaobject, metaclass); 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 164