Skip to content

Commit

Permalink
fixed bugs so that sample programs can run.
Browse files Browse the repository at this point in the history
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@86 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
  • Loading branch information
chiba committed Apr 16, 2004
1 parent f480c5d commit a5ddd61
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 103 deletions.
8 changes: 4 additions & 4 deletions sample/evolve/Evolution.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,23 @@ public void start(ClassPool _pool) throws NotFoundException {
trapMethod = _pool.getMethod("sample.evolve.Sample", "make");
}

public void onWrite(ClassPool _pool, CtClass clazz)
public void onLoad(ClassPool _pool, String classname)
throws NotFoundException, CannotCompileException
{
onWriteUpdatable(clazz.getName());
onLoadUpdatable(classname);

/*
* Replaces all the occurrences of the new operator with a call
* to _makeInstance().
*/
CtClass clazz = _pool.get(classname);
CtClass absClass = updatableClass;
CodeConverter converter = new CodeConverter();
converter.replaceNew(absClass, absClass, handlerMethod);
clazz.instrument(converter);
}

private void onWriteUpdatable(String classname)
private void onLoadUpdatable(String classname)
throws NotFoundException, CannotCompileException
{
// if the class is a concrete class,
Expand All @@ -80,7 +81,6 @@ private void onWriteUpdatable(String classname)
throw new NotFoundException(classname, e);
}


CtClass clazz = pool.getAndRename(orgname, classname);
makeConcreteClass(clazz, updatableClass, version);
}
Expand Down
3 changes: 1 addition & 2 deletions src/main/javassist/ClassPath.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* representing a class search path.
* <code>ClassPool</code> uses those objects for reading class files.
*
* <code>The users can define a class implementing this interface so that
* <p>The users can define a class implementing this interface so that
* a class file is obtained from a non-standard source.
*
* @see ClassPool#insertClassPath(ClassPath)
Expand All @@ -42,7 +42,6 @@ public interface ClassPath {
* so that the search will be terminated.
*
* <p>This method should not modify the contents of the class file.
* Use <code>javassist.Translator</code> for modification.
*
* @param classname a fully-qualified class name
* @return the input stream for reading a class file
Expand Down
81 changes: 28 additions & 53 deletions src/main/javassist/ClassPool.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,68 +20,36 @@
import java.util.Hashtable;

/**
* A driver class for controlling bytecode editing with Javassist.
* It manages where a class file is obtained and how it is modified.
*
* <p>A <code>ClassPool</code> object can be regarded as a container
* of <code>CtClass</code> objects. It reads class files on demand
* from various
* sources represented by <code>ClassPath</code> and create
* <code>CtClass</code> objects representing those class files.
*
* <p>A <code>CtClass</code>
* object contained in a <code>ClassPool</code> is written to an
* output stream (or a file) if <code>write()</code>
* (or <code>writeFile()</code>) is called on the
* <code>ClassPool</code>.
* <code>write()</code> is typically called by a class loader,
* which obtains the bytecode image to be loaded.
*
* <p>The users can modify <code>CtClass</code> objects
* before those objects are written out.
* To obtain a reference
* to a <code>CtClass</code> object contained in a
* <code>ClassPool</code>, <code>get()</code> should be
* called on the <code>ClassPool</code>. If a <code>CtClass</code>
* object is modified, then the modification is reflected on the resulting
* class file returned by <code>write()</code> in <code>ClassPool</code>.
*
* <p>In summary,
*
* <ul>
* <li><code>get()</code> returns a reference to a <code>CtClass</code>
* object contained in a <code>ClassPool</code>.
*
* <li><code>write()</code> translates a <code>CtClass</code>
* object contained in a <code>ClassPool</code> into a class file
* and writes it to an output stream.
* </ul>
*
* <p>The users can add a listener object receiving an event from a
* <code>ClassPool</code>. An event occurs when a listener is
* added to a <code>ClassPool</code> and when <code>write()</code>
* is called on a <code>ClassPool</code> (not when <code>get()</code>
* is called!). The listener class
* must implement <code>Translator</code>. A typical listener object
* is used for modifying a <code>CtClass</code> object <i>on demand</i>
* when it is written to an output stream.
*
* <p>The implementation of this class is thread-safe.
* 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, multiple <code>ClassPool</code> objects
* must be used. Note that <code>getDefault()</code> is a singleton
* factory.
* 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.
*
* <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
* @see javassist.Translator
*/
public class ClassPool {

Expand All @@ -107,10 +75,18 @@ public class ClassPool {
*/
private Hashtable cflow = null; // should be synchronous.

/**
* Creates a root class pool. No parent class pool is specified.
*
*/
public ClassPool() {
this(null);
}

/**
* Creates a class pool.
*
* @param p the parent of this class pool. If this is a root
* @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()
*/
Expand Down Expand Up @@ -148,7 +124,6 @@ public ClassPool(ClassPool parent) {
* <p>If the default class pool cannot find any class files,
* try <code>ClassClassPath</code> and <code>LoaderClassPath</code>.
*
* @param t null or the translator linked to the class pool.
* @see ClassClassPath
* @see LoaderClassPath
*/
Expand Down
4 changes: 2 additions & 2 deletions src/main/javassist/CtClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ public void instrument(ExprEditor editor)
*
* @return the <code>Class</code> object representing the loaded class.
* @see CtClass#forName(String)
* @see ClassPool.SimpleClassLoader
* @see ClassPool.SimpleLoader
* @see Loader
*/
public Class toClass()
Expand All @@ -859,7 +859,7 @@ public Class toClass()
* been loaded by an internal class loader of Javassist.
*
* @see CtClass#toClass()
* @see ClassPool.SimpleClassLoader
* @see ClassPool.SimpleLoader
*/
public static Class forName(String name) throws ClassNotFoundException {
return ClassPool.forName(name);
Expand Down
58 changes: 29 additions & 29 deletions src/main/javassist/Loader.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import java.util.Vector;

/**
* The class loader for Javassist (JDK 1.2 or later only).
* The class loader for Javassist.
*
* <p>This is a sample class loader using <code>ClassPool</code>.
* Unlike a regular class loader, this class loader obtains bytecode
Expand Down Expand Up @@ -61,7 +61,7 @@
* </pre></ul>
*
* <p>It modifies the class <code>MyApp</code> with a <code>MyTranslator</code>
* object before loading it into the JVM.
* object before the JVM loads it.
* Then it calls <code>main()</code> in <code>MyApp</code> with arguments
* <i>arg1</i>, <i>arg2</i>, ...
*
Expand All @@ -74,20 +74,20 @@
* <p>except that classes are translated by <code>MyTranslator</code>
* at load time.
*
* <p>If only a particular class is modified when it is loaded,
* a program like the following can be used:
* <p>If only a particular class must be modified when it is loaded,
* the startup program can be simpler; <code>MyTranslator</code> is
* unnecessary. For example, if only a class <code>test.Rectangle</code>
* is modified, the <code>main()</code> method above will be the following:
*
* <ul><pre>ClassPool cp = ClassPool.getDefault();
* <ul><pre>
* 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);</pre></ul>
*
* Class c = cl.loadClass("test.Rectangle");
* Object rect = c.newInstance();</pre></ul>
*
* <p>This program modifies the super class of the <code>Rectangle</code>
* class and loads it into the JVM with a class loader <code>cl</code>.
* <p>This program changes the super class of the <code>test.Rectangle</code>
* class.
*
* <p><b>Note 1:</b>
*
Expand Down Expand Up @@ -128,8 +128,8 @@
* @see javassist.Translator
*/
public class Loader extends ClassLoader {
private Hashtable notDefinedHere; // must be atomic.
private Vector notDefinedPackages; // must be atomic.
private Hashtable notDefinedHere; // must be atomic.
private Vector notDefinedPackages; // must be atomic.
private ClassPool source;
private Translator translator;

Expand Down Expand Up @@ -212,8 +212,7 @@ public void setClassPool(ClassPool cp) {
* @param t a translator.
*/
public void addTranslator(ClassPool cp, Translator t)
throws NotFoundException, CannotCompileException
{
throws NotFoundException, CannotCompileException {
source = cp;
translator = t;
t.start(cp);
Expand Down Expand Up @@ -269,8 +268,9 @@ public void run(String[] args) throws Throwable {
public void run(String classname, String[] args) throws Throwable {
Class c = loadClass(classname);
try {
c.getDeclaredMethod("main", new Class[] { String[].class })
.invoke(null, new Object[] { args });
c.getDeclaredMethod("main", new Class[] { String[].class }).invoke(
null,
new Object[] { args });
}
catch (java.lang.reflect.InvocationTargetException e) {
throw e.getTargetException();
Expand All @@ -281,8 +281,7 @@ public void run(String classname, String[] args) throws Throwable {
* Requests the class loader to load a class.
*/
protected Class loadClass(String name, boolean resolve)
throws ClassFormatError, ClassNotFoundException
{
throws ClassFormatError, ClassNotFoundException {
Class c = findLoadedClass(name);
if (c == null)
c = loadClassByDelegation(name);
Expand Down Expand Up @@ -310,11 +309,10 @@ protected Class findClass(String name) {
byte[] classfile;
try {
if (source != null) {
CtClass c = source.get(name);
if (translator != null)
translator.onWrite(source, c);
translator.onLoad(source, name);

classfile = c.toBytecode();
classfile = source.get(name).toBytecode();
}
else {
String jarname = "/" + name.replace('.', '/') + ".class";
Expand All @@ -327,13 +325,13 @@ protected Class findClass(String name) {
return null;
}

int i = name.lastIndexOf('.');
if (i != -1) {
String pname = name.substring(0, i);
int i = name.lastIndexOf('.');
if (i != -1) {
String pname = name.substring(0, i);
if (getPackage(pname) == null)
try {
definePackage(pname, null, null, null,
null, null, null, null);
definePackage(
pname, null, null, null, null, null, null, null);
}
catch (IllegalArgumentException e) {
// ignore. maybe the package object for the same
Expand All @@ -359,8 +357,10 @@ private Class loadClassByDelegation(String name)

Class c = null;
if (doDelegation)
if (name.startsWith("java.") || name.startsWith("javax.")
|| name.startsWith("sun.") || name.startsWith("com.sun.")
if (name.startsWith("java.")
|| name.startsWith("javax.")
|| name.startsWith("sun.")
|| name.startsWith("com.sun.")
|| notDelegated(name))
c = delegateToParent(name);

Expand Down
17 changes: 13 additions & 4 deletions src/main/javassist/Translator.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* <code>Loader</code> object so that it can translate a class file
* when the class file is loaded into the JVM.
*
* @see Loader
* @see Loader#addTranslator(ClassPool, Translator)
*/
public interface Translator {
/**
Expand All @@ -38,13 +38,22 @@ void start(ClassPool pool)

/**
* Is invoked by a <code>Loader</code> for notifying that
* a class is loaded.
* a class is loaded. The <code>Loader</code> calls
*
* <ul><pre>
* pool.get(classname).toBytecode()</pre></ul>
*
* to read the class file after <code>onLoad()</code> returns.
*
* <p>The class specified by <code>classname</code> may not exist.
* If so, <code>onLoad()</code> should create that class so that
* the <code>Loader</code> can read it.
*
* @param pool the <code>ClassPool</code> that this translator
* should use.
* @param clazz the class that is being loaded.
* @param classname the name of the class being loaded.
* @see Loader
*/
void onWrite(ClassPool pool, CtClass clazz)
void onLoad(ClassPool pool, String classname)
throws NotFoundException, CannotCompileException;
}
5 changes: 2 additions & 3 deletions src/main/javassist/reflect/Compiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,8 @@ private static void processClasses(CompiledClass[] entries, int n)
}

for (int i = 0; i < n; ++i) {
CtClass c = pool.get(entries[i].classname);
implementor.onWrite(pool, c);
c.writeFile();
implementor.onLoad(pool, entries[i].classname);
pool.get(entries[i].classname).writeFile();
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/main/javassist/reflect/Reflection.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public Reflection() {
}

/**
* Initializes.
* Initializes the object.
*/
public void start(ClassPool pool) throws NotFoundException {
classPool = pool;
Expand All @@ -115,9 +115,10 @@ public void start(ClassPool pool) throws NotFoundException {
* Inserts hooks for intercepting accesses to the fields declared
* in reflective classes.
*/
public void onWrite(ClassPool pool, CtClass clazz)
public void onLoad(ClassPool pool, String classname)
throws CannotCompileException, NotFoundException
{
CtClass clazz = pool.get(classname);
clazz.instrument(converter);
}

Expand Down
Loading

0 comments on commit a5ddd61

Please sign in to comment.