169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License.  Alternatively, the contents of this file may be used under
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis,
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.tools.reflect;
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CannotCompileException;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.NotFoundException;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.ClassPool;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A class loader for reflection.
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>To run a program, say <code>MyApp</code>,
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * including a reflective class,
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * you must write a start-up program as follows:
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public class Main {
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   public static void main(String[] args) throws Throwable {
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     javassist.tools.reflect.Loader cl
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *         = (javassist.tools.reflect.Loader)Main.class.getClassLoader();
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     cl.makeReflective("Person", "MyMetaobject",
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *                       "javassist.tools.reflect.ClassMetaobject");
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     cl.run("MyApp", args);
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   }
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * }
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul>
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Then run this program as follows:
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>% java javassist.tools.reflect.Loader Main arg1, ...</pre></ul>
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This command runs <code>Main.main()</code> with <code>arg1</code>, ...
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * and <code>Main.main()</code> runs <code>MyApp.main()</code> with
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>arg1</code>, ...
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The <code>Person</code> class is modified
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to be a reflective class.  Method calls on a <code>Person</code>
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * object are intercepted by an instance of <code>MyMetaobject</code>.
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Also, you can run <code>MyApp</code> in a slightly different way:
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public class Main2 {
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   public static void main(String[] args) throws Throwable {
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     javassist.tools.reflect.Loader cl = new javassist.tools.reflect.Loader();
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     cl.makeReflective("Person", "MyMetaobject",
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *                       "javassist.tools.reflect.ClassMetaobject");
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     cl.run("MyApp", args);
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   }
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * }
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul>
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This program is run as follows:
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>% java Main2 arg1, ...</pre></ul>
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>The difference from the former one is that the class <code>Main</code>
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * is loaded by <code>javassist.tools.reflect.Loader</code> whereas the class
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>Main2</code> is not.  Thus, <code>Main</code> belongs
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to the same name space (security domain) as <code>MyApp</code>
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * whereas <code>Main2</code> does not; <code>Main2</code> belongs
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to the same name space as <code>javassist.tools.reflect.Loader</code>.
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * For more details,
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * see the notes in the manual page of <code>javassist.Loader</code>.
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>The class <code>Main2</code> is equivalent to this class:
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public class Main3 {
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   public static void main(String[] args) throws Throwable {
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     Reflection reflection = new Reflection();
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     javassist.Loader cl
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *         = new javassist.Loader(ClassPool.getDefault(reflection));
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     reflection.makeReflective("Person", "MyMetaobject",
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *                               "javassist.tools.reflect.ClassMetaobject");
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     cl.run("MyApp", args);
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   }
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * }
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul>
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><b>Note:</b>
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><code>javassist.tools.reflect.Loader</code> does not make a class reflective
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * if that class is in a <code>java.*</code> or
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>javax.*</code> pacakge because of the specifications
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * on the class loading algorithm of Java.  The JVM does not allow to
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * load such a system class with a user class loader.
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>To avoid this limitation, those classes should be statically
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * modified with <code>javassist.tools.reflect.Compiler</code> and the original
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class files should be replaced.
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.tools.reflect.Reflection
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.tools.reflect.Compiler
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.Loader
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class Loader extends javassist.Loader {
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected Reflection reflection;
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Loads a class with an instance of <code>Loader</code>
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * and calls <code>main()</code> in that class.
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param args              command line parameters.
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <ul>
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>args[0]</code> is the class name to be loaded.
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <br><code>args[1..n]</code> are parameters passed
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      to the target <code>main()</code>.
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * </ul>
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static void main(String[] args) throws Throwable {
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Loader cl = new Loader();
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        cl.run(args);
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Constructs a new class loader.
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Loader() throws CannotCompileException, NotFoundException {
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        super();
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        delegateLoadingOf("javassist.tools.reflect.Loader");
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        reflection = new Reflection();
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        ClassPool pool = ClassPool.getDefault();
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        addTranslator(pool, reflection);
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Produces a reflective class.
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If the super class is also made reflective, it must be done
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * before the sub class.
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param clazz             the reflective class.
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param metaobject        the class of metaobjects.
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                          It must be a subclass of
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                          <code>Metaobject</code>.
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param metaclass         the class of the class metaobject.
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                          It must be a subclass of
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                          <code>ClassMetaobject</code>.
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return <code>false</code>       if the class is already reflective.
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.tools.reflect.Metaobject
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.tools.reflect.ClassMetaobject
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public boolean makeReflective(String clazz,
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                  String metaobject, String metaclass)
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CannotCompileException, NotFoundException
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return reflection.makeReflective(clazz, metaobject, metaclass);
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
164