xref: /aosp_15_r20/external/javassist/src/main/javassist/ClassPool.java (revision f1fbf3c2ab775ce834e0af96b7a85bdc7a0eac65)
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