aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/javassist/tools/reflect/Loader.java
blob: 3a4a3f62feb0f65a42e14f20ac3dd22ed1ce8764 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
 * Javassist, a Java-bytecode translator toolkit.
 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License.  Alternatively, the contents of this file may be used under
 * the terms of the GNU Lesser General Public License Version 2.1 or later,
 * or the Apache License Version 2.0.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 */

package javassist.tools.reflect;

import javassist.CannotCompileException;
import javassist.NotFoundException;
import javassist.ClassPool;

/**
 * A class loader for reflection.
 *
 * <p>To run a program, say <code>MyApp</code>,
 * including a reflective class,
 * you must write a start-up program as follows:
 *
 * <ul><pre>
 * public class Main {
 *   public static void main(String[] args) throws Throwable {
 *     javassist.tools.reflect.Loader cl
 *         = (javassist.tools.reflect.Loader)Main.class.getClassLoader();
 *     cl.makeReflective("Person", "MyMetaobject",
 *                       "javassist.tools.reflect.ClassMetaobject");
 *     cl.run("MyApp", args);
 *   }
 * }
 * </pre></ul>
 *
 * <p>Then run this program as follows:
 *
 * <ul><pre>% java javassist.tools.reflect.Loader Main arg1, ...</pre></ul>
 *
 * <p>This command runs <code>Main.main()</code> with <code>arg1</code>, ...
 * and <code>Main.main()</code> runs <code>MyApp.main()</code> with
 * <code>arg1</code>, ...
 * The <code>Person</code> class is modified
 * to be a reflective class.  Method calls on a <code>Person</code>
 * object are intercepted by an instance of <code>MyMetaobject</code>.
 *
 * <p>Also, you can run <code>MyApp</code> in a slightly different way:
 *
 * <ul><pre>
 * public class Main2 {
 *   public static void main(String[] args) throws Throwable {
 *     javassist.tools.reflect.Loader cl = new javassist.tools.reflect.Loader();
 *     cl.makeReflective("Person", "MyMetaobject",
 *                       "javassist.tools.reflect.ClassMetaobject");
 *     cl.run("MyApp", args);
 *   }
 * }
 * </pre></ul>
 *
 * <p>This program is run as follows:
 *
 * <ul><pre>% java Main2 arg1, ...</pre></ul>
 *
 * <p>The difference from the former one is that the class <code>Main</code>
 * is loaded by <code>javassist.tools.reflect.Loader</code> whereas the class
 * <code>Main2</code> is not.  Thus, <code>Main</code> belongs
 * to the same name space (security domain) as <code>MyApp</code>
 * whereas <code>Main2</code> does not; <code>Main2</code> belongs
 * to the same name space as <code>javassist.tools.reflect.Loader</code>.
 * For more details,
 * see the notes in the manual page of <code>javassist.Loader</code>.
 *
 * <p>The class <code>Main2</code> is equivalent to this class:
 *
 * <ul><pre>
 * public class Main3 {
 *   public static void main(String[] args) throws Throwable {
 *     Reflection reflection = new Reflection();
 *     javassist.Loader cl
 *         = new javassist.Loader(ClassPool.getDefault(reflection));
 *     reflection.makeReflective("Person", "MyMetaobject",
 *                               "javassist.tools.reflect.ClassMetaobject");
 *     cl.run("MyApp", args);
 *   }
 * }
 * </pre></ul>
 *
 * <p><b>Note:</b>
 *
 * <p><code>javassist.tools.reflect.Loader</code> does not make a class reflective
 * if that class is in a <code>java.*</code> or
 * <code>javax.*</code> pacakge because of the specifications
 * on the class loading algorithm of Java.  The JVM does not allow to
 * load such a system class with a user class loader.
 *
 * <p>To avoid this limitation, those classes should be statically
 * modified with <code>javassist.tools.reflect.Compiler</code> and the original
 * class files should be replaced.
 *
 * @see javassist.tools.reflect.Reflection
 * @see javassist.tools.reflect.Compiler
 * @see javassist.Loader
 */
public class Loader extends javassist.Loader {
    protected Reflection reflection;

    /**
     * Loads a class with an instance of <code>Loader</code>
     * and calls <code>main()</code> in that class.
     *
     * @param args              command line parameters.
     * <ul>
     * <code>args[0]</code> is the class name to be loaded.
     * <br><code>args[1..n]</code> are parameters passed
     *                      to the target <code>main()</code>.
     * </ul>
     */
    public static void main(String[] args) throws Throwable {
        Loader cl = new Loader();
        cl.run(args);
    }

    /**
     * Constructs a new class loader.
     */
    public Loader() throws CannotCompileException, NotFoundException {
        super();
        delegateLoadingOf("javassist.tools.reflect.Loader");

        reflection = new Reflection();
        ClassPool pool = ClassPool.getDefault();
        addTranslator(pool, reflection);
    }

    /**
     * Produces a reflective class.
     * If the super class is also made reflective, it must be done
     * before the sub class.
     *
     * @param clazz             the reflective class.
     * @param metaobject        the class of metaobjects.
     *                          It must be a subclass of
     *                          <code>Metaobject</code>.
     * @param metaclass         the class of the class metaobject.
     *                          It must be a subclass of
     *                          <code>ClassMetaobject</code>.
     * @return <code>false</code>       if the class is already reflective.
     *
     * @see javassist.tools.reflect.Metaobject
     * @see javassist.tools.reflect.ClassMetaobject
     */
    public boolean makeReflective(String clazz,
                                  String metaobject, String metaclass)
        throws CannotCompileException, NotFoundException
    {
        return reflection.makeReflective(clazz, metaobject, metaclass);
    }
}