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