public class Loader
extends java.lang.ClassLoader
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.
ClassPool
,
Translator
Modifier and Type | Field and Description |
---|---|
boolean |
doDelegation
Specifies the algorithm of class loading.
|
Constructor and Description |
---|
Loader()
Creates a new class loader.
|
Loader(java.lang.ClassLoader parent,
ClassPool cp)
Creates a new class loader
using the specified parent class loader for delegation.
|
Loader(ClassPool cp)
Creates a new class loader.
|
Modifier and Type | Method and Description |
---|---|
void |
addTranslator(ClassPool cp,
Translator t)
Adds a translator, which is called whenever a class is loaded.
|
void |
delegateLoadingOf(java.lang.String classname)
Records a class so that the loading of that class is delegated
to the parent class loader.
|
static void |
main(java.lang.String[] args)
Loads a class with an instance of
Loader
and calls main() of that class. |
void |
run(java.lang.String[] args)
Loads a class and calls
main() in that class. |
void |
run(java.lang.String classname,
java.lang.String[] args)
Loads a class and calls
main() in that class. |
void |
setClassPool(ClassPool cp)
Sets the soruce
ClassPool . |
void |
setDomain(java.security.ProtectionDomain d)
Sets the protection domain for the classes handled by this class
loader.
|
clearAssertionStatus, getParent, getResource, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, loadClass, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus
public boolean doDelegation
This class loader uses the parent class loader for
java.*
and javax.*
classes.
If this variable doDelegation
is false
, this class loader does not delegate those
classes to the parent class loader.
The default value is true
.
public Loader()
public Loader(ClassPool cp)
cp
- the source of class files.public Loader(java.lang.ClassLoader parent, ClassPool cp)
parent
- the parent class loader.cp
- the source of class files.public void delegateLoadingOf(java.lang.String classname)
If the given class name ends with .
(dot), then
that name is interpreted as a package name. All the classes
in that package and the sub packages are delegated.
public void setDomain(java.security.ProtectionDomain d)
public void setClassPool(ClassPool cp)
ClassPool
.public void addTranslator(ClassPool cp, Translator t) throws NotFoundException, CannotCompileException
cp
- the ClassPool
object for obtaining
a class file.t
- a translator.NotFoundException
- if t.start()
throws an exception.CannotCompileException
- if t.start()
throws an exception.public static void main(java.lang.String[] args) throws java.lang.Throwable
Loader
and calls main()
of that class.
This method calls run()
.
args
- command line parameters.
args[0]
is the class name to be loaded.
args[1..n]
are parameters passed
to the target main()
.java.lang.Throwable
run(String[])
public void run(java.lang.String[] args) throws java.lang.Throwable
main()
in that class.args
- command line parameters.
args[0]
is the class name to be loaded.
args[1..n]
are parameters passed
to the target main()
.java.lang.Throwable
public void run(java.lang.String classname, java.lang.String[] args) throws java.lang.Throwable
main()
in that class.classname
- the loaded class.args
- parameters passed to main()
.java.lang.Throwable
Javassist, a Java-bytecode translator toolkit.
Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.