1 /* 2 * Javassist, a Java-bytecode translator toolkit. 3 * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. 4 * 5 * The contents of this file are subject to the Mozilla Public License Version 6 * 1.1 (the "License"); you may not use this file except in compliance with 7 * the License. Alternatively, the contents of this file may be used under 8 * the terms of the GNU Lesser General Public License Version 2.1 or later. 9 * 10 * Software distributed under the License is distributed on an "AS IS" basis, 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 * for the specific language governing rights and limitations under the 13 * License. 14 */ 15 16 package javassist.tools.reflect; 17 18 import javassist.CannotCompileException; 19 import javassist.NotFoundException; 20 import javassist.ClassPool; 21 22 /** 23 * A class loader for reflection. 24 * 25 * <p>To run a program, say <code>MyApp</code>, 26 * including a reflective class, 27 * you must write a start-up program as follows: 28 * 29 * <ul><pre> 30 * public class Main { 31 * public static void main(String[] args) throws Throwable { 32 * javassist.tools.reflect.Loader cl 33 * = (javassist.tools.reflect.Loader)Main.class.getClassLoader(); 34 * cl.makeReflective("Person", "MyMetaobject", 35 * "javassist.tools.reflect.ClassMetaobject"); 36 * cl.run("MyApp", args); 37 * } 38 * } 39 * </pre></ul> 40 * 41 * <p>Then run this program as follows: 42 * 43 * <ul><pre>% java javassist.tools.reflect.Loader Main arg1, ...</pre></ul> 44 * 45 * <p>This command runs <code>Main.main()</code> with <code>arg1</code>, ... 46 * and <code>Main.main()</code> runs <code>MyApp.main()</code> with 47 * <code>arg1</code>, ... 48 * The <code>Person</code> class is modified 49 * to be a reflective class. Method calls on a <code>Person</code> 50 * object are intercepted by an instance of <code>MyMetaobject</code>. 51 * 52 * <p>Also, you can run <code>MyApp</code> in a slightly different way: 53 * 54 * <ul><pre> 55 * public class Main2 { 56 * public static void main(String[] args) throws Throwable { 57 * javassist.tools.reflect.Loader cl = new javassist.tools.reflect.Loader(); 58 * cl.makeReflective("Person", "MyMetaobject", 59 * "javassist.tools.reflect.ClassMetaobject"); 60 * cl.run("MyApp", args); 61 * } 62 * } 63 * </pre></ul> 64 * 65 * <p>This program is run as follows: 66 * 67 * <ul><pre>% java Main2 arg1, ...</pre></ul> 68 * 69 * <p>The difference from the former one is that the class <code>Main</code> 70 * is loaded by <code>javassist.tools.reflect.Loader</code> whereas the class 71 * <code>Main2</code> is not. Thus, <code>Main</code> belongs 72 * to the same name space (security domain) as <code>MyApp</code> 73 * whereas <code>Main2</code> does not; <code>Main2</code> belongs 74 * to the same name space as <code>javassist.tools.reflect.Loader</code>. 75 * For more details, 76 * see the notes in the manual page of <code>javassist.Loader</code>. 77 * 78 * <p>The class <code>Main2</code> is equivalent to this class: 79 * 80 * <ul><pre> 81 * public class Main3 { 82 * public static void main(String[] args) throws Throwable { 83 * Reflection reflection = new Reflection(); 84 * javassist.Loader cl 85 * = new javassist.Loader(ClassPool.getDefault(reflection)); 86 * reflection.makeReflective("Person", "MyMetaobject", 87 * "javassist.tools.reflect.ClassMetaobject"); 88 * cl.run("MyApp", args); 89 * } 90 * } 91 * </pre></ul> 92 * 93 * <p><b>Note:</b> 94 * 95 * <p><code>javassist.tools.reflect.Loader</code> does not make a class reflective 96 * if that class is in a <code>java.*</code> or 97 * <code>javax.*</code> pacakge because of the specifications 98 * on the class loading algorithm of Java. The JVM does not allow to 99 * load such a system class with a user class loader. 100 * 101 * <p>To avoid this limitation, those classes should be statically 102 * modified with <code>javassist.tools.reflect.Compiler</code> and the original 103 * class files should be replaced. 104 * 105 * @see javassist.tools.reflect.Reflection 106 * @see javassist.tools.reflect.Compiler 107 * @see javassist.Loader 108 */ 109 public class Loader extends javassist.Loader { 110 protected Reflection reflection; 111 112 /** 113 * Loads a class with an instance of <code>Loader</code> 114 * and calls <code>main()</code> in that class. 115 * 116 * @param args command line parameters. 117 * <ul> 118 * <code>args[0]</code> is the class name to be loaded. 119 * <br><code>args[1..n]</code> are parameters passed 120 * to the target <code>main()</code>. 121 * </ul> 122 */ main(String[] args)123 public static void main(String[] args) throws Throwable { 124 Loader cl = new Loader(); 125 cl.run(args); 126 } 127 128 /** 129 * Constructs a new class loader. 130 */ Loader()131 public Loader() throws CannotCompileException, NotFoundException { 132 super(); 133 delegateLoadingOf("javassist.tools.reflect.Loader"); 134 135 reflection = new Reflection(); 136 ClassPool pool = ClassPool.getDefault(); 137 addTranslator(pool, reflection); 138 } 139 140 /** 141 * Produces a reflective class. 142 * If the super class is also made reflective, it must be done 143 * before the sub class. 144 * 145 * @param clazz the reflective class. 146 * @param metaobject the class of metaobjects. 147 * It must be a subclass of 148 * <code>Metaobject</code>. 149 * @param metaclass the class of the class metaobject. 150 * It must be a subclass of 151 * <code>ClassMetaobject</code>. 152 * @return <code>false</code> if the class is already reflective. 153 * 154 * @see javassist.tools.reflect.Metaobject 155 * @see javassist.tools.reflect.ClassMetaobject 156 */ makeReflective(String clazz, String metaobject, String metaclass)157 public boolean makeReflective(String clazz, 158 String metaobject, String metaclass) 159 throws CannotCompileException, NotFoundException 160 { 161 return reflection.makeReflective(clazz, metaobject, metaclass); 162 } 163 } 164