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