001: /*
002: * Javassist, a Java-bytecode translator toolkit.
003: * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
004: *
005: * The contents of this file are subject to the Mozilla Public License Version
006: * 1.1 (the "License"); you may not use this file except in compliance with
007: * the License. Alternatively, the contents of this file may be used under
008: * the terms of the GNU Lesser General Public License Version 2.1 or later.
009: *
010: * Software distributed under the License is distributed on an "AS IS" basis,
011: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012: * for the specific language governing rights and limitations under the
013: * License.
014: */
015:
016: package javassist.tools.reflect;
017:
018: import javassist.CannotCompileException;
019: import javassist.NotFoundException;
020: import javassist.ClassPool;
021:
022: /**
023: * A class loader for reflection.
024: *
025: * <p>To run a program, say <code>MyApp</code>,
026: * including a reflective class,
027: * you must write a start-up program as follows:
028: *
029: * <ul><pre>
030: * public class Main {
031: * public static void main(String[] args) throws Throwable {
032: * javassist.tools.reflect.Loader cl
033: * = (javassist.tools.reflect.Loader)Main.class.getClassLoader();
034: * cl.makeReflective("Person", "MyMetaobject",
035: * "javassist.tools.reflect.ClassMetaobject");
036: * cl.run("MyApp", args);
037: * }
038: * }
039: * </pre></ul>
040: *
041: * <p>Then run this program as follows:
042: *
043: * <ul><pre>% java javassist.tools.reflect.Loader Main arg1, ...</pre></ul>
044: *
045: * <p>This command runs <code>Main.main()</code> with <code>arg1</code>, ...
046: * and <code>Main.main()</code> runs <code>MyApp.main()</code> with
047: * <code>arg1</code>, ...
048: * The <code>Person</code> class is modified
049: * to be a reflective class. Method calls on a <code>Person</code>
050: * object are intercepted by an instance of <code>MyMetaobject</code>.
051: *
052: * <p>Also, you can run <code>MyApp</code> in a slightly different way:
053: *
054: * <ul><pre>
055: * public class Main2 {
056: * public static void main(String[] args) throws Throwable {
057: * javassist.tools.reflect.Loader cl = new javassist.tools.reflect.Loader();
058: * cl.makeReflective("Person", "MyMetaobject",
059: * "javassist.tools.reflect.ClassMetaobject");
060: * cl.run("MyApp", args);
061: * }
062: * }
063: * </pre></ul>
064: *
065: * <p>This program is run as follows:
066: *
067: * <ul><pre>% java Main2 arg1, ...</pre></ul>
068: *
069: * <p>The difference from the former one is that the class <code>Main</code>
070: * is loaded by <code>javassist.tools.reflect.Loader</code> whereas the class
071: * <code>Main2</code> is not. Thus, <code>Main</code> belongs
072: * to the same name space (security domain) as <code>MyApp</code>
073: * whereas <code>Main2</code> does not; <code>Main2</code> belongs
074: * to the same name space as <code>javassist.tools.reflect.Loader</code>.
075: * For more details,
076: * see the notes in the manual page of <code>javassist.Loader</code>.
077: *
078: * <p>The class <code>Main2</code> is equivalent to this class:
079: *
080: * <ul><pre>
081: * public class Main3 {
082: * public static void main(String[] args) throws Throwable {
083: * Reflection reflection = new Reflection();
084: * javassist.Loader cl
085: * = new javassist.Loader(ClassPool.getDefault(reflection));
086: * reflection.makeReflective("Person", "MyMetaobject",
087: * "javassist.tools.reflect.ClassMetaobject");
088: * cl.run("MyApp", args);
089: * }
090: * }
091: * </pre></ul>
092: *
093: * <p><b>Note:</b>
094: *
095: * <p><code>javassist.tools.reflect.Loader</code> does not make a class reflective
096: * if that class is in a <code>java.*</code> or
097: * <code>javax.*</code> pacakge because of the specifications
098: * on the class loading algorithm of Java. The JVM does not allow to
099: * 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: */
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: */
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: */
157: public boolean makeReflective(String clazz, String metaobject,
158: String metaclass) throws CannotCompileException,
159: NotFoundException {
160: return reflection.makeReflective(clazz, metaobject, metaclass);
161: }
162: }
|