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.CtClass; 19 import javassist.ClassPool; 20 import java.io.PrintStream; 21 22 class CompiledClass { 23 public String classname; 24 public String metaobject; 25 public String classobject; 26 } 27 28 /** 29 * A bytecode translator for reflection. 30 * 31 * <p>This translator directly modifies class files on a local disk so that 32 * the classes represented by those class files are reflective. 33 * After the modification, the class files can be run with the standard JVM 34 * without <code>javassist.tools.reflect.Loader</code> 35 * or any other user-defined class loader. 36 * 37 * <p>The modified class files are given as the command-line parameters, 38 * which are a sequence of fully-qualified class names followed by options: 39 * 40 * <p><code>-m <i>classname</i></code> : specifies the class of the 41 * metaobjects associated with instances of the class followed by 42 * this option. The default is <code>javassit.reflect.Metaobject</code>. 43 * 44 * <p><code>-c <i>classname</i></code> : specifies the class of the 45 * class metaobjects associated with instances of the class followed by 46 * this option. The default is <code>javassit.reflect.ClassMetaobject</code>. 47 * 48 * <p>If a class name is not followed by any options, the class indicated 49 * by that class name is not reflective. 50 * 51 * <p>For example, 52 * <ul><pre>% java Compiler Dog -m MetaDog -c CMetaDog Cat -m MetaCat Cow 53 * </pre></ul> 54 * 55 * <p>modifies class files <code>Dog.class</code>, <code>Cat.class</code>, 56 * and <code>Cow.class</code>. 57 * The metaobject of a Dog object is a MetaDog object and the class 58 * metaobject is a CMetaDog object. 59 * The metaobject of a Cat object is a MetaCat object but 60 * the class metaobject is a default one. 61 * Cow objects are not reflective. 62 * 63 * <p>Note that if the super class is also made reflective, it must be done 64 * before the sub class. 65 * 66 * @see javassist.tools.reflect.Metaobject 67 * @see javassist.tools.reflect.ClassMetaobject 68 * @see javassist.tools.reflect.Reflection 69 */ 70 public class Compiler { 71 main(String[] args)72 public static void main(String[] args) throws Exception { 73 if (args.length == 0) { 74 help(System.err); 75 return; 76 } 77 78 CompiledClass[] entries = new CompiledClass[args.length]; 79 int n = parse(args, entries); 80 81 if (n < 1) { 82 System.err.println("bad parameter."); 83 return; 84 } 85 86 processClasses(entries, n); 87 } 88 processClasses(CompiledClass[] entries, int n)89 private static void processClasses(CompiledClass[] entries, int n) 90 throws Exception 91 { 92 Reflection implementor = new Reflection(); 93 ClassPool pool = ClassPool.getDefault(); 94 implementor.start(pool); 95 96 for (int i = 0; i < n; ++i) { 97 CtClass c = pool.get(entries[i].classname); 98 if (entries[i].metaobject != null 99 || entries[i].classobject != null) { 100 String metaobj, classobj; 101 102 if (entries[i].metaobject == null) 103 metaobj = "javassist.tools.reflect.Metaobject"; 104 else 105 metaobj = entries[i].metaobject; 106 107 if (entries[i].classobject == null) 108 classobj = "javassist.tools.reflect.ClassMetaobject"; 109 else 110 classobj = entries[i].classobject; 111 112 if (!implementor.makeReflective(c, pool.get(metaobj), 113 pool.get(classobj))) 114 System.err.println("Warning: " + c.getName() 115 + " is reflective. It was not changed."); 116 117 System.err.println(c.getName() + ": " + metaobj + ", " 118 + classobj); 119 } 120 else 121 System.err.println(c.getName() + ": not reflective"); 122 } 123 124 for (int i = 0; i < n; ++i) { 125 implementor.onLoad(pool, entries[i].classname); 126 pool.get(entries[i].classname).writeFile(); 127 } 128 } 129 parse(String[] args, CompiledClass[] result)130 private static int parse(String[] args, CompiledClass[] result) { 131 int n = -1; 132 for (int i = 0; i < args.length; ++i) { 133 String a = args[i]; 134 if (a.equals("-m")) 135 if (n < 0 || i + 1 > args.length) 136 return -1; 137 else 138 result[n].metaobject = args[++i]; 139 else if (a.equals("-c")) 140 if (n < 0 || i + 1 > args.length) 141 return -1; 142 else 143 result[n].classobject = args[++i]; 144 else if (a.charAt(0) == '-') 145 return -1; 146 else { 147 CompiledClass cc = new CompiledClass(); 148 cc.classname = a; 149 cc.metaobject = null; 150 cc.classobject = null; 151 result[++n] = cc; 152 } 153 } 154 155 return n + 1; 156 } 157 help(PrintStream out)158 private static void help(PrintStream out) { 159 out.println("Usage: java javassist.tools.reflect.Compiler"); 160 out.println(" (<class> [-m <metaobject>] [-c <class metaobject>])+"); 161 } 162 } 163