This is a sample class loader using ClassPool.
Unlike a regular class loader, this class loader obtains bytecode
from a ClassPool.
Note that Javassist can be used without this class loader; programmers can define their own versions of class loader. They can run a program even without any user-defined class loader if that program is statically translated with Javassist. This class loader is just provided as a utility class.
Suppose that an instance of MyTranslator implementing
the interface Translator is responsible for modifying
class files.
The startup program of an application using MyTranslator
should be something like this:
import javassist.*;
public class Main {
public static void main(String[] args) throws Throwable {
MyTranslator myTrans = new MyTranslator();
ClassPool cp = ClassPool.getDefault();
Loader cl = new Loader(cp);
cl.addTranslator(cp, myTrans);
cl.run("MyApp", args);
}
}
Class MyApp is the main program of the application.
This program should be executed as follows:
% java Main arg1 arg2...
It modifies the class MyApp with a MyTranslator
object before the JVM loads it.
Then it calls main() in MyApp with arguments
arg1, arg2, ...
This program execution is equivalent to:
% java MyApp arg1 arg2...
except that classes are translated by MyTranslator
at load time.
If only a particular class must be modified when it is loaded,
the startup program can be simpler; MyTranslator is
unnecessary. For example, if only a class test.Rectangle
is modified, the main() method above will be the following:
ClassPool cp = ClassPool.getDefault();
Loader cl = new Loader(cp);
CtClass ct = cp.get("test.Rectangle");
ct.setSuperclass(cp.get("test.Point"));
cl.run("MyApp", args);
This program changes the super class of the test.Rectangle
class.
Note 1:
This class loader does not allow the users to intercept the loading
of java.* and javax.* classes (and
sun.*, org.xml.*, ...) unless
Loader.doDelegation is false. This is because
the JVM prohibits a user class loader from loading a system class.
Also see Note 2.
If this behavior is not appropriate, a subclass of Loader
must be defined and loadClassByDelegation() must be overridden.
Note 2:
If classes are loaded with different class loaders, they belong to
separate name spaces. If class C is loaded by a class
loader CL, all classes that the class C
refers to are also loaded by CL. However, if CL
delegates the loading of the class C to CL',
then those classes that the class C refers to
are loaded by a parent class loader CL'
instead of CL.
If an object of class C is assigned
to a variable of class C belonging to a different name
space, then a ClassCastException is thrown.
Because of the fact above, this loader delegates only the loading of
javassist.Loader
and classes included in package java.* and
javax.* to the parent class
loader. Other classes are directly loaded by this loader.
For example, suppose that java.lang.String would be loaded
by this loader while java.io.File is loaded by the parent
class loader. If the constructor of java.io.File is called
with an instance of java.lang.String, then it may throw
an exception since it accepts an instance of only the
java.lang.String loaded by the parent class loader.
javassist.ClassPool , javassist.Translator
| Modifier and Type | Class and Description |
|---|---|
| public static class | Loader.
A simpler class loader. |
| Modifier and Type | Field and Description |
|---|---|
| public boolean | doDelegation
Specifies the algorithm of class loading. |
| private ProtectionDomain | |
| private HashMap | |
| private Vector | |
| private ClassPool | |
| private Translator |
| Access | Constructor and Description |
|---|---|
| public | |
| public | |
| public | Loader(ClassLoader
the parent class loader. parent, ClassPool the source of class files. cp)Creates a new class loader using the specified parent class loader for delegation. |
| Modifier and Type | Method and Description |
|---|---|
| public void | addTranslator(ClassPool
the cp, Translator ClassPool object for obtaining
a class file.a translator. t)Adds a translator, which is called whenever a class is loaded. |
| public void | delegateLoadingOf(String classname)
Records a class so that the loading of that class is delegated to the parent class loader. |
| protected Class | |
| protected Class | Returns: null if the specified class could not be found.The binary name of the class name)Overrides java. Finds the specified class using |
| private void | |
| private boolean | |
| protected Class | loadClass(String
The binary name of the class name, boolean If resolve)true then resolve the classOverrides java. Requests the class loader to load a class. |
| protected Class | |
| public static void | |
| private boolean | |
| public void | |
| public void | |
| public void | |
| public void | setDomain(ProtectionDomain d)
Sets the protection domain for the classes handled by this class loader. |
| doDelegation | back to summary |
|---|---|
| public boolean doDelegation Specifies the algorithm of class loading. This class loader uses the parent class loader for
The default value is | |
| domain | back to summary |
|---|---|
| private ProtectionDomain domain | |
| notDefinedHere | back to summary |
|---|---|
| private HashMap<String, ClassLoader> notDefinedHere | |
| notDefinedPackages | back to summary |
|---|---|
| private Vector<String> notDefinedPackages | |
| source | back to summary |
|---|---|
| private ClassPool source | |
| translator | back to summary |
|---|---|
| private Translator translator | |
| Loader | back to summary |
|---|---|
| public Loader() Creates a new class loader. | |
| Loader | back to summary |
|---|---|
| public Loader(ClassPool cp) Creates a new class loader.
| |
| Loader | back to summary |
|---|---|
| public Loader(ClassLoader parent, ClassPool cp) Creates a new class loader using the specified parent class loader for delegation.
| |
| addTranslator | back to summary |
|---|---|
| public void addTranslator(ClassPool cp, Translator t) throws NotFoundException, CannotCompileException Adds a translator, which is called whenever a class is loaded.
| |
| delegateLoadingOf | back to summary |
|---|---|
| public void delegateLoadingOf(String classname) Records a class so that the loading of that class is delegated to the parent class loader. If the given class name ends with | |
| delegateToParent | back to summary |
|---|---|
| protected Class | |
| findClass | back to summary |
|---|---|
| protected Class Overrides java. Finds the specified class using This method can be overridden by a subclass of
| |
| init | back to summary |
|---|---|
| private void init(ClassPool cp) | |
| isDefinedPackage | back to summary |
|---|---|
| private boolean isDefinedPackage(String name) | |
| loadClass | back to summary |
|---|---|
| protected Class Overrides java. Requests the class loader to load a class.
| |
| loadClassByDelegation | back to summary |
|---|---|
| protected Class | |
| main | back to summary |
|---|---|
| public static void main(String[] args) throws Throwable Loads a class with an instance of This method calls
| |
| notDelegated | back to summary |
|---|---|
| private boolean notDelegated(String name) | |
| run | back to summary |
|---|---|
| public void run(String[] args) throws Throwable Loads a class and calls
| |
| run | back to summary |
|---|---|
| public void run(String classname, String[] args) throws Throwable Loads a class and calls | |
| setClassPool | back to summary |
|---|---|
| public void setClassPool(ClassPool cp) Sets the soruce | |
| setDomain | back to summary |
|---|---|
| public void setDomain(ProtectionDomain d) Sets the protection domain for the classes handled by this class loader. Without registering an appropriate protection domain, the program loaded by this loader will not work with a security manager or a signed jar file. | |
defineClass() method
declared in java.lang.ClassLoader. It provides a method similar to
CtClass#toClass().
When loading a class, this class loader delegates the work to the
parent class loader unless the loaded classes are explicitly given
by invokeDefineClass(CtClass).
Note that a class Foo loaded by this class loader is
different from the class with the same name Foo but loaded by
another class loader. This is Java's naming rule.
| Access | Constructor and Description |
|---|---|
| public | |
| public |
| Modifier and Type | Method and Description |
|---|---|
| public Class |
| Simple | back to summary |
|---|---|
| public Simple() Constructs a class loader. | |
| Simple | back to summary |
|---|---|
| public Simple(ClassLoader parent) Constructs a class loader.
| |
| invokeDefineClass | back to summary |
|---|---|
| public Class Invokes the protected | |