1*f1fbf3c2SXin Li /* 2*f1fbf3c2SXin Li * Javassist, a Java-bytecode translator toolkit. 3*f1fbf3c2SXin Li * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. 4*f1fbf3c2SXin Li * 5*f1fbf3c2SXin Li * The contents of this file are subject to the Mozilla Public License Version 6*f1fbf3c2SXin Li * 1.1 (the "License"); you may not use this file except in compliance with 7*f1fbf3c2SXin Li * the License. Alternatively, the contents of this file may be used under 8*f1fbf3c2SXin Li * the terms of the GNU Lesser General Public License Version 2.1 or later, 9*f1fbf3c2SXin Li * or the Apache License Version 2.0. 10*f1fbf3c2SXin Li * 11*f1fbf3c2SXin Li * Software distributed under the License is distributed on an "AS IS" basis, 12*f1fbf3c2SXin Li * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13*f1fbf3c2SXin Li * for the specific language governing rights and limitations under the 14*f1fbf3c2SXin Li * License. 15*f1fbf3c2SXin Li */ 16*f1fbf3c2SXin Li 17*f1fbf3c2SXin Li package javassist; 18*f1fbf3c2SXin Li 19*f1fbf3c2SXin Li import java.io.BufferedInputStream; 20*f1fbf3c2SXin Li import java.io.File; 21*f1fbf3c2SXin Li import java.io.IOException; 22*f1fbf3c2SXin Li import java.io.InputStream; 23*f1fbf3c2SXin Li import java.io.OutputStream; 24*f1fbf3c2SXin Li import java.net.URL; 25*f1fbf3c2SXin Li import java.security.ProtectionDomain; 26*f1fbf3c2SXin Li import java.util.ArrayList; 27*f1fbf3c2SXin Li import java.util.Enumeration; 28*f1fbf3c2SXin Li import java.util.Hashtable; 29*f1fbf3c2SXin Li import java.util.Iterator; 30*f1fbf3c2SXin Li 31*f1fbf3c2SXin Li import javassist.bytecode.ClassFile; 32*f1fbf3c2SXin Li import javassist.bytecode.Descriptor; 33*f1fbf3c2SXin Li import javassist.util.proxy.DefinePackageHelper; 34*f1fbf3c2SXin Li 35*f1fbf3c2SXin Li /** 36*f1fbf3c2SXin Li * A container of <code>CtClass</code> objects. 37*f1fbf3c2SXin Li * A <code>CtClass</code> object must be obtained from this object. 38*f1fbf3c2SXin Li * If <code>get()</code> is called on this object, 39*f1fbf3c2SXin Li * it searches various sources represented by <code>ClassPath</code> 40*f1fbf3c2SXin Li * to find a class file and then it creates a <code>CtClass</code> object 41*f1fbf3c2SXin Li * representing that class file. The created object is returned to the 42*f1fbf3c2SXin Li * caller. 43*f1fbf3c2SXin Li * 44*f1fbf3c2SXin Li * <p><b>Memory consumption memo:</b> 45*f1fbf3c2SXin Li * 46*f1fbf3c2SXin Li * <p><code>ClassPool</code> objects hold all the <code>CtClass</code>es 47*f1fbf3c2SXin Li * that have been created so that the consistency among modified classes 48*f1fbf3c2SXin Li * can be guaranteed. Thus if a large number of <code>CtClass</code>es 49*f1fbf3c2SXin Li * are processed, the <code>ClassPool</code> will consume a huge amount 50*f1fbf3c2SXin Li * of memory. To avoid this, a <code>ClassPool</code> object 51*f1fbf3c2SXin Li * should be recreated, for example, every hundred classes processed. 52*f1fbf3c2SXin Li * Note that <code>getDefault()</code> is a singleton factory. 53*f1fbf3c2SXin Li * Otherwise, <code>detach()</code> in <code>CtClass</code> should be used 54*f1fbf3c2SXin Li * to avoid huge memory consumption. 55*f1fbf3c2SXin Li * 56*f1fbf3c2SXin Li * <p><b><code>ClassPool</code> hierarchy:</b> 57*f1fbf3c2SXin Li * 58*f1fbf3c2SXin Li * <p><code>ClassPool</code>s can make a parent-child hierarchy as 59*f1fbf3c2SXin Li * <code>java.lang.ClassLoader</code>s. If a <code>ClassPool</code> has 60*f1fbf3c2SXin Li * a parent pool, <code>get()</code> first asks the parent pool to find 61*f1fbf3c2SXin Li * a class file. Only if the parent could not find the class file, 62*f1fbf3c2SXin Li * <code>get()</code> searches the <code>ClassPath</code>s of 63*f1fbf3c2SXin Li * the child <code>ClassPool</code>. This search order is reversed if 64*f1fbf3c2SXin Li * <code>ClassPath.childFirstLookup</code> is <code>true</code>. 65*f1fbf3c2SXin Li * 66*f1fbf3c2SXin Li * @see javassist.CtClass 67*f1fbf3c2SXin Li * @see javassist.ClassPath 68*f1fbf3c2SXin Li */ 69*f1fbf3c2SXin Li @SuppressWarnings({"unchecked", "rawtypes"}) 70*f1fbf3c2SXin Li public class ClassPool { 71*f1fbf3c2SXin Li 72*f1fbf3c2SXin Li /** 73*f1fbf3c2SXin Li * Determines the search order. 74*f1fbf3c2SXin Li * 75*f1fbf3c2SXin Li * <p>If this field is true, <code>get()</code> first searches the 76*f1fbf3c2SXin Li * class path associated to this <code>ClassPool</code> and then 77*f1fbf3c2SXin Li * the class path associated with the parent <code>ClassPool</code>. 78*f1fbf3c2SXin Li * Otherwise, the class path associated with the parent is searched 79*f1fbf3c2SXin Li * first. 80*f1fbf3c2SXin Li * 81*f1fbf3c2SXin Li * <p>The default value is false. 82*f1fbf3c2SXin Li */ 83*f1fbf3c2SXin Li public boolean childFirstLookup = false; 84*f1fbf3c2SXin Li 85*f1fbf3c2SXin Li /** 86*f1fbf3c2SXin Li * Turning the automatic pruning on/off. 87*f1fbf3c2SXin Li * 88*f1fbf3c2SXin Li * <p>If this field is true, <code>CtClass</code> objects are 89*f1fbf3c2SXin Li * automatically pruned by default when <code>toBytecode()</code> etc. 90*f1fbf3c2SXin Li * are called. The automatic pruning can be turned on/off individually 91*f1fbf3c2SXin Li * for each <code>CtClass</code> object. 92*f1fbf3c2SXin Li * 93*f1fbf3c2SXin Li * <p>The initial value is false. 94*f1fbf3c2SXin Li * 95*f1fbf3c2SXin Li * @see CtClass#prune() 96*f1fbf3c2SXin Li * @see CtClass#stopPruning(boolean) 97*f1fbf3c2SXin Li * @see CtClass#detach() 98*f1fbf3c2SXin Li */ 99*f1fbf3c2SXin Li public static boolean doPruning = false; 100*f1fbf3c2SXin Li 101*f1fbf3c2SXin Li private int compressCount; 102*f1fbf3c2SXin Li private static final int COMPRESS_THRESHOLD = 100; 103*f1fbf3c2SXin Li 104*f1fbf3c2SXin Li /* releaseUnmodifiedClassFile was introduced for avoiding a bug 105*f1fbf3c2SXin Li of JBoss AOP. So the value should be true except for JBoss AOP. 106*f1fbf3c2SXin Li */ 107*f1fbf3c2SXin Li 108*f1fbf3c2SXin Li /** 109*f1fbf3c2SXin Li * If true, unmodified and not-recently-used class files are 110*f1fbf3c2SXin Li * periodically released for saving memory. 111*f1fbf3c2SXin Li * 112*f1fbf3c2SXin Li * <p>The initial value is true. 113*f1fbf3c2SXin Li */ 114*f1fbf3c2SXin Li public static boolean releaseUnmodifiedClassFile = true; 115*f1fbf3c2SXin Li 116*f1fbf3c2SXin Li protected ClassPoolTail source; 117*f1fbf3c2SXin Li protected ClassPool parent; 118*f1fbf3c2SXin Li protected Hashtable classes; // should be synchronous 119*f1fbf3c2SXin Li 120*f1fbf3c2SXin Li /** 121*f1fbf3c2SXin Li * Table of registered cflow variables. 122*f1fbf3c2SXin Li */ 123*f1fbf3c2SXin Li private Hashtable cflow = null; // should be synchronous. 124*f1fbf3c2SXin Li 125*f1fbf3c2SXin Li private static final int INIT_HASH_SIZE = 191; 126*f1fbf3c2SXin Li 127*f1fbf3c2SXin Li private ArrayList importedPackages; 128*f1fbf3c2SXin Li 129*f1fbf3c2SXin Li /** 130*f1fbf3c2SXin Li * Creates a root class pool. No parent class pool is specified. 131*f1fbf3c2SXin Li */ ClassPool()132*f1fbf3c2SXin Li public ClassPool() { 133*f1fbf3c2SXin Li this(null); 134*f1fbf3c2SXin Li } 135*f1fbf3c2SXin Li 136*f1fbf3c2SXin Li /** 137*f1fbf3c2SXin Li * Creates a root class pool. If <code>useDefaultPath</code> is 138*f1fbf3c2SXin Li * true, <code>appendSystemPath()</code> is called. Otherwise, 139*f1fbf3c2SXin Li * this constructor is equivalent to the constructor taking no 140*f1fbf3c2SXin Li * parameter. 141*f1fbf3c2SXin Li * 142*f1fbf3c2SXin Li * @param useDefaultPath true if the system search path is 143*f1fbf3c2SXin Li * appended. 144*f1fbf3c2SXin Li */ ClassPool(boolean useDefaultPath)145*f1fbf3c2SXin Li public ClassPool(boolean useDefaultPath) { 146*f1fbf3c2SXin Li this(null); 147*f1fbf3c2SXin Li if (useDefaultPath) 148*f1fbf3c2SXin Li appendSystemPath(); 149*f1fbf3c2SXin Li } 150*f1fbf3c2SXin Li 151*f1fbf3c2SXin Li /** 152*f1fbf3c2SXin Li * Creates a class pool. 153*f1fbf3c2SXin Li * 154*f1fbf3c2SXin Li * @param parent the parent of this class pool. If this is a root 155*f1fbf3c2SXin Li * class pool, this parameter must be <code>null</code>. 156*f1fbf3c2SXin Li * @see javassist.ClassPool#getDefault() 157*f1fbf3c2SXin Li */ ClassPool(ClassPool parent)158*f1fbf3c2SXin Li public ClassPool(ClassPool parent) { 159*f1fbf3c2SXin Li this.classes = new Hashtable(INIT_HASH_SIZE); 160*f1fbf3c2SXin Li this.source = new ClassPoolTail(); 161*f1fbf3c2SXin Li this.parent = parent; 162*f1fbf3c2SXin Li if (parent == null) { 163*f1fbf3c2SXin Li CtClass[] pt = CtClass.primitiveTypes; 164*f1fbf3c2SXin Li for (int i = 0; i < pt.length; ++i) 165*f1fbf3c2SXin Li classes.put(pt[i].getName(), pt[i]); 166*f1fbf3c2SXin Li } 167*f1fbf3c2SXin Li 168*f1fbf3c2SXin Li this.cflow = null; 169*f1fbf3c2SXin Li this.compressCount = 0; 170*f1fbf3c2SXin Li clearImportedPackages(); 171*f1fbf3c2SXin Li } 172*f1fbf3c2SXin Li 173*f1fbf3c2SXin Li /** 174*f1fbf3c2SXin Li * Returns the default class pool. 175*f1fbf3c2SXin Li * The returned object is always identical since this method is 176*f1fbf3c2SXin Li * a singleton factory. 177*f1fbf3c2SXin Li * 178*f1fbf3c2SXin Li * <p>The default class pool searches the system search path, 179*f1fbf3c2SXin Li * which usually includes the platform library, extension 180*f1fbf3c2SXin Li * libraries, and the search path specified by the 181*f1fbf3c2SXin Li * <code>-classpath</code> option or the <code>CLASSPATH</code> 182*f1fbf3c2SXin Li * environment variable. 183*f1fbf3c2SXin Li * 184*f1fbf3c2SXin Li * <p>When this method is called for the first time, the default 185*f1fbf3c2SXin Li * class pool is created with the following code snippet: 186*f1fbf3c2SXin Li * 187*f1fbf3c2SXin Li * <pre>ClassPool cp = new ClassPool(); 188*f1fbf3c2SXin Li * cp.appendSystemPath(); 189*f1fbf3c2SXin Li * </pre> 190*f1fbf3c2SXin Li * 191*f1fbf3c2SXin Li * <p>If the default class pool cannot find any class files, 192*f1fbf3c2SXin Li * try <code>ClassClassPath</code>, <code>ModuleClassPath</code>, 193*f1fbf3c2SXin Li * or <code>LoaderClassPath</code>. 194*f1fbf3c2SXin Li * 195*f1fbf3c2SXin Li * @see ClassClassPath 196*f1fbf3c2SXin Li * @see LoaderClassPath 197*f1fbf3c2SXin Li */ getDefault()198*f1fbf3c2SXin Li public static synchronized ClassPool getDefault() { 199*f1fbf3c2SXin Li if (defaultPool == null) { 200*f1fbf3c2SXin Li defaultPool = new ClassPool(null); 201*f1fbf3c2SXin Li defaultPool.appendSystemPath(); 202*f1fbf3c2SXin Li } 203*f1fbf3c2SXin Li 204*f1fbf3c2SXin Li return defaultPool; 205*f1fbf3c2SXin Li } 206*f1fbf3c2SXin Li 207*f1fbf3c2SXin Li private static ClassPool defaultPool = null; 208*f1fbf3c2SXin Li 209*f1fbf3c2SXin Li /** 210*f1fbf3c2SXin Li * Provide a hook so that subclasses can do their own 211*f1fbf3c2SXin Li * caching of classes. 212*f1fbf3c2SXin Li * 213*f1fbf3c2SXin Li * @see #cacheCtClass(String,CtClass,boolean) 214*f1fbf3c2SXin Li * @see #removeCached(String) 215*f1fbf3c2SXin Li */ getCached(String classname)216*f1fbf3c2SXin Li protected CtClass getCached(String classname) { 217*f1fbf3c2SXin Li return (CtClass)classes.get(classname); 218*f1fbf3c2SXin Li } 219*f1fbf3c2SXin Li 220*f1fbf3c2SXin Li /** 221*f1fbf3c2SXin Li * Provides a hook so that subclasses can do their own 222*f1fbf3c2SXin Li * caching of classes. 223*f1fbf3c2SXin Li * 224*f1fbf3c2SXin Li * @see #getCached(String) 225*f1fbf3c2SXin Li * @see #removeCached(String) 226*f1fbf3c2SXin Li */ cacheCtClass(String classname, CtClass c, boolean dynamic)227*f1fbf3c2SXin Li protected void cacheCtClass(String classname, CtClass c, boolean dynamic) { 228*f1fbf3c2SXin Li classes.put(classname, c); 229*f1fbf3c2SXin Li } 230*f1fbf3c2SXin Li 231*f1fbf3c2SXin Li /** 232*f1fbf3c2SXin Li * Provide a hook so that subclasses can do their own 233*f1fbf3c2SXin Li * caching of classes. 234*f1fbf3c2SXin Li * 235*f1fbf3c2SXin Li * @see #getCached(String) 236*f1fbf3c2SXin Li * @see #cacheCtClass(String,CtClass,boolean) 237*f1fbf3c2SXin Li */ removeCached(String classname)238*f1fbf3c2SXin Li protected CtClass removeCached(String classname) { 239*f1fbf3c2SXin Li return (CtClass)classes.remove(classname); 240*f1fbf3c2SXin Li } 241*f1fbf3c2SXin Li 242*f1fbf3c2SXin Li /** 243*f1fbf3c2SXin Li * Returns the class search path. 244*f1fbf3c2SXin Li */ toString()245*f1fbf3c2SXin Li public String toString() { 246*f1fbf3c2SXin Li return source.toString(); 247*f1fbf3c2SXin Li } 248*f1fbf3c2SXin Li 249*f1fbf3c2SXin Li /** 250*f1fbf3c2SXin Li * This method is periodically invoked so that memory 251*f1fbf3c2SXin Li * footprint will be minimized. 252*f1fbf3c2SXin Li */ compress()253*f1fbf3c2SXin Li void compress() { 254*f1fbf3c2SXin Li if (compressCount++ > COMPRESS_THRESHOLD) { 255*f1fbf3c2SXin Li compressCount = 0; 256*f1fbf3c2SXin Li Enumeration e = classes.elements(); 257*f1fbf3c2SXin Li while (e.hasMoreElements()) 258*f1fbf3c2SXin Li ((CtClass)e.nextElement()).compress(); 259*f1fbf3c2SXin Li } 260*f1fbf3c2SXin Li } 261*f1fbf3c2SXin Li 262*f1fbf3c2SXin Li /** 263*f1fbf3c2SXin Li * Record a package name so that the Javassist compiler searches 264*f1fbf3c2SXin Li * the package to resolve a class name. 265*f1fbf3c2SXin Li * Don't record the <code>java.lang</code> package, which has 266*f1fbf3c2SXin Li * been implicitly recorded by default. 267*f1fbf3c2SXin Li * 268*f1fbf3c2SXin Li * <p>Since version 3.14, <code>packageName</code> can be a 269*f1fbf3c2SXin Li * fully-qualified class name. 270*f1fbf3c2SXin Li * 271*f1fbf3c2SXin Li * <p>Note that <code>get()</code> in <code>ClassPool</code> does 272*f1fbf3c2SXin Li * not search the recorded package. Only the compiler searches it. 273*f1fbf3c2SXin Li * 274*f1fbf3c2SXin Li * @param packageName the package name. 275*f1fbf3c2SXin Li * It must not include the last '.' (dot). 276*f1fbf3c2SXin Li * For example, "java.util" is valid but "java.util." is wrong. 277*f1fbf3c2SXin Li * @since 3.1 278*f1fbf3c2SXin Li */ importPackage(String packageName)279*f1fbf3c2SXin Li public void importPackage(String packageName) { 280*f1fbf3c2SXin Li importedPackages.add(packageName); 281*f1fbf3c2SXin Li } 282*f1fbf3c2SXin Li 283*f1fbf3c2SXin Li /** 284*f1fbf3c2SXin Li * Clear all the package names recorded by <code>importPackage()</code>. 285*f1fbf3c2SXin Li * The <code>java.lang</code> package is not removed. 286*f1fbf3c2SXin Li * 287*f1fbf3c2SXin Li * @see #importPackage(String) 288*f1fbf3c2SXin Li * @since 3.1 289*f1fbf3c2SXin Li */ clearImportedPackages()290*f1fbf3c2SXin Li public void clearImportedPackages() { 291*f1fbf3c2SXin Li importedPackages = new ArrayList(); 292*f1fbf3c2SXin Li importedPackages.add("java.lang"); 293*f1fbf3c2SXin Li } 294*f1fbf3c2SXin Li 295*f1fbf3c2SXin Li /** 296*f1fbf3c2SXin Li * Returns all the package names recorded by <code>importPackage()</code>. 297*f1fbf3c2SXin Li * 298*f1fbf3c2SXin Li * @see #importPackage(String) 299*f1fbf3c2SXin Li * @since 3.1 300*f1fbf3c2SXin Li */ getImportedPackages()301*f1fbf3c2SXin Li public Iterator<String> getImportedPackages() { 302*f1fbf3c2SXin Li return importedPackages.iterator(); 303*f1fbf3c2SXin Li } 304*f1fbf3c2SXin Li 305*f1fbf3c2SXin Li /** 306*f1fbf3c2SXin Li * Records a class name that never exists. 307*f1fbf3c2SXin Li * For example, a package name can be recorded by this method. 308*f1fbf3c2SXin Li * This would improve execution performance 309*f1fbf3c2SXin Li * since <code>get()</code> quickly throw an exception 310*f1fbf3c2SXin Li * without searching the class path at all 311*f1fbf3c2SXin Li * if the given name is an invalid name recorded by this method. 312*f1fbf3c2SXin Li * Note that searching the class path takes relatively long time. 313*f1fbf3c2SXin Li * 314*f1fbf3c2SXin Li * <p>The current implementation of this method performs nothing. 315*f1fbf3c2SXin Li * 316*f1fbf3c2SXin Li * @param name an invalid class name (separeted by dots). 317*f1fbf3c2SXin Li * @deprecated 318*f1fbf3c2SXin Li */ recordInvalidClassName(String name)319*f1fbf3c2SXin Li public void recordInvalidClassName(String name) { 320*f1fbf3c2SXin Li // source.recordInvalidClassName(name); 321*f1fbf3c2SXin Li } 322*f1fbf3c2SXin Li 323*f1fbf3c2SXin Li /** 324*f1fbf3c2SXin Li * Records the <code>$cflow</code> variable for the field specified 325*f1fbf3c2SXin Li * by <code>cname</code> and <code>fname</code>. 326*f1fbf3c2SXin Li * 327*f1fbf3c2SXin Li * @param name variable name 328*f1fbf3c2SXin Li * @param cname class name 329*f1fbf3c2SXin Li * @param fname field name 330*f1fbf3c2SXin Li */ recordCflow(String name, String cname, String fname)331*f1fbf3c2SXin Li void recordCflow(String name, String cname, String fname) { 332*f1fbf3c2SXin Li if (cflow == null) 333*f1fbf3c2SXin Li cflow = new Hashtable(); 334*f1fbf3c2SXin Li 335*f1fbf3c2SXin Li cflow.put(name, new Object[] { cname, fname }); 336*f1fbf3c2SXin Li } 337*f1fbf3c2SXin Li 338*f1fbf3c2SXin Li /** 339*f1fbf3c2SXin Li * Undocumented method. Do not use; internal-use only. 340*f1fbf3c2SXin Li * 341*f1fbf3c2SXin Li * @param name the name of <code>$cflow</code> variable 342*f1fbf3c2SXin Li */ lookupCflow(String name)343*f1fbf3c2SXin Li public Object[] lookupCflow(String name) { 344*f1fbf3c2SXin Li if (cflow == null) 345*f1fbf3c2SXin Li cflow = new Hashtable(); 346*f1fbf3c2SXin Li 347*f1fbf3c2SXin Li return (Object[])cflow.get(name); 348*f1fbf3c2SXin Li } 349*f1fbf3c2SXin Li 350*f1fbf3c2SXin Li /** 351*f1fbf3c2SXin Li * Reads a class file and constructs a <code>CtClass</code> 352*f1fbf3c2SXin Li * object with a new name. 353*f1fbf3c2SXin Li * This method is useful if you want to generate a new class as a copy 354*f1fbf3c2SXin Li * of another class (except the class name). For example, 355*f1fbf3c2SXin Li * 356*f1fbf3c2SXin Li * <pre> 357*f1fbf3c2SXin Li * getAndRename("Point", "Pair") 358*f1fbf3c2SXin Li * </pre> 359*f1fbf3c2SXin Li * 360*f1fbf3c2SXin Li * returns a <code>CtClass</code> object representing <code>Pair</code> 361*f1fbf3c2SXin Li * class. The definition of <code>Pair</code> is the same as that of 362*f1fbf3c2SXin Li * <code>Point</code> class except the class name since <code>Pair</code> 363*f1fbf3c2SXin Li * is defined by reading <code>Point.class</code>. 364*f1fbf3c2SXin Li * 365*f1fbf3c2SXin Li * @param orgName the original (fully-qualified) class name 366*f1fbf3c2SXin Li * @param newName the new class name 367*f1fbf3c2SXin Li */ getAndRename(String orgName, String newName)368*f1fbf3c2SXin Li public CtClass getAndRename(String orgName, String newName) 369*f1fbf3c2SXin Li throws NotFoundException 370*f1fbf3c2SXin Li { 371*f1fbf3c2SXin Li CtClass clazz = get0(orgName, false); 372*f1fbf3c2SXin Li if (clazz == null) 373*f1fbf3c2SXin Li throw new NotFoundException(orgName); 374*f1fbf3c2SXin Li 375*f1fbf3c2SXin Li if (clazz instanceof CtClassType) 376*f1fbf3c2SXin Li ((CtClassType)clazz).setClassPool(this); 377*f1fbf3c2SXin Li 378*f1fbf3c2SXin Li clazz.setName(newName); // indirectly calls 379*f1fbf3c2SXin Li // classNameChanged() in this class 380*f1fbf3c2SXin Li return clazz; 381*f1fbf3c2SXin Li } 382*f1fbf3c2SXin Li 383*f1fbf3c2SXin Li /* 384*f1fbf3c2SXin Li * This method is invoked by CtClassType.setName(). It removes a 385*f1fbf3c2SXin Li * CtClass object from the hash table and inserts it with the new 386*f1fbf3c2SXin Li * name. Don't delegate to the parent. 387*f1fbf3c2SXin Li */ classNameChanged(String oldname, CtClass clazz)388*f1fbf3c2SXin Li synchronized void classNameChanged(String oldname, CtClass clazz) { 389*f1fbf3c2SXin Li CtClass c = (CtClass)getCached(oldname); 390*f1fbf3c2SXin Li if (c == clazz) // must check this equation. 391*f1fbf3c2SXin Li removeCached(oldname); // see getAndRename(). 392*f1fbf3c2SXin Li 393*f1fbf3c2SXin Li String newName = clazz.getName(); 394*f1fbf3c2SXin Li checkNotFrozen(newName); 395*f1fbf3c2SXin Li cacheCtClass(newName, clazz, false); 396*f1fbf3c2SXin Li } 397*f1fbf3c2SXin Li 398*f1fbf3c2SXin Li /** 399*f1fbf3c2SXin Li * Reads a class file from the source and returns a reference 400*f1fbf3c2SXin Li * to the <code>CtClass</code> 401*f1fbf3c2SXin Li * object representing that class file. If that class file has been 402*f1fbf3c2SXin Li * already read, this method returns a reference to the 403*f1fbf3c2SXin Li * <code>CtClass</code> created when that class file was read at the 404*f1fbf3c2SXin Li * first time. 405*f1fbf3c2SXin Li * 406*f1fbf3c2SXin Li * <p>If <code>classname</code> ends with "[]", then this method 407*f1fbf3c2SXin Li * returns a <code>CtClass</code> object for that array type. 408*f1fbf3c2SXin Li * 409*f1fbf3c2SXin Li * <p>To obtain an inner class, use "$" instead of "." for separating 410*f1fbf3c2SXin Li * the enclosing class name and the inner class name. 411*f1fbf3c2SXin Li * 412*f1fbf3c2SXin Li * @param classname a fully-qualified class name. 413*f1fbf3c2SXin Li */ get(String classname)414*f1fbf3c2SXin Li public CtClass get(String classname) throws NotFoundException { 415*f1fbf3c2SXin Li CtClass clazz; 416*f1fbf3c2SXin Li if (classname == null) 417*f1fbf3c2SXin Li clazz = null; 418*f1fbf3c2SXin Li else 419*f1fbf3c2SXin Li clazz = get0(classname, true); 420*f1fbf3c2SXin Li 421*f1fbf3c2SXin Li if (clazz == null) 422*f1fbf3c2SXin Li throw new NotFoundException(classname); 423*f1fbf3c2SXin Li else { 424*f1fbf3c2SXin Li clazz.incGetCounter(); 425*f1fbf3c2SXin Li return clazz; 426*f1fbf3c2SXin Li } 427*f1fbf3c2SXin Li } 428*f1fbf3c2SXin Li 429*f1fbf3c2SXin Li /** 430*f1fbf3c2SXin Li * Reads a class file from the source and returns a reference 431*f1fbf3c2SXin Li * to the <code>CtClass</code> 432*f1fbf3c2SXin Li * object representing that class file. 433*f1fbf3c2SXin Li * This method is equivalent to <code>get</code> except 434*f1fbf3c2SXin Li * that it returns <code>null</code> when a class file is 435*f1fbf3c2SXin Li * not found and it never throws an exception. 436*f1fbf3c2SXin Li * 437*f1fbf3c2SXin Li * @param classname a fully-qualified class name. 438*f1fbf3c2SXin Li * @return a <code>CtClass</code> object or <code>null</code>. 439*f1fbf3c2SXin Li * @see #get(String) 440*f1fbf3c2SXin Li * @see #find(String) 441*f1fbf3c2SXin Li * @since 3.13 442*f1fbf3c2SXin Li */ getOrNull(String classname)443*f1fbf3c2SXin Li public CtClass getOrNull(String classname) { 444*f1fbf3c2SXin Li CtClass clazz = null; 445*f1fbf3c2SXin Li if (classname == null) 446*f1fbf3c2SXin Li clazz = null; 447*f1fbf3c2SXin Li else 448*f1fbf3c2SXin Li try { 449*f1fbf3c2SXin Li /* ClassPool.get0() never throws an exception 450*f1fbf3c2SXin Li but its subclass may implement get0 that 451*f1fbf3c2SXin Li may throw an exception. 452*f1fbf3c2SXin Li */ 453*f1fbf3c2SXin Li clazz = get0(classname, true); 454*f1fbf3c2SXin Li } 455*f1fbf3c2SXin Li catch (NotFoundException e){} 456*f1fbf3c2SXin Li 457*f1fbf3c2SXin Li if (clazz != null) 458*f1fbf3c2SXin Li clazz.incGetCounter(); 459*f1fbf3c2SXin Li 460*f1fbf3c2SXin Li return clazz; 461*f1fbf3c2SXin Li } 462*f1fbf3c2SXin Li 463*f1fbf3c2SXin Li /** 464*f1fbf3c2SXin Li * Returns a <code>CtClass</code> object with the given name. 465*f1fbf3c2SXin Li * This is almost equivalent to <code>get(String)</code> except 466*f1fbf3c2SXin Li * that classname can be an array-type "descriptor" (an encoded 467*f1fbf3c2SXin Li * type name) such as <code>[Ljava/lang/Object;</code>. 468*f1fbf3c2SXin Li * 469*f1fbf3c2SXin Li * <p>Using this method is not recommended; this method should be 470*f1fbf3c2SXin Li * used only to obtain the <code>CtClass</code> object 471*f1fbf3c2SXin Li * with a name returned from <code>getClassInfo</code> in 472*f1fbf3c2SXin Li * <code>javassist.bytecode.ClassPool</code>. <code>getClassInfo</code> 473*f1fbf3c2SXin Li * returns a fully-qualified class name but, if the class is an array 474*f1fbf3c2SXin Li * type, it returns a descriptor. 475*f1fbf3c2SXin Li * 476*f1fbf3c2SXin Li * @param classname a fully-qualified class name or a descriptor 477*f1fbf3c2SXin Li * representing an array type. 478*f1fbf3c2SXin Li * @see #get(String) 479*f1fbf3c2SXin Li * @see javassist.bytecode.ConstPool#getClassInfo(int) 480*f1fbf3c2SXin Li * @see javassist.bytecode.Descriptor#toCtClass(String, ClassPool) 481*f1fbf3c2SXin Li * @since 3.8.1 482*f1fbf3c2SXin Li */ getCtClass(String classname)483*f1fbf3c2SXin Li public CtClass getCtClass(String classname) throws NotFoundException { 484*f1fbf3c2SXin Li if (classname.charAt(0) == '[') 485*f1fbf3c2SXin Li return Descriptor.toCtClass(classname, this); 486*f1fbf3c2SXin Li else 487*f1fbf3c2SXin Li return get(classname); 488*f1fbf3c2SXin Li } 489*f1fbf3c2SXin Li 490*f1fbf3c2SXin Li /** 491*f1fbf3c2SXin Li * @param useCache false if the cached CtClass must be ignored. 492*f1fbf3c2SXin Li * @return null if the class could not be found. 493*f1fbf3c2SXin Li */ get0(String classname, boolean useCache)494*f1fbf3c2SXin Li protected synchronized CtClass get0(String classname, boolean useCache) 495*f1fbf3c2SXin Li throws NotFoundException 496*f1fbf3c2SXin Li { 497*f1fbf3c2SXin Li CtClass clazz = null; 498*f1fbf3c2SXin Li if (useCache) { 499*f1fbf3c2SXin Li clazz = getCached(classname); 500*f1fbf3c2SXin Li if (clazz != null) 501*f1fbf3c2SXin Li return clazz; 502*f1fbf3c2SXin Li } 503*f1fbf3c2SXin Li 504*f1fbf3c2SXin Li if (!childFirstLookup && parent != null) { 505*f1fbf3c2SXin Li clazz = parent.get0(classname, useCache); 506*f1fbf3c2SXin Li if (clazz != null) 507*f1fbf3c2SXin Li return clazz; 508*f1fbf3c2SXin Li } 509*f1fbf3c2SXin Li 510*f1fbf3c2SXin Li clazz = createCtClass(classname, useCache); 511*f1fbf3c2SXin Li if (clazz != null) { 512*f1fbf3c2SXin Li // clazz.getName() != classname if classname is "[L<name>;". 513*f1fbf3c2SXin Li if (useCache) 514*f1fbf3c2SXin Li cacheCtClass(clazz.getName(), clazz, false); 515*f1fbf3c2SXin Li 516*f1fbf3c2SXin Li return clazz; 517*f1fbf3c2SXin Li } 518*f1fbf3c2SXin Li 519*f1fbf3c2SXin Li if (childFirstLookup && parent != null) 520*f1fbf3c2SXin Li clazz = parent.get0(classname, useCache); 521*f1fbf3c2SXin Li 522*f1fbf3c2SXin Li return clazz; 523*f1fbf3c2SXin Li } 524*f1fbf3c2SXin Li 525*f1fbf3c2SXin Li /** 526*f1fbf3c2SXin Li * Creates a CtClass object representing the specified class. 527*f1fbf3c2SXin Li * It first examines whether or not the corresponding class 528*f1fbf3c2SXin Li * file exists. If yes, it creates a CtClass object. 529*f1fbf3c2SXin Li * 530*f1fbf3c2SXin Li * @return null if the class file could not be found. 531*f1fbf3c2SXin Li */ createCtClass(String classname, boolean useCache)532*f1fbf3c2SXin Li protected CtClass createCtClass(String classname, boolean useCache) { 533*f1fbf3c2SXin Li // accept "[L<class name>;" as a class name. 534*f1fbf3c2SXin Li if (classname.charAt(0) == '[') 535*f1fbf3c2SXin Li classname = Descriptor.toClassName(classname); 536*f1fbf3c2SXin Li 537*f1fbf3c2SXin Li if (classname.endsWith("[]")) { 538*f1fbf3c2SXin Li String base = classname.substring(0, classname.indexOf('[')); 539*f1fbf3c2SXin Li if ((!useCache || getCached(base) == null) && find(base) == null) 540*f1fbf3c2SXin Li return null; 541*f1fbf3c2SXin Li else 542*f1fbf3c2SXin Li return new CtArray(classname, this); 543*f1fbf3c2SXin Li } 544*f1fbf3c2SXin Li else 545*f1fbf3c2SXin Li if (find(classname) == null) 546*f1fbf3c2SXin Li return null; 547*f1fbf3c2SXin Li else 548*f1fbf3c2SXin Li return new CtClassType(classname, this); 549*f1fbf3c2SXin Li } 550*f1fbf3c2SXin Li 551*f1fbf3c2SXin Li /** 552*f1fbf3c2SXin Li * Searches the class path to obtain the URL of the class file 553*f1fbf3c2SXin Li * specified by classname. It is also used to determine whether 554*f1fbf3c2SXin Li * the class file exists. 555*f1fbf3c2SXin Li * 556*f1fbf3c2SXin Li * @param classname a fully-qualified class name. 557*f1fbf3c2SXin Li * @return null if the class file could not be found. 558*f1fbf3c2SXin Li * @see CtClass#getURL() 559*f1fbf3c2SXin Li */ find(String classname)560*f1fbf3c2SXin Li public URL find(String classname) { 561*f1fbf3c2SXin Li return source.find(classname); 562*f1fbf3c2SXin Li } 563*f1fbf3c2SXin Li 564*f1fbf3c2SXin Li /* 565*f1fbf3c2SXin Li * Is invoked by CtClassType.setName() and methods in this class. 566*f1fbf3c2SXin Li * This method throws an exception if the class is already frozen or 567*f1fbf3c2SXin Li * if this class pool cannot edit the class since it is in a parent 568*f1fbf3c2SXin Li * class pool. 569*f1fbf3c2SXin Li * 570*f1fbf3c2SXin Li * @see checkNotExists(String) 571*f1fbf3c2SXin Li */ checkNotFrozen(String classname)572*f1fbf3c2SXin Li void checkNotFrozen(String classname) throws RuntimeException { 573*f1fbf3c2SXin Li CtClass clazz = getCached(classname); 574*f1fbf3c2SXin Li if (clazz == null) { 575*f1fbf3c2SXin Li if (!childFirstLookup && parent != null) { 576*f1fbf3c2SXin Li try { 577*f1fbf3c2SXin Li clazz = parent.get0(classname, true); 578*f1fbf3c2SXin Li } 579*f1fbf3c2SXin Li catch (NotFoundException e) {} 580*f1fbf3c2SXin Li if (clazz != null) 581*f1fbf3c2SXin Li throw new RuntimeException(classname 582*f1fbf3c2SXin Li + " is in a parent ClassPool. Use the parent."); 583*f1fbf3c2SXin Li } 584*f1fbf3c2SXin Li } 585*f1fbf3c2SXin Li else 586*f1fbf3c2SXin Li if (clazz.isFrozen()) 587*f1fbf3c2SXin Li throw new RuntimeException(classname 588*f1fbf3c2SXin Li + ": frozen class (cannot edit)"); 589*f1fbf3c2SXin Li } 590*f1fbf3c2SXin Li 591*f1fbf3c2SXin Li /* 592*f1fbf3c2SXin Li * This method returns null if this or its parent class pool does 593*f1fbf3c2SXin Li * not contain a CtClass object with the class name. 594*f1fbf3c2SXin Li * 595*f1fbf3c2SXin Li * @see checkNotFrozen(String) 596*f1fbf3c2SXin Li */ checkNotExists(String classname)597*f1fbf3c2SXin Li CtClass checkNotExists(String classname) { 598*f1fbf3c2SXin Li CtClass clazz = getCached(classname); 599*f1fbf3c2SXin Li if (clazz == null) 600*f1fbf3c2SXin Li if (!childFirstLookup && parent != null) { 601*f1fbf3c2SXin Li try { 602*f1fbf3c2SXin Li clazz = parent.get0(classname, true); 603*f1fbf3c2SXin Li } 604*f1fbf3c2SXin Li catch (NotFoundException e) {} 605*f1fbf3c2SXin Li } 606*f1fbf3c2SXin Li 607*f1fbf3c2SXin Li return clazz; 608*f1fbf3c2SXin Li } 609*f1fbf3c2SXin Li 610*f1fbf3c2SXin Li /* for CtClassType.getClassFile2(). Don't delegate to the parent. 611*f1fbf3c2SXin Li */ openClassfile(String classname)612*f1fbf3c2SXin Li InputStream openClassfile(String classname) throws NotFoundException { 613*f1fbf3c2SXin Li return source.openClassfile(classname); 614*f1fbf3c2SXin Li } 615*f1fbf3c2SXin Li writeClassfile(String classname, OutputStream out)616*f1fbf3c2SXin Li void writeClassfile(String classname, OutputStream out) 617*f1fbf3c2SXin Li throws NotFoundException, IOException, CannotCompileException 618*f1fbf3c2SXin Li { 619*f1fbf3c2SXin Li source.writeClassfile(classname, out); 620*f1fbf3c2SXin Li } 621*f1fbf3c2SXin Li 622*f1fbf3c2SXin Li /** 623*f1fbf3c2SXin Li * Reads class files from the source and returns an array of 624*f1fbf3c2SXin Li * <code>CtClass</code> 625*f1fbf3c2SXin Li * objects representing those class files. 626*f1fbf3c2SXin Li * 627*f1fbf3c2SXin Li * <p>If an element of <code>classnames</code> ends with "[]", 628*f1fbf3c2SXin Li * then this method 629*f1fbf3c2SXin Li * returns a <code>CtClass</code> object for that array type. 630*f1fbf3c2SXin Li * 631*f1fbf3c2SXin Li * @param classnames an array of fully-qualified class name. 632*f1fbf3c2SXin Li */ get(String[] classnames)633*f1fbf3c2SXin Li public CtClass[] get(String[] classnames) throws NotFoundException { 634*f1fbf3c2SXin Li if (classnames == null) 635*f1fbf3c2SXin Li return new CtClass[0]; 636*f1fbf3c2SXin Li 637*f1fbf3c2SXin Li int num = classnames.length; 638*f1fbf3c2SXin Li CtClass[] result = new CtClass[num]; 639*f1fbf3c2SXin Li for (int i = 0; i < num; ++i) 640*f1fbf3c2SXin Li result[i] = get(classnames[i]); 641*f1fbf3c2SXin Li 642*f1fbf3c2SXin Li return result; 643*f1fbf3c2SXin Li } 644*f1fbf3c2SXin Li 645*f1fbf3c2SXin Li /** 646*f1fbf3c2SXin Li * Reads a class file and obtains a compile-time method. 647*f1fbf3c2SXin Li * 648*f1fbf3c2SXin Li * @param classname the class name 649*f1fbf3c2SXin Li * @param methodname the method name 650*f1fbf3c2SXin Li * @see CtClass#getDeclaredMethod(String) 651*f1fbf3c2SXin Li */ getMethod(String classname, String methodname)652*f1fbf3c2SXin Li public CtMethod getMethod(String classname, String methodname) 653*f1fbf3c2SXin Li throws NotFoundException 654*f1fbf3c2SXin Li { 655*f1fbf3c2SXin Li CtClass c = get(classname); 656*f1fbf3c2SXin Li return c.getDeclaredMethod(methodname); 657*f1fbf3c2SXin Li } 658*f1fbf3c2SXin Li 659*f1fbf3c2SXin Li /** 660*f1fbf3c2SXin Li * Creates a new class (or interface) from the given class file. 661*f1fbf3c2SXin Li * If there already exists a class with the same name, the new class 662*f1fbf3c2SXin Li * overwrites that previous class. 663*f1fbf3c2SXin Li * 664*f1fbf3c2SXin Li * <p>This method is used for creating a <code>CtClass</code> object 665*f1fbf3c2SXin Li * directly from a class file. The qualified class name is obtained 666*f1fbf3c2SXin Li * from the class file; you do not have to explicitly give the name. 667*f1fbf3c2SXin Li * 668*f1fbf3c2SXin Li * @param classfile class file. 669*f1fbf3c2SXin Li * @throws RuntimeException if there is a frozen class with the 670*f1fbf3c2SXin Li * the same name. 671*f1fbf3c2SXin Li * @see #makeClassIfNew(InputStream) 672*f1fbf3c2SXin Li * @see javassist.ByteArrayClassPath 673*f1fbf3c2SXin Li */ makeClass(InputStream classfile)674*f1fbf3c2SXin Li public CtClass makeClass(InputStream classfile) 675*f1fbf3c2SXin Li throws IOException, RuntimeException 676*f1fbf3c2SXin Li { 677*f1fbf3c2SXin Li return makeClass(classfile, true); 678*f1fbf3c2SXin Li } 679*f1fbf3c2SXin Li 680*f1fbf3c2SXin Li /** 681*f1fbf3c2SXin Li * Creates a new class (or interface) from the given class file. 682*f1fbf3c2SXin Li * If there already exists a class with the same name, the new class 683*f1fbf3c2SXin Li * overwrites that previous class. 684*f1fbf3c2SXin Li * 685*f1fbf3c2SXin Li * <p>This method is used for creating a <code>CtClass</code> object 686*f1fbf3c2SXin Li * directly from a class file. The qualified class name is obtained 687*f1fbf3c2SXin Li * from the class file; you do not have to explicitly give the name. 688*f1fbf3c2SXin Li * 689*f1fbf3c2SXin Li * @param classfile class file. 690*f1fbf3c2SXin Li * @param ifNotFrozen throws a RuntimeException if this parameter is true 691*f1fbf3c2SXin Li * and there is a frozen class with the same name. 692*f1fbf3c2SXin Li * @see javassist.ByteArrayClassPath 693*f1fbf3c2SXin Li */ makeClass(InputStream classfile, boolean ifNotFrozen)694*f1fbf3c2SXin Li public CtClass makeClass(InputStream classfile, boolean ifNotFrozen) 695*f1fbf3c2SXin Li throws IOException, RuntimeException 696*f1fbf3c2SXin Li { 697*f1fbf3c2SXin Li compress(); 698*f1fbf3c2SXin Li classfile = new BufferedInputStream(classfile); 699*f1fbf3c2SXin Li CtClass clazz = new CtClassType(classfile, this); 700*f1fbf3c2SXin Li clazz.checkModify(); 701*f1fbf3c2SXin Li String classname = clazz.getName(); 702*f1fbf3c2SXin Li if (ifNotFrozen) 703*f1fbf3c2SXin Li checkNotFrozen(classname); 704*f1fbf3c2SXin Li 705*f1fbf3c2SXin Li cacheCtClass(classname, clazz, true); 706*f1fbf3c2SXin Li return clazz; 707*f1fbf3c2SXin Li } 708*f1fbf3c2SXin Li 709*f1fbf3c2SXin Li /** 710*f1fbf3c2SXin Li * Creates a new class (or interface) from the given class file. 711*f1fbf3c2SXin Li * If there already exists a class with the same name, the new class 712*f1fbf3c2SXin Li * overwrites that previous class. 713*f1fbf3c2SXin Li * 714*f1fbf3c2SXin Li * <p>This method is used for creating a <code>CtClass</code> object 715*f1fbf3c2SXin Li * directly from a class file. The qualified class name is obtained 716*f1fbf3c2SXin Li * from the class file; you do not have to explicitly give the name. 717*f1fbf3c2SXin Li * 718*f1fbf3c2SXin Li * @param classfile class file. 719*f1fbf3c2SXin Li * @throws RuntimeException if there is a frozen class with the 720*f1fbf3c2SXin Li * the same name. 721*f1fbf3c2SXin Li * @since 3.20 722*f1fbf3c2SXin Li */ makeClass(ClassFile classfile)723*f1fbf3c2SXin Li public CtClass makeClass(ClassFile classfile) 724*f1fbf3c2SXin Li throws RuntimeException 725*f1fbf3c2SXin Li { 726*f1fbf3c2SXin Li return makeClass(classfile, true); 727*f1fbf3c2SXin Li } 728*f1fbf3c2SXin Li 729*f1fbf3c2SXin Li /** 730*f1fbf3c2SXin Li * Creates a new class (or interface) from the given class file. 731*f1fbf3c2SXin Li * If there already exists a class with the same name, the new class 732*f1fbf3c2SXin Li * overwrites that previous class. 733*f1fbf3c2SXin Li * 734*f1fbf3c2SXin Li * <p>This method is used for creating a <code>CtClass</code> object 735*f1fbf3c2SXin Li * directly from a class file. The qualified class name is obtained 736*f1fbf3c2SXin Li * from the class file; you do not have to explicitly give the name. 737*f1fbf3c2SXin Li * 738*f1fbf3c2SXin Li * @param classfile class file. 739*f1fbf3c2SXin Li * @param ifNotFrozen throws a RuntimeException if this parameter is true 740*f1fbf3c2SXin Li * and there is a frozen class with the same name. 741*f1fbf3c2SXin Li * @since 3.20 742*f1fbf3c2SXin Li */ makeClass(ClassFile classfile, boolean ifNotFrozen)743*f1fbf3c2SXin Li public CtClass makeClass(ClassFile classfile, boolean ifNotFrozen) 744*f1fbf3c2SXin Li throws RuntimeException 745*f1fbf3c2SXin Li { 746*f1fbf3c2SXin Li compress(); 747*f1fbf3c2SXin Li CtClass clazz = new CtClassType(classfile, this); 748*f1fbf3c2SXin Li clazz.checkModify(); 749*f1fbf3c2SXin Li String classname = clazz.getName(); 750*f1fbf3c2SXin Li if (ifNotFrozen) 751*f1fbf3c2SXin Li checkNotFrozen(classname); 752*f1fbf3c2SXin Li 753*f1fbf3c2SXin Li cacheCtClass(classname, clazz, true); 754*f1fbf3c2SXin Li return clazz; 755*f1fbf3c2SXin Li } 756*f1fbf3c2SXin Li 757*f1fbf3c2SXin Li /** 758*f1fbf3c2SXin Li * Creates a new class (or interface) from the given class file. 759*f1fbf3c2SXin Li * If there already exists a class with the same name, this method 760*f1fbf3c2SXin Li * returns the existing class; a new class is never created from 761*f1fbf3c2SXin Li * the given class file. 762*f1fbf3c2SXin Li * 763*f1fbf3c2SXin Li * <p>This method is used for creating a <code>CtClass</code> object 764*f1fbf3c2SXin Li * directly from a class file. The qualified class name is obtained 765*f1fbf3c2SXin Li * from the class file; you do not have to explicitly give the name. 766*f1fbf3c2SXin Li * 767*f1fbf3c2SXin Li * @param classfile the class file. 768*f1fbf3c2SXin Li * @see #makeClass(InputStream) 769*f1fbf3c2SXin Li * @see javassist.ByteArrayClassPath 770*f1fbf3c2SXin Li * @since 3.9 771*f1fbf3c2SXin Li */ makeClassIfNew(InputStream classfile)772*f1fbf3c2SXin Li public CtClass makeClassIfNew(InputStream classfile) 773*f1fbf3c2SXin Li throws IOException, RuntimeException 774*f1fbf3c2SXin Li { 775*f1fbf3c2SXin Li compress(); 776*f1fbf3c2SXin Li classfile = new BufferedInputStream(classfile); 777*f1fbf3c2SXin Li CtClass clazz = new CtClassType(classfile, this); 778*f1fbf3c2SXin Li clazz.checkModify(); 779*f1fbf3c2SXin Li String classname = clazz.getName(); 780*f1fbf3c2SXin Li CtClass found = checkNotExists(classname); 781*f1fbf3c2SXin Li if (found != null) 782*f1fbf3c2SXin Li return found; 783*f1fbf3c2SXin Li else { 784*f1fbf3c2SXin Li cacheCtClass(classname, clazz, true); 785*f1fbf3c2SXin Li return clazz; 786*f1fbf3c2SXin Li } 787*f1fbf3c2SXin Li } 788*f1fbf3c2SXin Li 789*f1fbf3c2SXin Li /** 790*f1fbf3c2SXin Li * Creates a new public class. 791*f1fbf3c2SXin Li * If there already exists a class with the same name, the new class 792*f1fbf3c2SXin Li * overwrites that previous class. 793*f1fbf3c2SXin Li * 794*f1fbf3c2SXin Li * <p>If no constructor is explicitly added to the created new 795*f1fbf3c2SXin Li * class, Javassist generates constructors and adds it when 796*f1fbf3c2SXin Li * the class file is generated. It generates a new constructor 797*f1fbf3c2SXin Li * for each constructor of the super class. The new constructor 798*f1fbf3c2SXin Li * takes the same set of parameters and invokes the 799*f1fbf3c2SXin Li * corresponding constructor of the super class. All the received 800*f1fbf3c2SXin Li * parameters are passed to it. 801*f1fbf3c2SXin Li * 802*f1fbf3c2SXin Li * @param classname a fully-qualified class name. 803*f1fbf3c2SXin Li * @throws RuntimeException if the existing class is frozen. 804*f1fbf3c2SXin Li */ makeClass(String classname)805*f1fbf3c2SXin Li public CtClass makeClass(String classname) throws RuntimeException { 806*f1fbf3c2SXin Li return makeClass(classname, null); 807*f1fbf3c2SXin Li } 808*f1fbf3c2SXin Li 809*f1fbf3c2SXin Li /** 810*f1fbf3c2SXin Li * Creates a new public class. 811*f1fbf3c2SXin Li * If there already exists a class/interface with the same name, 812*f1fbf3c2SXin Li * the new class overwrites that previous class. 813*f1fbf3c2SXin Li * 814*f1fbf3c2SXin Li * <p>If no constructor is explicitly added to the created new 815*f1fbf3c2SXin Li * class, Javassist generates constructors and adds it when 816*f1fbf3c2SXin Li * the class file is generated. It generates a new constructor 817*f1fbf3c2SXin Li * for each constructor of the super class. The new constructor 818*f1fbf3c2SXin Li * takes the same set of parameters and invokes the 819*f1fbf3c2SXin Li * corresponding constructor of the super class. All the received 820*f1fbf3c2SXin Li * parameters are passed to it. 821*f1fbf3c2SXin Li * 822*f1fbf3c2SXin Li * @param classname a fully-qualified class name. 823*f1fbf3c2SXin Li * @param superclass the super class. 824*f1fbf3c2SXin Li * @throws RuntimeException if the existing class is frozen. 825*f1fbf3c2SXin Li */ makeClass(String classname, CtClass superclass)826*f1fbf3c2SXin Li public synchronized CtClass makeClass(String classname, CtClass superclass) 827*f1fbf3c2SXin Li throws RuntimeException 828*f1fbf3c2SXin Li { 829*f1fbf3c2SXin Li checkNotFrozen(classname); 830*f1fbf3c2SXin Li CtClass clazz = new CtNewClass(classname, this, false, superclass); 831*f1fbf3c2SXin Li cacheCtClass(classname, clazz, true); 832*f1fbf3c2SXin Li return clazz; 833*f1fbf3c2SXin Li } 834*f1fbf3c2SXin Li 835*f1fbf3c2SXin Li /** 836*f1fbf3c2SXin Li * Creates a new public nested class. 837*f1fbf3c2SXin Li * This method is called by {@link CtClassType#makeNestedClass()}. 838*f1fbf3c2SXin Li * 839*f1fbf3c2SXin Li * @param classname a fully-qualified class name. 840*f1fbf3c2SXin Li * @return the nested class. 841*f1fbf3c2SXin Li */ makeNestedClass(String classname)842*f1fbf3c2SXin Li synchronized CtClass makeNestedClass(String classname) { 843*f1fbf3c2SXin Li checkNotFrozen(classname); 844*f1fbf3c2SXin Li CtClass clazz = new CtNewClass(classname, this, false, null); 845*f1fbf3c2SXin Li cacheCtClass(classname, clazz, true); 846*f1fbf3c2SXin Li return clazz; 847*f1fbf3c2SXin Li } 848*f1fbf3c2SXin Li 849*f1fbf3c2SXin Li /** 850*f1fbf3c2SXin Li * Creates a new public interface. 851*f1fbf3c2SXin Li * If there already exists a class/interface with the same name, 852*f1fbf3c2SXin Li * the new interface overwrites that previous one. 853*f1fbf3c2SXin Li * 854*f1fbf3c2SXin Li * @param name a fully-qualified interface name. 855*f1fbf3c2SXin Li * @throws RuntimeException if the existing interface is frozen. 856*f1fbf3c2SXin Li */ makeInterface(String name)857*f1fbf3c2SXin Li public CtClass makeInterface(String name) throws RuntimeException { 858*f1fbf3c2SXin Li return makeInterface(name, null); 859*f1fbf3c2SXin Li } 860*f1fbf3c2SXin Li 861*f1fbf3c2SXin Li /** 862*f1fbf3c2SXin Li * Creates a new public interface. 863*f1fbf3c2SXin Li * If there already exists a class/interface with the same name, 864*f1fbf3c2SXin Li * the new interface overwrites that previous one. 865*f1fbf3c2SXin Li * 866*f1fbf3c2SXin Li * @param name a fully-qualified interface name. 867*f1fbf3c2SXin Li * @param superclass the super interface. 868*f1fbf3c2SXin Li * @throws RuntimeException if the existing interface is frozen. 869*f1fbf3c2SXin Li */ makeInterface(String name, CtClass superclass)870*f1fbf3c2SXin Li public synchronized CtClass makeInterface(String name, CtClass superclass) 871*f1fbf3c2SXin Li throws RuntimeException 872*f1fbf3c2SXin Li { 873*f1fbf3c2SXin Li checkNotFrozen(name); 874*f1fbf3c2SXin Li CtClass clazz = new CtNewClass(name, this, true, superclass); 875*f1fbf3c2SXin Li cacheCtClass(name, clazz, true); 876*f1fbf3c2SXin Li return clazz; 877*f1fbf3c2SXin Li } 878*f1fbf3c2SXin Li 879*f1fbf3c2SXin Li /** 880*f1fbf3c2SXin Li * Creates a new annotation. 881*f1fbf3c2SXin Li * If there already exists a class/interface with the same name, 882*f1fbf3c2SXin Li * the new interface overwrites that previous one. 883*f1fbf3c2SXin Li * 884*f1fbf3c2SXin Li * @param name a fully-qualified interface name. 885*f1fbf3c2SXin Li * Or null if the annotation has no super interface. 886*f1fbf3c2SXin Li * @throws RuntimeException if the existing interface is frozen. 887*f1fbf3c2SXin Li * @since 3.19 888*f1fbf3c2SXin Li */ makeAnnotation(String name)889*f1fbf3c2SXin Li public CtClass makeAnnotation(String name) throws RuntimeException { 890*f1fbf3c2SXin Li try { 891*f1fbf3c2SXin Li CtClass cc = makeInterface(name, get("java.lang.annotation.Annotation")); 892*f1fbf3c2SXin Li cc.setModifiers(cc.getModifiers() | Modifier.ANNOTATION); 893*f1fbf3c2SXin Li return cc; 894*f1fbf3c2SXin Li } 895*f1fbf3c2SXin Li catch (NotFoundException e) { 896*f1fbf3c2SXin Li // should never happen. 897*f1fbf3c2SXin Li throw new RuntimeException(e.getMessage(), e); 898*f1fbf3c2SXin Li } 899*f1fbf3c2SXin Li } 900*f1fbf3c2SXin Li 901*f1fbf3c2SXin Li /** 902*f1fbf3c2SXin Li * Appends the system search path to the end of the 903*f1fbf3c2SXin Li * search path. The system search path 904*f1fbf3c2SXin Li * usually includes the platform library, extension 905*f1fbf3c2SXin Li * libraries, and the search path specified by the 906*f1fbf3c2SXin Li * <code>-classpath</code> option or the <code>CLASSPATH</code> 907*f1fbf3c2SXin Li * environment variable. 908*f1fbf3c2SXin Li * 909*f1fbf3c2SXin Li * @return the appended class path. 910*f1fbf3c2SXin Li */ appendSystemPath()911*f1fbf3c2SXin Li public ClassPath appendSystemPath() { 912*f1fbf3c2SXin Li return source.appendSystemPath(); 913*f1fbf3c2SXin Li } 914*f1fbf3c2SXin Li 915*f1fbf3c2SXin Li /** 916*f1fbf3c2SXin Li * Insert a <code>ClassPath</code> object at the head of the 917*f1fbf3c2SXin Li * search path. 918*f1fbf3c2SXin Li * 919*f1fbf3c2SXin Li * @return the inserted class path. 920*f1fbf3c2SXin Li * @see javassist.ClassPath 921*f1fbf3c2SXin Li * @see javassist.URLClassPath 922*f1fbf3c2SXin Li * @see javassist.ByteArrayClassPath 923*f1fbf3c2SXin Li */ insertClassPath(ClassPath cp)924*f1fbf3c2SXin Li public ClassPath insertClassPath(ClassPath cp) { 925*f1fbf3c2SXin Li return source.insertClassPath(cp); 926*f1fbf3c2SXin Li } 927*f1fbf3c2SXin Li 928*f1fbf3c2SXin Li /** 929*f1fbf3c2SXin Li * Appends a <code>ClassPath</code> object to the end of the 930*f1fbf3c2SXin Li * search path. 931*f1fbf3c2SXin Li * 932*f1fbf3c2SXin Li * @return the appended class path. 933*f1fbf3c2SXin Li * @see javassist.ClassPath 934*f1fbf3c2SXin Li * @see javassist.URLClassPath 935*f1fbf3c2SXin Li * @see javassist.ByteArrayClassPath 936*f1fbf3c2SXin Li */ appendClassPath(ClassPath cp)937*f1fbf3c2SXin Li public ClassPath appendClassPath(ClassPath cp) { 938*f1fbf3c2SXin Li return source.appendClassPath(cp); 939*f1fbf3c2SXin Li } 940*f1fbf3c2SXin Li 941*f1fbf3c2SXin Li /** 942*f1fbf3c2SXin Li * Inserts a directory or a jar (or zip) file at the head of the 943*f1fbf3c2SXin Li * search path. 944*f1fbf3c2SXin Li * 945*f1fbf3c2SXin Li * @param pathname the path name of the directory or jar file. 946*f1fbf3c2SXin Li * It must not end with a path separator ("/"). 947*f1fbf3c2SXin Li * If the path name ends with "/*", then all the 948*f1fbf3c2SXin Li * jar files matching the path name are inserted. 949*f1fbf3c2SXin Li * 950*f1fbf3c2SXin Li * @return the inserted class path. 951*f1fbf3c2SXin Li * @throws NotFoundException if the jar file is not found. 952*f1fbf3c2SXin Li */ insertClassPath(String pathname)953*f1fbf3c2SXin Li public ClassPath insertClassPath(String pathname) 954*f1fbf3c2SXin Li throws NotFoundException 955*f1fbf3c2SXin Li { 956*f1fbf3c2SXin Li return source.insertClassPath(pathname); 957*f1fbf3c2SXin Li } 958*f1fbf3c2SXin Li 959*f1fbf3c2SXin Li /** 960*f1fbf3c2SXin Li * Appends a directory or a jar (or zip) file to the end of the 961*f1fbf3c2SXin Li * search path. 962*f1fbf3c2SXin Li * 963*f1fbf3c2SXin Li * @param pathname the path name of the directory or jar file. 964*f1fbf3c2SXin Li * It must not end with a path separator ("/"). 965*f1fbf3c2SXin Li * If the path name ends with "/*", then all the 966*f1fbf3c2SXin Li * jar files matching the path name are appended. 967*f1fbf3c2SXin Li * 968*f1fbf3c2SXin Li * @return the appended class path. 969*f1fbf3c2SXin Li * @throws NotFoundException if the jar file is not found. 970*f1fbf3c2SXin Li */ appendClassPath(String pathname)971*f1fbf3c2SXin Li public ClassPath appendClassPath(String pathname) 972*f1fbf3c2SXin Li throws NotFoundException 973*f1fbf3c2SXin Li { 974*f1fbf3c2SXin Li return source.appendClassPath(pathname); 975*f1fbf3c2SXin Li } 976*f1fbf3c2SXin Li 977*f1fbf3c2SXin Li /** 978*f1fbf3c2SXin Li * Detatches the <code>ClassPath</code> object from the search path. 979*f1fbf3c2SXin Li * The detached <code>ClassPath</code> object cannot be added 980*f1fbf3c2SXin Li * to the path again. 981*f1fbf3c2SXin Li */ removeClassPath(ClassPath cp)982*f1fbf3c2SXin Li public void removeClassPath(ClassPath cp) { 983*f1fbf3c2SXin Li source.removeClassPath(cp); 984*f1fbf3c2SXin Li } 985*f1fbf3c2SXin Li 986*f1fbf3c2SXin Li /** 987*f1fbf3c2SXin Li * Appends directories and jar files for search. 988*f1fbf3c2SXin Li * 989*f1fbf3c2SXin Li * <p>The elements of the given path list must be separated by colons 990*f1fbf3c2SXin Li * in Unix or semi-colons in Windows. 991*f1fbf3c2SXin Li * 992*f1fbf3c2SXin Li * @param pathlist a (semi)colon-separated list of 993*f1fbf3c2SXin Li * the path names of directories and jar files. 994*f1fbf3c2SXin Li * The directory name must not end with a path 995*f1fbf3c2SXin Li * separator ("/"). 996*f1fbf3c2SXin Li * @throws NotFoundException if a jar file is not found. 997*f1fbf3c2SXin Li */ appendPathList(String pathlist)998*f1fbf3c2SXin Li public void appendPathList(String pathlist) throws NotFoundException { 999*f1fbf3c2SXin Li char sep = File.pathSeparatorChar; 1000*f1fbf3c2SXin Li int i = 0; 1001*f1fbf3c2SXin Li for (;;) { 1002*f1fbf3c2SXin Li int j = pathlist.indexOf(sep, i); 1003*f1fbf3c2SXin Li if (j < 0) { 1004*f1fbf3c2SXin Li appendClassPath(pathlist.substring(i)); 1005*f1fbf3c2SXin Li break; 1006*f1fbf3c2SXin Li } 1007*f1fbf3c2SXin Li else { 1008*f1fbf3c2SXin Li appendClassPath(pathlist.substring(i, j)); 1009*f1fbf3c2SXin Li i = j + 1; 1010*f1fbf3c2SXin Li } 1011*f1fbf3c2SXin Li } 1012*f1fbf3c2SXin Li } 1013*f1fbf3c2SXin Li 1014*f1fbf3c2SXin Li /** 1015*f1fbf3c2SXin Li * Converts the given class to a <code>java.lang.Class</code> object. 1016*f1fbf3c2SXin Li * Once this method is called, further modifications are not 1017*f1fbf3c2SXin Li * allowed any more. 1018*f1fbf3c2SXin Li * To load the class, this method uses the context class loader 1019*f1fbf3c2SXin Li * of the current thread. It is obtained by calling 1020*f1fbf3c2SXin Li * <code>getClassLoader()</code>. 1021*f1fbf3c2SXin Li * 1022*f1fbf3c2SXin Li * <p>This behavior can be changed by subclassing the pool and changing 1023*f1fbf3c2SXin Li * the <code>getClassLoader()</code> method. 1024*f1fbf3c2SXin Li * If the program is running on some application 1025*f1fbf3c2SXin Li * server, the context class loader might be inappropriate to load the 1026*f1fbf3c2SXin Li * class.</p> 1027*f1fbf3c2SXin Li * 1028*f1fbf3c2SXin Li * <p>This method is provided for convenience. If you need more 1029*f1fbf3c2SXin Li * complex functionality, you should write your own class loader. 1030*f1fbf3c2SXin Li * 1031*f1fbf3c2SXin Li * <p><b>Warining:</b> 1032*f1fbf3c2SXin Li * This method should not be used in Java 11 or later. 1033*f1fbf3c2SXin Li * Use {@link #toClass(CtClass,Class)}. 1034*f1fbf3c2SXin Li * </p> 1035*f1fbf3c2SXin Li * 1036*f1fbf3c2SXin Li * <p><b>Warining:</b> 1037*f1fbf3c2SXin Li * A Class object returned by this method may not 1038*f1fbf3c2SXin Li * work with a security manager or a signed jar file because a 1039*f1fbf3c2SXin Li * protection domain is not specified.</p> 1040*f1fbf3c2SXin Li * 1041*f1fbf3c2SXin Li * @see #toClass(CtClass,Class) 1042*f1fbf3c2SXin Li * @see #toClass(CtClass,Class,java.lang.ClassLoader,ProtectionDomain) 1043*f1fbf3c2SXin Li * @see #getClassLoader() 1044*f1fbf3c2SXin Li */ toClass(CtClass clazz)1045*f1fbf3c2SXin Li public Class toClass(CtClass clazz) throws CannotCompileException { 1046*f1fbf3c2SXin Li // Some subclasses of ClassPool may override toClass(CtClass,ClassLoader). 1047*f1fbf3c2SXin Li // So we should call that method instead of toClass(.., ProtectionDomain). 1048*f1fbf3c2SXin Li return toClass(clazz, getClassLoader()); 1049*f1fbf3c2SXin Li } 1050*f1fbf3c2SXin Li 1051*f1fbf3c2SXin Li /** 1052*f1fbf3c2SXin Li * Get the classloader for <code>toClass()</code>, <code>getAnnotations()</code> in 1053*f1fbf3c2SXin Li * <code>CtClass</code>, etc. 1054*f1fbf3c2SXin Li * 1055*f1fbf3c2SXin Li * <p>The default is the context class loader. 1056*f1fbf3c2SXin Li * 1057*f1fbf3c2SXin Li * @return the classloader for the pool 1058*f1fbf3c2SXin Li * @see #toClass(CtClass) 1059*f1fbf3c2SXin Li * @see CtClass#getAnnotations() 1060*f1fbf3c2SXin Li */ getClassLoader()1061*f1fbf3c2SXin Li public ClassLoader getClassLoader() { 1062*f1fbf3c2SXin Li return getContextClassLoader(); 1063*f1fbf3c2SXin Li } 1064*f1fbf3c2SXin Li 1065*f1fbf3c2SXin Li /** 1066*f1fbf3c2SXin Li * Obtains a class loader that seems appropriate to look up a class 1067*f1fbf3c2SXin Li * by name. 1068*f1fbf3c2SXin Li */ getContextClassLoader()1069*f1fbf3c2SXin Li static ClassLoader getContextClassLoader() { 1070*f1fbf3c2SXin Li return Thread.currentThread().getContextClassLoader(); 1071*f1fbf3c2SXin Li } 1072*f1fbf3c2SXin Li 1073*f1fbf3c2SXin Li /** 1074*f1fbf3c2SXin Li * Converts the class to a <code>java.lang.Class</code> object. 1075*f1fbf3c2SXin Li * Do not override this method any more at a subclass because 1076*f1fbf3c2SXin Li * {@link #toClass(CtClass)} will never calls this method. 1077*f1fbf3c2SXin Li * 1078*f1fbf3c2SXin Li * <p><b>Warining:</b> A Class object returned by this method may not 1079*f1fbf3c2SXin Li * work with a security manager or a signed jar file because a 1080*f1fbf3c2SXin Li * protection domain is not specified. 1081*f1fbf3c2SXin Li * 1082*f1fbf3c2SXin Li * @deprecated Replaced by {@link #toClass(CtClass,Class,ClassLoader,ProtectionDomain)}. 1083*f1fbf3c2SXin Li * A subclass of <code>ClassPool</code> that has been 1084*f1fbf3c2SXin Li * overriding this method should be modified. It should override 1085*f1fbf3c2SXin Li * {@link #toClass(CtClass,Class,ClassLoader,ProtectionDomain)}. 1086*f1fbf3c2SXin Li */ toClass(CtClass ct, ClassLoader loader)1087*f1fbf3c2SXin Li public Class toClass(CtClass ct, ClassLoader loader) 1088*f1fbf3c2SXin Li throws CannotCompileException 1089*f1fbf3c2SXin Li { 1090*f1fbf3c2SXin Li return toClass(ct, null, loader, null); 1091*f1fbf3c2SXin Li } 1092*f1fbf3c2SXin Li 1093*f1fbf3c2SXin Li /** 1094*f1fbf3c2SXin Li * Converts the class to a <code>java.lang.Class</code> object. 1095*f1fbf3c2SXin Li * Once this method is called, further modifications are not allowed 1096*f1fbf3c2SXin Li * any more. 1097*f1fbf3c2SXin Li * 1098*f1fbf3c2SXin Li * <p>The class file represented by the given <code>CtClass</code> is 1099*f1fbf3c2SXin Li * loaded by the given class loader to construct a 1100*f1fbf3c2SXin Li * <code>java.lang.Class</code> object. Since a private method 1101*f1fbf3c2SXin Li * on the class loader is invoked through the reflection API, 1102*f1fbf3c2SXin Li * the caller must have permissions to do that.</p> 1103*f1fbf3c2SXin Li * 1104*f1fbf3c2SXin Li * <p>An easy way to obtain <code>ProtectionDomain</code> object is 1105*f1fbf3c2SXin Li * to call <code>getProtectionDomain()</code> 1106*f1fbf3c2SXin Li * in <code>java.lang.Class</code>. It returns the domain that the 1107*f1fbf3c2SXin Li * class belongs to. 1108*f1fbf3c2SXin Li * 1109*f1fbf3c2SXin Li * <p>This method is provided for convenience. If you need more 1110*f1fbf3c2SXin Li * complex functionality, you should write your own class loader.</p> 1111*f1fbf3c2SXin Li * 1112*f1fbf3c2SXin Li * @param ct the class converted into {@code java.lang.Class}. 1113*f1fbf3c2SXin Li * @param loader the class loader used to load this class. 1114*f1fbf3c2SXin Li * For example, the loader returned by 1115*f1fbf3c2SXin Li * <code>getClassLoader()</code> can be used 1116*f1fbf3c2SXin Li * for this parameter. 1117*f1fbf3c2SXin Li * @param domain the protection domain for the class. 1118*f1fbf3c2SXin Li * If it is null, the default domain created 1119*f1fbf3c2SXin Li * by <code>java.lang.ClassLoader</code> is used. 1120*f1fbf3c2SXin Li * 1121*f1fbf3c2SXin Li * @see #getClassLoader() 1122*f1fbf3c2SXin Li * @since 3.3 1123*f1fbf3c2SXin Li * @deprecated Replaced by {@link #toClass(CtClass,Class,ClassLoader,ProtectionDomain)}. 1124*f1fbf3c2SXin Li */ toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain)1125*f1fbf3c2SXin Li public Class toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain) 1126*f1fbf3c2SXin Li throws CannotCompileException 1127*f1fbf3c2SXin Li { 1128*f1fbf3c2SXin Li return toClass(ct, null, loader, domain); 1129*f1fbf3c2SXin Li } 1130*f1fbf3c2SXin Li 1131*f1fbf3c2SXin Li /** 1132*f1fbf3c2SXin Li * Converts the class to a <code>java.lang.Class</code> object. 1133*f1fbf3c2SXin Li * Once this method is called, further modifications are not allowed 1134*f1fbf3c2SXin Li * any more. 1135*f1fbf3c2SXin Li * 1136*f1fbf3c2SXin Li * <p>This method is available in Java 9 or later. 1137*f1fbf3c2SXin Li * It loads the class 1138*f1fbf3c2SXin Li * by using {@code java.lang.invoke.MethodHandles} with {@code neighbor}. 1139*f1fbf3c2SXin Li * </p> 1140*f1fbf3c2SXin Li * 1141*f1fbf3c2SXin Li * @param ct the class converted into {@code java.lang.Class}. 1142*f1fbf3c2SXin Li * @param neighbor a class belonging to the same package that 1143*f1fbf3c2SXin Li * the converted class belongs to. 1144*f1fbf3c2SXin Li * @since 3.24 1145*f1fbf3c2SXin Li */ toClass(CtClass ct, Class<?> neighbor)1146*f1fbf3c2SXin Li public Class<?> toClass(CtClass ct, Class<?> neighbor) 1147*f1fbf3c2SXin Li throws CannotCompileException 1148*f1fbf3c2SXin Li { 1149*f1fbf3c2SXin Li try { 1150*f1fbf3c2SXin Li return javassist.util.proxy.DefineClassHelper.toClass(neighbor, 1151*f1fbf3c2SXin Li ct.toBytecode()); 1152*f1fbf3c2SXin Li } 1153*f1fbf3c2SXin Li catch (IOException e) { 1154*f1fbf3c2SXin Li throw new CannotCompileException(e); 1155*f1fbf3c2SXin Li } 1156*f1fbf3c2SXin Li } 1157*f1fbf3c2SXin Li 1158*f1fbf3c2SXin Li /** 1159*f1fbf3c2SXin Li * Converts the class to a <code>java.lang.Class</code> object. 1160*f1fbf3c2SXin Li * Once this method is called, further modifications are not allowed 1161*f1fbf3c2SXin Li * any more. 1162*f1fbf3c2SXin Li * 1163*f1fbf3c2SXin Li * <p>This method is available in Java 9 or later. 1164*f1fbf3c2SXin Li * It loads the class 1165*f1fbf3c2SXin Li * by using the given {@code java.lang.invoke.MethodHandles.Lookup}. 1166*f1fbf3c2SXin Li * </p> 1167*f1fbf3c2SXin Li * 1168*f1fbf3c2SXin Li * @param ct the class converted into {@code java.lang.Class}. 1169*f1fbf3c2SXin Li * @since 3.24 1170*f1fbf3c2SXin Li */ toClass(CtClass ct, java.lang.invoke.MethodHandles.Lookup lookup)1171*f1fbf3c2SXin Li public Class<?> toClass(CtClass ct, 1172*f1fbf3c2SXin Li java.lang.invoke.MethodHandles.Lookup lookup) 1173*f1fbf3c2SXin Li throws CannotCompileException 1174*f1fbf3c2SXin Li { 1175*f1fbf3c2SXin Li try { 1176*f1fbf3c2SXin Li return javassist.util.proxy.DefineClassHelper.toClass(lookup, 1177*f1fbf3c2SXin Li ct.toBytecode()); 1178*f1fbf3c2SXin Li } 1179*f1fbf3c2SXin Li catch (IOException e) { 1180*f1fbf3c2SXin Li throw new CannotCompileException(e); 1181*f1fbf3c2SXin Li } 1182*f1fbf3c2SXin Li } 1183*f1fbf3c2SXin Li 1184*f1fbf3c2SXin Li /** 1185*f1fbf3c2SXin Li * Converts the class to a <code>java.lang.Class</code> object. 1186*f1fbf3c2SXin Li * Once this method is called, further modifications are not allowed 1187*f1fbf3c2SXin Li * any more. 1188*f1fbf3c2SXin Li * 1189*f1fbf3c2SXin Li * <p>When the JVM is Java 11 or later, this method loads the class 1190*f1fbf3c2SXin Li * by using {@code java.lang.invoke.MethodHandles} with {@code neighbor}. 1191*f1fbf3c2SXin Li * The other arguments {@code loader} and {@code domain} are not used; 1192*f1fbf3c2SXin Li * so they can be null. 1193*f1fbf3c2SXin Li * </p> 1194*f1fbf3c2SXin Li * 1195*f1fbf3c2SXin Li * <p>Otherwise, or when {@code neighbor} is null, 1196*f1fbf3c2SXin Li * the class file represented by the given <code>CtClass</code> is 1197*f1fbf3c2SXin Li * loaded by the given class loader to construct a 1198*f1fbf3c2SXin Li * <code>java.lang.Class</code> object. Since a private method 1199*f1fbf3c2SXin Li * on the class loader is invoked through the reflection API, 1200*f1fbf3c2SXin Li * the caller must have permissions to do that. 1201*f1fbf3c2SXin Li * 1202*f1fbf3c2SXin Li * <p>An easy way to obtain <code>ProtectionDomain</code> object is 1203*f1fbf3c2SXin Li * to call <code>getProtectionDomain()</code> 1204*f1fbf3c2SXin Li * in <code>java.lang.Class</code>. It returns the domain that the 1205*f1fbf3c2SXin Li * class belongs to. 1206*f1fbf3c2SXin Li * 1207*f1fbf3c2SXin Li * <p>If your program is for only Java 9 or later, don't use this method. 1208*f1fbf3c2SXin Li * Use {@link #toClass(CtClass,Class)} or 1209*f1fbf3c2SXin Li * {@link #toClass(CtClass,java.lang.invoke.MethodHandles.Lookup)}. 1210*f1fbf3c2SXin Li * </p> 1211*f1fbf3c2SXin Li * 1212*f1fbf3c2SXin Li * @param ct the class converted into {@code java.lang.Class}. 1213*f1fbf3c2SXin Li * @param neighbor a class belonging to the same package that 1214*f1fbf3c2SXin Li * the converted class belongs to. 1215*f1fbf3c2SXin Li * It can be null. 1216*f1fbf3c2SXin Li * @param loader the class loader used to load this class. 1217*f1fbf3c2SXin Li * For example, the loader returned by 1218*f1fbf3c2SXin Li * <code>getClassLoader()</code> can be used 1219*f1fbf3c2SXin Li * for this parameter. 1220*f1fbf3c2SXin Li * @param domain the protection domain for the class. 1221*f1fbf3c2SXin Li * If it is null, the default domain created 1222*f1fbf3c2SXin Li * by <code>java.lang.ClassLoader</code> is used. 1223*f1fbf3c2SXin Li * 1224*f1fbf3c2SXin Li * @see #getClassLoader() 1225*f1fbf3c2SXin Li * @since 3.24 1226*f1fbf3c2SXin Li */ toClass(CtClass ct, Class<?> neighbor, ClassLoader loader, ProtectionDomain domain)1227*f1fbf3c2SXin Li public Class toClass(CtClass ct, Class<?> neighbor, ClassLoader loader, 1228*f1fbf3c2SXin Li ProtectionDomain domain) 1229*f1fbf3c2SXin Li throws CannotCompileException 1230*f1fbf3c2SXin Li { 1231*f1fbf3c2SXin Li try { 1232*f1fbf3c2SXin Li return javassist.util.proxy.DefineClassHelper.toClass(ct.getName(), 1233*f1fbf3c2SXin Li neighbor, loader, domain, ct.toBytecode()); 1234*f1fbf3c2SXin Li } 1235*f1fbf3c2SXin Li catch (IOException e) { 1236*f1fbf3c2SXin Li throw new CannotCompileException(e); 1237*f1fbf3c2SXin Li } 1238*f1fbf3c2SXin Li } 1239*f1fbf3c2SXin Li 1240*f1fbf3c2SXin Li /** 1241*f1fbf3c2SXin Li * Defines a new package. If the package is already defined, this method 1242*f1fbf3c2SXin Li * performs nothing. 1243*f1fbf3c2SXin Li * 1244*f1fbf3c2SXin Li * <p>You do not necessarily need to 1245*f1fbf3c2SXin Li * call this method. If this method is called, then 1246*f1fbf3c2SXin Li * <code>getPackage()</code> on the <code>Class</code> object returned 1247*f1fbf3c2SXin Li * by <code>toClass()</code> will return a non-null object.</p> 1248*f1fbf3c2SXin Li * 1249*f1fbf3c2SXin Li * <p>The jigsaw module introduced by Java 9 has broken this method. 1250*f1fbf3c2SXin Li * In Java 9 or later, the VM argument 1251*f1fbf3c2SXin Li * <code>--add-opens java.base/java.lang=ALL-UNNAMED</code> 1252*f1fbf3c2SXin Li * has to be given to the JVM so that this method can run. 1253*f1fbf3c2SXin Li * </p> 1254*f1fbf3c2SXin Li * 1255*f1fbf3c2SXin Li * @param loader the class loader passed to <code>toClass()</code> or 1256*f1fbf3c2SXin Li * the default one obtained by <code>getClassLoader()</code>. 1257*f1fbf3c2SXin Li * @param name the package name. 1258*f1fbf3c2SXin Li * @see #getClassLoader() 1259*f1fbf3c2SXin Li * @see #toClass(CtClass) 1260*f1fbf3c2SXin Li * @see CtClass#toClass() 1261*f1fbf3c2SXin Li * @since 3.16 1262*f1fbf3c2SXin Li * @deprecated 1263*f1fbf3c2SXin Li */ makePackage(ClassLoader loader, String name)1264*f1fbf3c2SXin Li public void makePackage(ClassLoader loader, String name) 1265*f1fbf3c2SXin Li throws CannotCompileException 1266*f1fbf3c2SXin Li { 1267*f1fbf3c2SXin Li DefinePackageHelper.definePackage(name, loader); 1268*f1fbf3c2SXin Li } 1269*f1fbf3c2SXin Li 1270*f1fbf3c2SXin Li } 1271