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