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.CtClass; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.ClassPool; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.PrintStream; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalclass CompiledClass { 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String classname; 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String metaobject; 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String classobject; 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A bytecode translator for reflection. 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This translator directly modifies class files on a local disk so that 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the classes represented by those class files are reflective. 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * After the modification, the class files can be run with the standard JVM 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * without <code>javassist.tools.reflect.Loader</code> 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * or any other user-defined class loader. 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>The modified class files are given as the command-line parameters, 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * which are a sequence of fully-qualified class names followed by options: 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><code>-m <i>classname</i></code> : specifies the class of the 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * metaobjects associated with instances of the class followed by 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * this option. The default is <code>javassit.reflect.Metaobject</code>. 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><code>-c <i>classname</i></code> : specifies the class of the 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class metaobjects associated with instances of the class followed by 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * this option. The default is <code>javassit.reflect.ClassMetaobject</code>. 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>If a class name is not followed by any options, the class indicated 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * by that class name is not reflective. 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>For example, 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>% java Compiler Dog -m MetaDog -c CMetaDog Cat -m MetaCat Cow 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul> 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>modifies class files <code>Dog.class</code>, <code>Cat.class</code>, 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * and <code>Cow.class</code>. 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The metaobject of a Dog object is a MetaDog object and the class 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * metaobject is a CMetaDog object. 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The metaobject of a Cat object is a MetaCat object but 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the class metaobject is a default one. 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Cow objects are not reflective. 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Note that if the super class is also made reflective, it must be done 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * before the sub class. 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.tools.reflect.Metaobject 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.tools.reflect.ClassMetaobject 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.tools.reflect.Reflection 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class Compiler { 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static void main(String[] args) throws Exception { 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (args.length == 0) { 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal help(System.err); 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CompiledClass[] entries = new CompiledClass[args.length]; 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = parse(args, entries); 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (n < 1) { 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal System.err.println("bad parameter."); 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal processClasses(entries, n); 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static void processClasses(CompiledClass[] entries, int n) 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws Exception 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Reflection implementor = new Reflection(); 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassPool pool = ClassPool.getDefault(); 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal implementor.start(pool); 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; ++i) { 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass c = pool.get(entries[i].classname); 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (entries[i].metaobject != null 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal || entries[i].classobject != null) { 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String metaobj, classobj; 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (entries[i].metaobject == null) 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal metaobj = "javassist.tools.reflect.Metaobject"; 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal metaobj = entries[i].metaobject; 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (entries[i].classobject == null) 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal classobj = "javassist.tools.reflect.ClassMetaobject"; 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal classobj = entries[i].classobject; 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (!implementor.makeReflective(c, pool.get(metaobj), 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal pool.get(classobj))) 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal System.err.println("Warning: " + c.getName() 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + " is reflective. It was not changed."); 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal System.err.println(c.getName() + ": " + metaobj + ", " 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + classobj); 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal System.err.println(c.getName() + ": not reflective"); 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; ++i) { 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal implementor.onLoad(pool, entries[i].classname); 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal pool.get(entries[i].classname).writeFile(); 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static int parse(String[] args, CompiledClass[] result) { 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = -1; 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < args.length; ++i) { 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String a = args[i]; 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (a.equals("-m")) 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (n < 0 || i + 1 > args.length) 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return -1; 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal result[n].metaobject = args[++i]; 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (a.equals("-c")) 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (n < 0 || i + 1 > args.length) 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return -1; 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal result[n].classobject = args[++i]; 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (a.charAt(0) == '-') 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return -1; 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CompiledClass cc = new CompiledClass(); 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cc.classname = a; 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cc.metaobject = null; 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cc.classobject = null; 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal result[++n] = cc; 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return n + 1; 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static void help(PrintStream out) { 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.println("Usage: java javassist.tools.reflect.Compiler"); 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.println(" (<class> [-m <metaobject>] [-c <class metaobject>])+"); 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 163