/*
 * Javassist, a Java-bytecode translator toolkit.
 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License.  Alternatively, the contents of this file may be used under
 * the terms of the GNU Lesser General Public License Version 2.1 or later,
 * or the Apache License Version 2.0.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 */

package javassist;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;

import javassist.bytecode.ClassFile;
import javassist.bytecode.Descriptor;
import javassist.util.proxy.DefinePackageHelper;

A container of CtClass objects. A CtClass object must be obtained from this object. If get() is called on this object, it searches various sources represented by ClassPath to find a class file and then it creates a CtClass object representing that class file. The created object is returned to the caller.

Memory consumption memo:

ClassPool objects hold all the CtClasses that have been created so that the consistency among modified classes can be guaranteed. Thus if a large number of CtClasses are processed, the ClassPool will consume a huge amount of memory. To avoid this, a ClassPool object should be recreated, for example, every hundred classes processed. Note that getDefault() is a singleton factory. Otherwise, detach() in CtClass should be used to avoid huge memory consumption.

ClassPool hierarchy:

ClassPools can make a parent-child hierarchy as java.lang.ClassLoaders. If a ClassPool has a parent pool, get() first asks the parent pool to find a class file. Only if the parent could not find the class file, get() searches the ClassPaths of the child ClassPool. This search order is reversed if ClassPath.childFirstLookup is true.

See Also:
/** * A container of <code>CtClass</code> objects. * A <code>CtClass</code> object must be obtained from this object. * If <code>get()</code> is called on this object, * it searches various sources represented by <code>ClassPath</code> * to find a class file and then it creates a <code>CtClass</code> object * representing that class file. The created object is returned to the * caller. * * <p><b>Memory consumption memo:</b> * * <p><code>ClassPool</code> objects hold all the <code>CtClass</code>es * that have been created so that the consistency among modified classes * can be guaranteed. Thus if a large number of <code>CtClass</code>es * are processed, the <code>ClassPool</code> will consume a huge amount * of memory. To avoid this, a <code>ClassPool</code> object * should be recreated, for example, every hundred classes processed. * Note that <code>getDefault()</code> is a singleton factory. * Otherwise, <code>detach()</code> in <code>CtClass</code> should be used * to avoid huge memory consumption. * * <p><b><code>ClassPool</code> hierarchy:</b> * * <p><code>ClassPool</code>s can make a parent-child hierarchy as * <code>java.lang.ClassLoader</code>s. If a <code>ClassPool</code> has * a parent pool, <code>get()</code> first asks the parent pool to find * a class file. Only if the parent could not find the class file, * <code>get()</code> searches the <code>ClassPath</code>s of * the child <code>ClassPool</code>. This search order is reversed if * <code>ClassPath.childFirstLookup</code> is <code>true</code>. * * @see javassist.CtClass * @see javassist.ClassPath */
@SuppressWarnings({"unchecked", "rawtypes"}) public class ClassPool {
Determines the search order.

If this field is true, get() first searches the class path associated to this ClassPool and then the class path associated with the parent ClassPool. Otherwise, the class path associated with the parent is searched first.

The default value is false.

/** * Determines the search order. * * <p>If this field is true, <code>get()</code> first searches the * class path associated to this <code>ClassPool</code> and then * the class path associated with the parent <code>ClassPool</code>. * Otherwise, the class path associated with the parent is searched * first. * * <p>The default value is false. */
public boolean childFirstLookup = false;
Turning the automatic pruning on/off.

If this field is true, CtClass objects are automatically pruned by default when toBytecode() etc. are called. The automatic pruning can be turned on/off individually for each CtClass object.

The initial value is false.

See Also:
/** * Turning the automatic pruning on/off. * * <p>If this field is true, <code>CtClass</code> objects are * automatically pruned by default when <code>toBytecode()</code> etc. * are called. The automatic pruning can be turned on/off individually * for each <code>CtClass</code> object. * * <p>The initial value is false. * * @see CtClass#prune() * @see CtClass#stopPruning(boolean) * @see CtClass#detach() */
public static boolean doPruning = false; private int compressCount; private static final int COMPRESS_THRESHOLD = 100; /* releaseUnmodifiedClassFile was introduced for avoiding a bug of JBoss AOP. So the value should be true except for JBoss AOP. */
If true, unmodified and not-recently-used class files are periodically released for saving memory.

The initial value is true.

/** * If true, unmodified and not-recently-used class files are * periodically released for saving memory. * * <p>The initial value is true. */
public static boolean releaseUnmodifiedClassFile = true;
If true, the contents of a jar file are cached after the jar file is opened.

The initial value is true.

/** * If true, the contents of a jar file are cached after the jar * file is opened. * * <p>The initial value is true. */
public static boolean cacheOpenedJarFile = true; // see ClassPoolTail.JarClassPath#openClassfile(String) protected ClassPoolTail source; protected ClassPool parent; protected Hashtable classes; // should be synchronous
Table of registered cflow variables.
/** * Table of registered cflow variables. */
private Hashtable cflow = null; // should be synchronous. private static final int INIT_HASH_SIZE = 191; private ArrayList importedPackages;
Creates a root class pool. No parent class pool is specified.
/** * Creates a root class pool. No parent class pool is specified. */
public ClassPool() { this(null); }
Creates a root class pool. If useDefaultPath is true, appendSystemPath() is called. Otherwise, this constructor is equivalent to the constructor taking no parameter.
Params:
  • useDefaultPath – true if the system search path is appended.
/** * Creates a root class pool. If <code>useDefaultPath</code> is * true, <code>appendSystemPath()</code> is called. Otherwise, * this constructor is equivalent to the constructor taking no * parameter. * * @param useDefaultPath true if the system search path is * appended. */
public ClassPool(boolean useDefaultPath) { this(null); if (useDefaultPath) appendSystemPath(); }
Creates a class pool.
Params:
  • parent – the parent of this class pool. If this is a root class pool, this parameter must be null.
See Also:
/** * Creates a class pool. * * @param parent the parent of this class pool. If this is a root * class pool, this parameter must be <code>null</code>. * @see javassist.ClassPool#getDefault() */
public ClassPool(ClassPool parent) { this.classes = new Hashtable(INIT_HASH_SIZE); this.source = new ClassPoolTail(); this.parent = parent; if (parent == null) { CtClass[] pt = CtClass.primitiveTypes; for (int i = 0; i < pt.length; ++i) classes.put(pt[i].getName(), pt[i]); } this.cflow = null; this.compressCount = 0; clearImportedPackages(); }
Returns the default class pool. The returned object is always identical since this method is a singleton factory.

The default class pool searches the system search path, which usually includes the platform library, extension libraries, and the search path specified by the -classpath option or the CLASSPATH environment variable.

When this method is called for the first time, the default class pool is created with the following code snippet:

ClassPool cp = new ClassPool();
cp.appendSystemPath();

If the default class pool cannot find any class files, try ClassClassPath, ModuleClassPath, or LoaderClassPath.

See Also:
/** * Returns the default class pool. * The returned object is always identical since this method is * a singleton factory. * * <p>The default class pool searches the system search path, * which usually includes the platform library, extension * libraries, and the search path specified by the * <code>-classpath</code> option or the <code>CLASSPATH</code> * environment variable. * * <p>When this method is called for the first time, the default * class pool is created with the following code snippet: * * <pre>ClassPool cp = new ClassPool(); * cp.appendSystemPath(); * </pre> * * <p>If the default class pool cannot find any class files, * try <code>ClassClassPath</code>, <code>ModuleClassPath</code>, * or <code>LoaderClassPath</code>. * * @see ClassClassPath * @see LoaderClassPath */
public static synchronized ClassPool getDefault() { if (defaultPool == null) { defaultPool = new ClassPool(null); defaultPool.appendSystemPath(); } return defaultPool; } private static ClassPool defaultPool = null;
Provide a hook so that subclasses can do their own caching of classes.
See Also:
/** * Provide a hook so that subclasses can do their own * caching of classes. * * @see #cacheCtClass(String,CtClass,boolean) * @see #removeCached(String) */
protected CtClass getCached(String classname) { return (CtClass)classes.get(classname); }
Provides a hook so that subclasses can do their own caching of classes.
See Also:
/** * Provides a hook so that subclasses can do their own * caching of classes. * * @see #getCached(String) * @see #removeCached(String) */
protected void cacheCtClass(String classname, CtClass c, boolean dynamic) { classes.put(classname, c); }
Provide a hook so that subclasses can do their own caching of classes.
See Also:
/** * Provide a hook so that subclasses can do their own * caching of classes. * * @see #getCached(String) * @see #cacheCtClass(String,CtClass,boolean) */
protected CtClass removeCached(String classname) { return (CtClass)classes.remove(classname); }
Returns the class search path.
/** * Returns the class search path. */
public String toString() { return source.toString(); }
This method is periodically invoked so that memory footprint will be minimized.
/** * This method is periodically invoked so that memory * footprint will be minimized. */
void compress() { if (compressCount++ > COMPRESS_THRESHOLD) { compressCount = 0; Enumeration e = classes.elements(); while (e.hasMoreElements()) ((CtClass)e.nextElement()).compress(); } }
Record a package name so that the Javassist compiler searches the package to resolve a class name. Don't record the java.lang package, which has been implicitly recorded by default.

Since version 3.14, packageName can be a fully-qualified class name.

Note that get() in ClassPool does not search the recorded package. Only the compiler searches it.

Params:
  • packageName – the package name. It must not include the last '.' (dot). For example, "java.util" is valid but "java.util." is wrong.
Since:3.1
/** * Record a package name so that the Javassist compiler searches * the package to resolve a class name. * Don't record the <code>java.lang</code> package, which has * been implicitly recorded by default. * * <p>Since version 3.14, <code>packageName</code> can be a * fully-qualified class name. * * <p>Note that <code>get()</code> in <code>ClassPool</code> does * not search the recorded package. Only the compiler searches it. * * @param packageName the package name. * It must not include the last '.' (dot). * For example, "java.util" is valid but "java.util." is wrong. * @since 3.1 */
public void importPackage(String packageName) { importedPackages.add(packageName); }
Clear all the package names recorded by importPackage(). The java.lang package is not removed.
See Also:
  • importPackage(String)
Since:3.1
/** * Clear all the package names recorded by <code>importPackage()</code>. * The <code>java.lang</code> package is not removed. * * @see #importPackage(String) * @since 3.1 */
public void clearImportedPackages() { importedPackages = new ArrayList(); importedPackages.add("java.lang"); }
Returns all the package names recorded by importPackage().
See Also:
  • importPackage(String)
Since:3.1
/** * Returns all the package names recorded by <code>importPackage()</code>. * * @see #importPackage(String) * @since 3.1 */
public Iterator<String> getImportedPackages() { return importedPackages.iterator(); }
Records a class name that never exists. For example, a package name can be recorded by this method. This would improve execution performance since get() quickly throw an exception without searching the class path at all if the given name is an invalid name recorded by this method. Note that searching the class path takes relatively long time.

The current implementation of this method performs nothing.

Params:
  • name – an invalid class name (separeted by dots).
Deprecated:
/** * Records a class name that never exists. * For example, a package name can be recorded by this method. * This would improve execution performance * since <code>get()</code> quickly throw an exception * without searching the class path at all * if the given name is an invalid name recorded by this method. * Note that searching the class path takes relatively long time. * * <p>The current implementation of this method performs nothing. * * @param name an invalid class name (separeted by dots). * @deprecated */
public void recordInvalidClassName(String name) { // source.recordInvalidClassName(name); }
Records the $cflow variable for the field specified by cname and fname.
Params:
  • name – variable name
  • cname – class name
  • fname – field name
/** * Records the <code>$cflow</code> variable for the field specified * by <code>cname</code> and <code>fname</code>. * * @param name variable name * @param cname class name * @param fname field name */
void recordCflow(String name, String cname, String fname) { if (cflow == null) cflow = new Hashtable(); cflow.put(name, new Object[] { cname, fname }); }
Undocumented method. Do not use; internal-use only.
Params:
  • name – the name of $cflow variable
/** * Undocumented method. Do not use; internal-use only. * * @param name the name of <code>$cflow</code> variable */
public Object[] lookupCflow(String name) { if (cflow == null) cflow = new Hashtable(); return (Object[])cflow.get(name); }
Reads a class file and constructs a CtClass object with a new name. This method is useful if you want to generate a new class as a copy of another class (except the class name). For example,
getAndRename("Point", "Pair")
returns a CtClass object representing Pair class. The definition of Pair is the same as that of Point class except the class name since Pair is defined by reading Point.class.
Params:
  • orgName – the original (fully-qualified) class name
  • newName – the new class name
/** * Reads a class file and constructs a <code>CtClass</code> * object with a new name. * This method is useful if you want to generate a new class as a copy * of another class (except the class name). For example, * * <pre> * getAndRename("Point", "Pair") * </pre> * * returns a <code>CtClass</code> object representing <code>Pair</code> * class. The definition of <code>Pair</code> is the same as that of * <code>Point</code> class except the class name since <code>Pair</code> * is defined by reading <code>Point.class</code>. * * @param orgName the original (fully-qualified) class name * @param newName the new class name */
public CtClass getAndRename(String orgName, String newName) throws NotFoundException { CtClass clazz = get0(orgName, false); if (clazz == null) throw new NotFoundException(orgName); if (clazz instanceof CtClassType) ((CtClassType)clazz).setClassPool(this); clazz.setName(newName); // indirectly calls // classNameChanged() in this class return clazz; } /* * This method is invoked by CtClassType.setName(). It removes a * CtClass object from the hash table and inserts it with the new * name. Don't delegate to the parent. */ synchronized void classNameChanged(String oldname, CtClass clazz) { CtClass c = (CtClass)getCached(oldname); if (c == clazz) // must check this equation. removeCached(oldname); // see getAndRename(). String newName = clazz.getName(); checkNotFrozen(newName); cacheCtClass(newName, clazz, false); }
Reads a class file from the source and returns a reference to the CtClass object representing that class file. If that class file has been already read, this method returns a reference to the CtClass created when that class file was read at the first time.

If classname ends with "[]", then this method returns a CtClass object for that array type.

To obtain an inner class, use "$" instead of "." for separating the enclosing class name and the inner class name.

Params:
  • classname – a fully-qualified class name.
/** * Reads a class file from the source and returns a reference * to the <code>CtClass</code> * object representing that class file. If that class file has been * already read, this method returns a reference to the * <code>CtClass</code> created when that class file was read at the * first time. * * <p>If <code>classname</code> ends with "[]", then this method * returns a <code>CtClass</code> object for that array type. * * <p>To obtain an inner class, use "$" instead of "." for separating * the enclosing class name and the inner class name. * * @param classname a fully-qualified class name. */
public CtClass get(String classname) throws NotFoundException { CtClass clazz; if (classname == null) clazz = null; else clazz = get0(classname, true); if (clazz == null) throw new NotFoundException(classname); else { clazz.incGetCounter(); return clazz; } }
Reads a class file from the source and returns a reference to the CtClass object representing that class file. This method is equivalent to get except that it returns null when a class file is not found and it never throws an exception.
Params:
  • classname – a fully-qualified class name.
See Also:
Returns:a CtClass object or null.
Since:3.13
/** * Reads a class file from the source and returns a reference * to the <code>CtClass</code> * object representing that class file. * This method is equivalent to <code>get</code> except * that it returns <code>null</code> when a class file is * not found and it never throws an exception. * * @param classname a fully-qualified class name. * @return a <code>CtClass</code> object or <code>null</code>. * @see #get(String) * @see #find(String) * @since 3.13 */
public CtClass getOrNull(String classname) { CtClass clazz = null; if (classname == null) clazz = null; else try { /* ClassPool.get0() never throws an exception but its subclass may implement get0 that may throw an exception. */ clazz = get0(classname, true); } catch (NotFoundException e){} if (clazz != null) clazz.incGetCounter(); return clazz; }
Returns a CtClass object with the given name. This is almost equivalent to get(String) except that classname can be an array-type "descriptor" (an encoded type name) such as [Ljava/lang/Object;.

Using this method is not recommended; this method should be used only to obtain the CtClass object with a name returned from getClassInfo in javassist.bytecode.ClassPool. getClassInfo returns a fully-qualified class name but, if the class is an array type, it returns a descriptor.

Params:
  • classname – a fully-qualified class name or a descriptor representing an array type.
See Also:
Since:3.8.1
/** * Returns a <code>CtClass</code> object with the given name. * This is almost equivalent to <code>get(String)</code> except * that classname can be an array-type "descriptor" (an encoded * type name) such as <code>[Ljava/lang/Object;</code>. * * <p>Using this method is not recommended; this method should be * used only to obtain the <code>CtClass</code> object * with a name returned from <code>getClassInfo</code> in * <code>javassist.bytecode.ClassPool</code>. <code>getClassInfo</code> * returns a fully-qualified class name but, if the class is an array * type, it returns a descriptor. * * @param classname a fully-qualified class name or a descriptor * representing an array type. * @see #get(String) * @see javassist.bytecode.ConstPool#getClassInfo(int) * @see javassist.bytecode.Descriptor#toCtClass(String, ClassPool) * @since 3.8.1 */
public CtClass getCtClass(String classname) throws NotFoundException { if (classname.charAt(0) == '[') return Descriptor.toCtClass(classname, this); else return get(classname); }
Params:
  • useCache – false if the cached CtClass must be ignored.
Returns:null if the class could not be found.
/** * @param useCache false if the cached CtClass must be ignored. * @return null if the class could not be found. */
protected synchronized CtClass get0(String classname, boolean useCache) throws NotFoundException { CtClass clazz = null; if (useCache) { clazz = getCached(classname); if (clazz != null) return clazz; } if (!childFirstLookup && parent != null) { clazz = parent.get0(classname, useCache); if (clazz != null) return clazz; } clazz = createCtClass(classname, useCache); if (clazz != null) { // clazz.getName() != classname if classname is "[L<name>;". if (useCache) cacheCtClass(clazz.getName(), clazz, false); return clazz; } if (childFirstLookup && parent != null) clazz = parent.get0(classname, useCache); return clazz; }
Creates a CtClass object representing the specified class. It first examines whether or not the corresponding class file exists. If yes, it creates a CtClass object.
Returns:null if the class file could not be found.
/** * Creates a CtClass object representing the specified class. * It first examines whether or not the corresponding class * file exists. If yes, it creates a CtClass object. * * @return null if the class file could not be found. */
protected CtClass createCtClass(String classname, boolean useCache) { // accept "[L<class name>;" as a class name. if (classname.charAt(0) == '[') classname = Descriptor.toClassName(classname); if (classname.endsWith("[]")) { String base = classname.substring(0, classname.indexOf('[')); if ((!useCache || getCached(base) == null) && find(base) == null) return null; else return new CtArray(classname, this); } else if (find(classname) == null) return null; else return new CtClassType(classname, this); }
Searches the class path to obtain the URL of the class file specified by classname. It is also used to determine whether the class file exists.
Params:
  • classname – a fully-qualified class name.
See Also:
Returns:null if the class file could not be found.
/** * Searches the class path to obtain the URL of the class file * specified by classname. It is also used to determine whether * the class file exists. * * @param classname a fully-qualified class name. * @return null if the class file could not be found. * @see CtClass#getURL() */
public URL find(String classname) { return source.find(classname); } /* * Is invoked by CtClassType.setName() and methods in this class. * This method throws an exception if the class is already frozen or * if this class pool cannot edit the class since it is in a parent * class pool. * * @see checkNotExists(String) */ void checkNotFrozen(String classname) throws RuntimeException { CtClass clazz = getCached(classname); if (clazz == null) { if (!childFirstLookup && parent != null) { try { clazz = parent.get0(classname, true); } catch (NotFoundException e) {} if (clazz != null) throw new RuntimeException(classname + " is in a parent ClassPool. Use the parent."); } } else if (clazz.isFrozen()) throw new RuntimeException(classname + ": frozen class (cannot edit)"); } /* * This method returns null if this or its parent class pool does * not contain a CtClass object with the class name. * * @see checkNotFrozen(String) */ CtClass checkNotExists(String classname) { CtClass clazz = getCached(classname); if (clazz == null) if (!childFirstLookup && parent != null) { try { clazz = parent.get0(classname, true); } catch (NotFoundException e) {} } return clazz; } /* for CtClassType.getClassFile2(). Don't delegate to the parent. */ InputStream openClassfile(String classname) throws NotFoundException { return source.openClassfile(classname); } void writeClassfile(String classname, OutputStream out) throws NotFoundException, IOException, CannotCompileException { source.writeClassfile(classname, out); }
Reads class files from the source and returns an array of CtClass objects representing those class files.

If an element of classnames ends with "[]", then this method returns a CtClass object for that array type.

Params:
  • classnames – an array of fully-qualified class name.
/** * Reads class files from the source and returns an array of * <code>CtClass</code> * objects representing those class files. * * <p>If an element of <code>classnames</code> ends with "[]", * then this method * returns a <code>CtClass</code> object for that array type. * * @param classnames an array of fully-qualified class name. */
public CtClass[] get(String[] classnames) throws NotFoundException { if (classnames == null) return new CtClass[0]; int num = classnames.length; CtClass[] result = new CtClass[num]; for (int i = 0; i < num; ++i) result[i] = get(classnames[i]); return result; }
Reads a class file and obtains a compile-time method.
Params:
  • classname – the class name
  • methodname – the method name
See Also:
/** * Reads a class file and obtains a compile-time method. * * @param classname the class name * @param methodname the method name * @see CtClass#getDeclaredMethod(String) */
public CtMethod getMethod(String classname, String methodname) throws NotFoundException { CtClass c = get(classname); return c.getDeclaredMethod(methodname); }
Creates a new class (or interface) from the given class file. If there already exists a class with the same name, the new class overwrites that previous class.

This method is used for creating a CtClass object directly from a class file. The qualified class name is obtained from the class file; you do not have to explicitly give the name.

Params:
  • classfile – class file.
Throws:
See Also:
/** * Creates a new class (or interface) from the given class file. * If there already exists a class with the same name, the new class * overwrites that previous class. * * <p>This method is used for creating a <code>CtClass</code> object * directly from a class file. The qualified class name is obtained * from the class file; you do not have to explicitly give the name. * * @param classfile class file. * @throws RuntimeException if there is a frozen class with the * the same name. * @see #makeClassIfNew(InputStream) * @see javassist.ByteArrayClassPath */
public CtClass makeClass(InputStream classfile) throws IOException, RuntimeException { return makeClass(classfile, true); }
Creates a new class (or interface) from the given class file. If there already exists a class with the same name, the new class overwrites that previous class.

This method is used for creating a CtClass object directly from a class file. The qualified class name is obtained from the class file; you do not have to explicitly give the name.

Params:
  • classfile – class file.
  • ifNotFrozen – throws a RuntimeException if this parameter is true and there is a frozen class with the same name.
See Also:
/** * Creates a new class (or interface) from the given class file. * If there already exists a class with the same name, the new class * overwrites that previous class. * * <p>This method is used for creating a <code>CtClass</code> object * directly from a class file. The qualified class name is obtained * from the class file; you do not have to explicitly give the name. * * @param classfile class file. * @param ifNotFrozen throws a RuntimeException if this parameter is true * and there is a frozen class with the same name. * @see javassist.ByteArrayClassPath */
public CtClass makeClass(InputStream classfile, boolean ifNotFrozen) throws IOException, RuntimeException { compress(); classfile = new BufferedInputStream(classfile); CtClass clazz = new CtClassType(classfile, this); clazz.checkModify(); String classname = clazz.getName(); if (ifNotFrozen) checkNotFrozen(classname); cacheCtClass(classname, clazz, true); return clazz; }
Creates a new class (or interface) from the given class file. If there already exists a class with the same name, the new class overwrites that previous class.

This method is used for creating a CtClass object directly from a class file. The qualified class name is obtained from the class file; you do not have to explicitly give the name.

Params:
  • classfile – class file.
Throws:
Since:3.20
/** * Creates a new class (or interface) from the given class file. * If there already exists a class with the same name, the new class * overwrites that previous class. * * <p>This method is used for creating a <code>CtClass</code> object * directly from a class file. The qualified class name is obtained * from the class file; you do not have to explicitly give the name. * * @param classfile class file. * @throws RuntimeException if there is a frozen class with the * the same name. * @since 3.20 */
public CtClass makeClass(ClassFile classfile) throws RuntimeException { return makeClass(classfile, true); }
Creates a new class (or interface) from the given class file. If there already exists a class with the same name, the new class overwrites that previous class.

This method is used for creating a CtClass object directly from a class file. The qualified class name is obtained from the class file; you do not have to explicitly give the name.

Params:
  • classfile – class file.
  • ifNotFrozen – throws a RuntimeException if this parameter is true and there is a frozen class with the same name.
Since:3.20
/** * Creates a new class (or interface) from the given class file. * If there already exists a class with the same name, the new class * overwrites that previous class. * * <p>This method is used for creating a <code>CtClass</code> object * directly from a class file. The qualified class name is obtained * from the class file; you do not have to explicitly give the name. * * @param classfile class file. * @param ifNotFrozen throws a RuntimeException if this parameter is true * and there is a frozen class with the same name. * @since 3.20 */
public CtClass makeClass(ClassFile classfile, boolean ifNotFrozen) throws RuntimeException { compress(); CtClass clazz = new CtClassType(classfile, this); clazz.checkModify(); String classname = clazz.getName(); if (ifNotFrozen) checkNotFrozen(classname); cacheCtClass(classname, clazz, true); return clazz; }
Creates a new class (or interface) from the given class file. If there already exists a class with the same name, this method returns the existing class; a new class is never created from the given class file.

This method is used for creating a CtClass object directly from a class file. The qualified class name is obtained from the class file; you do not have to explicitly give the name.

Params:
  • classfile – the class file.
See Also:
Since:3.9
/** * Creates a new class (or interface) from the given class file. * If there already exists a class with the same name, this method * returns the existing class; a new class is never created from * the given class file. * * <p>This method is used for creating a <code>CtClass</code> object * directly from a class file. The qualified class name is obtained * from the class file; you do not have to explicitly give the name. * * @param classfile the class file. * @see #makeClass(InputStream) * @see javassist.ByteArrayClassPath * @since 3.9 */
public CtClass makeClassIfNew(InputStream classfile) throws IOException, RuntimeException { compress(); classfile = new BufferedInputStream(classfile); CtClass clazz = new CtClassType(classfile, this); clazz.checkModify(); String classname = clazz.getName(); CtClass found = checkNotExists(classname); if (found != null) return found; else { cacheCtClass(classname, clazz, true); return clazz; } }
Creates a new public class. If there already exists a class with the same name, the new class overwrites that previous class.

If no constructor is explicitly added to the created new class, Javassist generates constructors and adds it when the class file is generated. It generates a new constructor for each constructor of the super class. The new constructor takes the same set of parameters and invokes the corresponding constructor of the super class. All the received parameters are passed to it.

Params:
  • classname – a fully-qualified class name.
Throws:
/** * Creates a new public class. * If there already exists a class with the same name, the new class * overwrites that previous class. * * <p>If no constructor is explicitly added to the created new * class, Javassist generates constructors and adds it when * the class file is generated. It generates a new constructor * for each constructor of the super class. The new constructor * takes the same set of parameters and invokes the * corresponding constructor of the super class. All the received * parameters are passed to it. * * @param classname a fully-qualified class name. * @throws RuntimeException if the existing class is frozen. */
public CtClass makeClass(String classname) throws RuntimeException { return makeClass(classname, null); }
Creates a new public class. If there already exists a class/interface with the same name, the new class overwrites that previous class.

If no constructor is explicitly added to the created new class, Javassist generates constructors and adds it when the class file is generated. It generates a new constructor for each constructor of the super class. The new constructor takes the same set of parameters and invokes the corresponding constructor of the super class. All the received parameters are passed to it.

Params:
  • classname – a fully-qualified class name.
  • superclass – the super class.
Throws:
/** * Creates a new public class. * If there already exists a class/interface with the same name, * the new class overwrites that previous class. * * <p>If no constructor is explicitly added to the created new * class, Javassist generates constructors and adds it when * the class file is generated. It generates a new constructor * for each constructor of the super class. The new constructor * takes the same set of parameters and invokes the * corresponding constructor of the super class. All the received * parameters are passed to it. * * @param classname a fully-qualified class name. * @param superclass the super class. * @throws RuntimeException if the existing class is frozen. */
public synchronized CtClass makeClass(String classname, CtClass superclass) throws RuntimeException { checkNotFrozen(classname); CtClass clazz = new CtNewClass(classname, this, false, superclass); cacheCtClass(classname, clazz, true); return clazz; }
Creates a new public nested class. This method is called by CtClassType.makeNestedClass().
Params:
  • classname – a fully-qualified class name.
Returns: the nested class.
/** * Creates a new public nested class. * This method is called by {@link CtClassType#makeNestedClass()}. * * @param classname a fully-qualified class name. * @return the nested class. */
synchronized CtClass makeNestedClass(String classname) { checkNotFrozen(classname); CtClass clazz = new CtNewClass(classname, this, false, null); cacheCtClass(classname, clazz, true); return clazz; }
Creates a new public interface. If there already exists a class/interface with the same name, the new interface overwrites that previous one.
Params:
  • name – a fully-qualified interface name.
Throws:
/** * Creates a new public interface. * If there already exists a class/interface with the same name, * the new interface overwrites that previous one. * * @param name a fully-qualified interface name. * @throws RuntimeException if the existing interface is frozen. */
public CtClass makeInterface(String name) throws RuntimeException { return makeInterface(name, null); }
Creates a new public interface. If there already exists a class/interface with the same name, the new interface overwrites that previous one.
Params:
  • name – a fully-qualified interface name.
  • superclass – the super interface.
Throws:
/** * Creates a new public interface. * If there already exists a class/interface with the same name, * the new interface overwrites that previous one. * * @param name a fully-qualified interface name. * @param superclass the super interface. * @throws RuntimeException if the existing interface is frozen. */
public synchronized CtClass makeInterface(String name, CtClass superclass) throws RuntimeException { checkNotFrozen(name); CtClass clazz = new CtNewClass(name, this, true, superclass); cacheCtClass(name, clazz, true); return clazz; }
Creates a new annotation. If there already exists a class/interface with the same name, the new interface overwrites that previous one.
Params:
  • name – a fully-qualified interface name. Or null if the annotation has no super interface.
Throws:
Since:3.19
/** * Creates a new annotation. * If there already exists a class/interface with the same name, * the new interface overwrites that previous one. * * @param name a fully-qualified interface name. * Or null if the annotation has no super interface. * @throws RuntimeException if the existing interface is frozen. * @since 3.19 */
public CtClass makeAnnotation(String name) throws RuntimeException { try { CtClass cc = makeInterface(name, get("java.lang.annotation.Annotation")); cc.setModifiers(cc.getModifiers() | Modifier.ANNOTATION); return cc; } catch (NotFoundException e) { // should never happen. throw new RuntimeException(e.getMessage(), e); } }
Appends the system search path to the end of the search path. The system search path usually includes the platform library, extension libraries, and the search path specified by the -classpath option or the CLASSPATH environment variable.
Returns:the appended class path.
/** * Appends the system search path to the end of the * search path. The system search path * usually includes the platform library, extension * libraries, and the search path specified by the * <code>-classpath</code> option or the <code>CLASSPATH</code> * environment variable. * * @return the appended class path. */
public ClassPath appendSystemPath() { return source.appendSystemPath(); }
Insert a ClassPath object at the head of the search path.
See Also:
Returns:the inserted class path.
/** * Insert a <code>ClassPath</code> object at the head of the * search path. * * @return the inserted class path. * @see javassist.ClassPath * @see javassist.URLClassPath * @see javassist.ByteArrayClassPath */
public ClassPath insertClassPath(ClassPath cp) { return source.insertClassPath(cp); }
Appends a ClassPath object to the end of the search path.
See Also:
Returns:the appended class path.
/** * Appends a <code>ClassPath</code> object to the end of the * search path. * * @return the appended class path. * @see javassist.ClassPath * @see javassist.URLClassPath * @see javassist.ByteArrayClassPath */
public ClassPath appendClassPath(ClassPath cp) { return source.appendClassPath(cp); }
Inserts a directory or a jar (or zip) file at the head of the search path.
Params:
  • pathname – the path name of the directory or jar file. It must not end with a path separator ("/"). If the path name ends with "/*", then all the jar files matching the path name are inserted.
Throws:
Returns:the inserted class path.
/** * Inserts a directory or a jar (or zip) file at the head of the * search path. * * @param pathname the path name of the directory or jar file. * It must not end with a path separator ("/"). * If the path name ends with "/*", then all the * jar files matching the path name are inserted. * * @return the inserted class path. * @throws NotFoundException if the jar file is not found. */
public ClassPath insertClassPath(String pathname) throws NotFoundException { return source.insertClassPath(pathname); }
Appends a directory or a jar (or zip) file to the end of the search path.
Params:
  • pathname – the path name of the directory or jar file. It must not end with a path separator ("/"). If the path name ends with "/*", then all the jar files matching the path name are appended.
Throws:
Returns:the appended class path.
/** * Appends a directory or a jar (or zip) file to the end of the * search path. * * @param pathname the path name of the directory or jar file. * It must not end with a path separator ("/"). * If the path name ends with "/*", then all the * jar files matching the path name are appended. * * @return the appended class path. * @throws NotFoundException if the jar file is not found. */
public ClassPath appendClassPath(String pathname) throws NotFoundException { return source.appendClassPath(pathname); }
Detatches the ClassPath object from the search path. The detached ClassPath object cannot be added to the path again.
/** * Detatches the <code>ClassPath</code> object from the search path. * The detached <code>ClassPath</code> object cannot be added * to the path again. */
public void removeClassPath(ClassPath cp) { source.removeClassPath(cp); }
Appends directories and jar files for search.

The elements of the given path list must be separated by colons in Unix or semi-colons in Windows.

Params:
  • pathlist – a (semi)colon-separated list of the path names of directories and jar files. The directory name must not end with a path separator ("/").
Throws:
/** * Appends directories and jar files for search. * * <p>The elements of the given path list must be separated by colons * in Unix or semi-colons in Windows. * * @param pathlist a (semi)colon-separated list of * the path names of directories and jar files. * The directory name must not end with a path * separator ("/"). * @throws NotFoundException if a jar file is not found. */
public void appendPathList(String pathlist) throws NotFoundException { char sep = File.pathSeparatorChar; int i = 0; for (;;) { int j = pathlist.indexOf(sep, i); if (j < 0) { appendClassPath(pathlist.substring(i)); break; } else { appendClassPath(pathlist.substring(i, j)); i = j + 1; } } }
Converts the given class to a java.lang.Class object. Once this method is called, further modifications are not allowed any more. To load the class, this method uses the context class loader of the current thread. It is obtained by calling getClassLoader().

This behavior can be changed by subclassing the pool and changing the getClassLoader() method. If the program is running on some application server, the context class loader might be inappropriate to load the class.

This method is provided for convenience. If you need more complex functionality, you should write your own class loader.

Warining: This method should not be used in Java 11 or later. Use toClass(CtClass, Class<?>).

Warining: A Class object returned by this method may not work with a security manager or a signed jar file because a protection domain is not specified.

See Also:
/** * Converts the given class to a <code>java.lang.Class</code> object. * Once this method is called, further modifications are not * allowed any more. * To load the class, this method uses the context class loader * of the current thread. It is obtained by calling * <code>getClassLoader()</code>. * * <p>This behavior can be changed by subclassing the pool and changing * the <code>getClassLoader()</code> method. * If the program is running on some application * server, the context class loader might be inappropriate to load the * class.</p> * * <p>This method is provided for convenience. If you need more * complex functionality, you should write your own class loader. * * <p><b>Warining:</b> * This method should not be used in Java 11 or later. * Use {@link #toClass(CtClass,Class)}. * </p> * * <p><b>Warining:</b> * A Class object returned by this method may not * work with a security manager or a signed jar file because a * protection domain is not specified.</p> * * @see #toClass(CtClass,Class) * @see #toClass(CtClass,Class,java.lang.ClassLoader,ProtectionDomain) * @see #getClassLoader() */
public Class toClass(CtClass clazz) throws CannotCompileException { // Some subclasses of ClassPool may override toClass(CtClass,ClassLoader). // So we should call that method instead of toClass(.., ProtectionDomain). return toClass(clazz, getClassLoader()); }
Get the classloader for toClass(), getAnnotations() in CtClass, etc.

The default is the context class loader.

See Also:
Returns:the classloader for the pool
/** * Get the classloader for <code>toClass()</code>, <code>getAnnotations()</code> in * <code>CtClass</code>, etc. * * <p>The default is the context class loader. * * @return the classloader for the pool * @see #toClass(CtClass) * @see CtClass#getAnnotations() */
public ClassLoader getClassLoader() { return getContextClassLoader(); }
Obtains a class loader that seems appropriate to look up a class by name.
/** * Obtains a class loader that seems appropriate to look up a class * by name. */
static ClassLoader getContextClassLoader() { return Thread.currentThread().getContextClassLoader(); }
Converts the class to a java.lang.Class object. Do not override this method any more at a subclass because toClass(CtClass) will never calls this method.

Warining: A Class object returned by this method may not work with a security manager or a signed jar file because a protection domain is not specified.

Deprecated: Replaced by toClass(CtClass, Class<?>, ClassLoader, ProtectionDomain). A subclass of ClassPool that has been overriding this method should be modified. It should override toClass(CtClass, Class<?>, ClassLoader, ProtectionDomain).
/** * Converts the class to a <code>java.lang.Class</code> object. * Do not override this method any more at a subclass because * {@link #toClass(CtClass)} will never calls this method. * * <p><b>Warining:</b> A Class object returned by this method may not * work with a security manager or a signed jar file because a * protection domain is not specified. * * @deprecated Replaced by {@link #toClass(CtClass,Class,ClassLoader,ProtectionDomain)}. * A subclass of <code>ClassPool</code> that has been * overriding this method should be modified. It should override * {@link #toClass(CtClass,Class,ClassLoader,ProtectionDomain)}. */
public Class toClass(CtClass ct, ClassLoader loader) throws CannotCompileException { return toClass(ct, null, loader, null); }
Converts the class to a java.lang.Class object. Once this method is called, further modifications are not allowed any more.

The class file represented by the given CtClass is loaded by the given class loader to construct a java.lang.Class object. Since a private method on the class loader is invoked through the reflection API, the caller must have permissions to do that.

An easy way to obtain ProtectionDomain object is to call getProtectionDomain() in java.lang.Class. It returns the domain that the class belongs to.

This method is provided for convenience. If you need more complex functionality, you should write your own class loader.

Params:
  • ct – the class converted into java.lang.Class.
  • loader – the class loader used to load this class. For example, the loader returned by getClassLoader() can be used for this parameter.
  • domain – the protection domain for the class. If it is null, the default domain created by java.lang.ClassLoader is used.
See Also:
Since:3.3
Deprecated: Replaced by toClass(CtClass, Class<?>, ClassLoader, ProtectionDomain).
/** * Converts the class to a <code>java.lang.Class</code> object. * Once this method is called, further modifications are not allowed * any more. * * <p>The class file represented by the given <code>CtClass</code> is * loaded by the given class loader to construct a * <code>java.lang.Class</code> object. Since a private method * on the class loader is invoked through the reflection API, * the caller must have permissions to do that.</p> * * <p>An easy way to obtain <code>ProtectionDomain</code> object is * to call <code>getProtectionDomain()</code> * in <code>java.lang.Class</code>. It returns the domain that the * class belongs to. * * <p>This method is provided for convenience. If you need more * complex functionality, you should write your own class loader.</p> * * @param ct the class converted into {@code java.lang.Class}. * @param loader the class loader used to load this class. * For example, the loader returned by * <code>getClassLoader()</code> can be used * for this parameter. * @param domain the protection domain for the class. * If it is null, the default domain created * by <code>java.lang.ClassLoader</code> is used. * * @see #getClassLoader() * @since 3.3 * @deprecated Replaced by {@link #toClass(CtClass,Class,ClassLoader,ProtectionDomain)}. */
public Class toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain) throws CannotCompileException { return toClass(ct, null, loader, domain); }
Converts the class to a java.lang.Class object. Once this method is called, further modifications are not allowed any more.

This method is available in Java 9 or later. It loads the class by using java.lang.invoke.MethodHandles with neighbor.

Params:
  • ct – the class converted into java.lang.Class.
  • neighbor – a class belonging to the same package that the converted class belongs to.
Since:3.24
/** * Converts the class to a <code>java.lang.Class</code> object. * Once this method is called, further modifications are not allowed * any more. * * <p>This method is available in Java 9 or later. * It loads the class * by using {@code java.lang.invoke.MethodHandles} with {@code neighbor}. * </p> * * @param ct the class converted into {@code java.lang.Class}. * @param neighbor a class belonging to the same package that * the converted class belongs to. * @since 3.24 */
public Class<?> toClass(CtClass ct, Class<?> neighbor) throws CannotCompileException { try { return javassist.util.proxy.DefineClassHelper.toClass(neighbor, ct.toBytecode()); } catch (IOException e) { throw new CannotCompileException(e); } }
Converts the class to a java.lang.Class object. Once this method is called, further modifications are not allowed any more.

This method is available in Java 9 or later. It loads the class by using the given java.lang.invoke.MethodHandles.Lookup.

Params:
  • ct – the class converted into java.lang.Class.
Since:3.24
/** * Converts the class to a <code>java.lang.Class</code> object. * Once this method is called, further modifications are not allowed * any more. * * <p>This method is available in Java 9 or later. * It loads the class * by using the given {@code java.lang.invoke.MethodHandles.Lookup}. * </p> * * @param ct the class converted into {@code java.lang.Class}. * @since 3.24 */
public Class<?> toClass(CtClass ct, java.lang.invoke.MethodHandles.Lookup lookup) throws CannotCompileException { try { return javassist.util.proxy.DefineClassHelper.toClass(lookup, ct.toBytecode()); } catch (IOException e) { throw new CannotCompileException(e); } }
Converts the class to a java.lang.Class object. Once this method is called, further modifications are not allowed any more.

When the JVM is Java 11 or later, this method loads the class by using java.lang.invoke.MethodHandles with neighbor. The other arguments loader and domain are not used; so they can be null.

Otherwise, or when neighbor is null, the class file represented by the given CtClass is loaded by the given class loader to construct a java.lang.Class object. Since a private method on the class loader is invoked through the reflection API, the caller must have permissions to do that.

An easy way to obtain ProtectionDomain object is to call getProtectionDomain() in java.lang.Class. It returns the domain that the class belongs to.

If your program is for only Java 9 or later, don't use this method. Use toClass(CtClass, Class<?>) or toClass(CtClass, Lookup).

Params:
  • ct – the class converted into java.lang.Class.
  • neighbor – a class belonging to the same package that the converted class belongs to. It can be null.
  • loader – the class loader used to load this class. For example, the loader returned by getClassLoader() can be used for this parameter.
  • domain – the protection domain for the class. If it is null, the default domain created by java.lang.ClassLoader is used.
See Also:
Since:3.24
/** * Converts the class to a <code>java.lang.Class</code> object. * Once this method is called, further modifications are not allowed * any more. * * <p>When the JVM is Java 11 or later, this method loads the class * by using {@code java.lang.invoke.MethodHandles} with {@code neighbor}. * The other arguments {@code loader} and {@code domain} are not used; * so they can be null. * </p> * * <p>Otherwise, or when {@code neighbor} is null, * the class file represented by the given <code>CtClass</code> is * loaded by the given class loader to construct a * <code>java.lang.Class</code> object. Since a private method * on the class loader is invoked through the reflection API, * the caller must have permissions to do that. * * <p>An easy way to obtain <code>ProtectionDomain</code> object is * to call <code>getProtectionDomain()</code> * in <code>java.lang.Class</code>. It returns the domain that the * class belongs to. * * <p>If your program is for only Java 9 or later, don't use this method. * Use {@link #toClass(CtClass,Class)} or * {@link #toClass(CtClass,java.lang.invoke.MethodHandles.Lookup)}. * </p> * * @param ct the class converted into {@code java.lang.Class}. * @param neighbor a class belonging to the same package that * the converted class belongs to. * It can be null. * @param loader the class loader used to load this class. * For example, the loader returned by * <code>getClassLoader()</code> can be used * for this parameter. * @param domain the protection domain for the class. * If it is null, the default domain created * by <code>java.lang.ClassLoader</code> is used. * * @see #getClassLoader() * @since 3.24 */
public Class toClass(CtClass ct, Class<?> neighbor, ClassLoader loader, ProtectionDomain domain) throws CannotCompileException { try { return javassist.util.proxy.DefineClassHelper.toClass(ct.getName(), neighbor, loader, domain, ct.toBytecode()); } catch (IOException e) { throw new CannotCompileException(e); } }
Defines a new package. If the package is already defined, this method performs nothing.

You do not necessarily need to call this method. If this method is called, then getPackage() on the Class object returned by toClass() will return a non-null object.

The jigsaw module introduced by Java 9 has broken this method.

Params:
  • loader – the class loader passed to toClass() or the default one obtained by getClassLoader().
  • name – the package name.
See Also:
Since:3.16
Deprecated:
/** * Defines a new package. If the package is already defined, this method * performs nothing. * * <p>You do not necessarily need to * call this method. If this method is called, then * <code>getPackage()</code> on the <code>Class</code> object returned * by <code>toClass()</code> will return a non-null object.</p> * * <p>The jigsaw module introduced by Java 9 has broken this method.</p> * * @param loader the class loader passed to <code>toClass()</code> or * the default one obtained by <code>getClassLoader()</code>. * @param name the package name. * @see #getClassLoader() * @see #toClass(CtClass) * @see CtClass#toClass() * @since 3.16 * @deprecated */
public void makePackage(ClassLoader loader, String name) throws CannotCompileException { DefinePackageHelper.definePackage(name, loader); } }