diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2004-04-16 15:12:45 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2004-04-16 15:12:45 +0000 |
commit | a5ddd6104e99fa22a5b1c36f5e3e585400b6e4c7 (patch) | |
tree | 8ae21fb63c94b9e58874377a5da414310f807a3c /src | |
parent | f480c5d9122f26f32fa89f44ea7d606fd3df8557 (diff) | |
download | javassist-a5ddd6104e99fa22a5b1c36f5e3e585400b6e4c7.tar.gz javassist-a5ddd6104e99fa22a5b1c36f5e3e585400b6e4c7.zip |
fixed bugs so that sample programs can run.
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@86 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src')
-rw-r--r-- | src/main/javassist/ClassPath.java | 3 | ||||
-rw-r--r-- | src/main/javassist/ClassPool.java | 81 | ||||
-rw-r--r-- | src/main/javassist/CtClass.java | 4 | ||||
-rw-r--r-- | src/main/javassist/Loader.java | 58 | ||||
-rw-r--r-- | src/main/javassist/Translator.java | 17 | ||||
-rw-r--r-- | src/main/javassist/reflect/Compiler.java | 5 | ||||
-rw-r--r-- | src/main/javassist/reflect/Reflection.java | 5 | ||||
-rw-r--r-- | src/main/javassist/rmi/StubGenerator.java | 10 | ||||
-rw-r--r-- | src/main/javassist/web/Webserver.java | 4 |
9 files changed, 88 insertions, 99 deletions
diff --git a/src/main/javassist/ClassPath.java b/src/main/javassist/ClassPath.java index e249272b..15236f88 100644 --- a/src/main/javassist/ClassPath.java +++ b/src/main/javassist/ClassPath.java @@ -23,7 +23,7 @@ import java.net.URL; * 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) @@ -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 diff --git a/src/main/javassist/ClassPool.java b/src/main/javassist/ClassPool.java index cd239522..c6a13d63 100644 --- a/src/main/javassist/ClassPool.java +++ b/src/main/javassist/ClassPool.java @@ -20,53 +20,13 @@ import java.net.URL; 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> * @@ -74,14 +34,22 @@ import java.util.Hashtable; * 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 { @@ -108,9 +76,17 @@ 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() */ @@ -148,7 +124,6 @@ public class ClassPool { * <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 */ diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index 1b9f14d8..bfca85fa 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -843,7 +843,7 @@ public abstract class CtClass { * * @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() @@ -859,7 +859,7 @@ public abstract class CtClass { * 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); diff --git a/src/main/javassist/Loader.java b/src/main/javassist/Loader.java index a8e80230..d8ee1ccf 100644 --- a/src/main/javassist/Loader.java +++ b/src/main/javassist/Loader.java @@ -20,7 +20,7 @@ import java.util.Hashtable; 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 @@ -61,7 +61,7 @@ import java.util.Vector; * </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>, ... * @@ -74,20 +74,20 @@ import java.util.Vector; * <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> * @@ -128,8 +128,8 @@ import java.util.Vector; * @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; @@ -212,8 +212,7 @@ public class Loader extends ClassLoader { * @param t a translator. */ public void addTranslator(ClassPool cp, Translator t) - throws NotFoundException, CannotCompileException - { + throws NotFoundException, CannotCompileException { source = cp; translator = t; t.start(cp); @@ -269,8 +268,9 @@ public class Loader extends ClassLoader { 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(); @@ -281,8 +281,7 @@ public class Loader extends ClassLoader { * 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); @@ -310,11 +309,10 @@ public class Loader extends ClassLoader { 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"; @@ -327,13 +325,13 @@ public class Loader extends ClassLoader { 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 @@ -359,8 +357,10 @@ public class Loader extends ClassLoader { 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); diff --git a/src/main/javassist/Translator.java b/src/main/javassist/Translator.java index 8380fe8a..a673b0b0 100644 --- a/src/main/javassist/Translator.java +++ b/src/main/javassist/Translator.java @@ -22,7 +22,7 @@ package javassist; * <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 { /** @@ -38,13 +38,22 @@ public interface Translator { /** * 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; } diff --git a/src/main/javassist/reflect/Compiler.java b/src/main/javassist/reflect/Compiler.java index 6ab55583..3b5b1f70 100644 --- a/src/main/javassist/reflect/Compiler.java +++ b/src/main/javassist/reflect/Compiler.java @@ -122,9 +122,8 @@ public class Compiler { } 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(); } } diff --git a/src/main/javassist/reflect/Reflection.java b/src/main/javassist/reflect/Reflection.java index 44477ee9..1405d9b3 100644 --- a/src/main/javassist/reflect/Reflection.java +++ b/src/main/javassist/reflect/Reflection.java @@ -91,7 +91,7 @@ public class Reflection implements Translator { } /** - * Initializes. + * Initializes the object. */ public void start(ClassPool pool) throws NotFoundException { classPool = pool; @@ -115,9 +115,10 @@ public class Reflection implements Translator { * 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); } diff --git a/src/main/javassist/rmi/StubGenerator.java b/src/main/javassist/rmi/StubGenerator.java index 638acd45..76c99e5e 100644 --- a/src/main/javassist/rmi/StubGenerator.java +++ b/src/main/javassist/rmi/StubGenerator.java @@ -62,7 +62,8 @@ public class StubGenerator implements Translator { } /** - * Is a method declared in javassist.Translator. + * Initializes the object. + * This is a method declared in javassist.Translator. * * @see javassist.Translator#start(ClassPool) */ @@ -82,7 +83,12 @@ public class StubGenerator implements Translator { = new CtClass[] { pool.get("javassist.rmi.RemoteException") }; } - public void onWrite(ClassPool pool, CtClass clazz) {} + /** + * Does nothing. + * This is a method declared in javassist.Translator. + * @see javassist.Translator#onLoad(ClassPool,String) + */ + public void onLoad(ClassPool pool, String classname) {} /** * Returns <code>true</code> if the specified class is a proxy class diff --git a/src/main/javassist/web/Webserver.java b/src/main/javassist/web/Webserver.java index 120646e2..ad1adc77 100644 --- a/src/main/javassist/web/Webserver.java +++ b/src/main/javassist/web/Webserver.java @@ -337,10 +337,10 @@ public class Webserver { String classname = filename.substring(0, length - 6).replace('/', '.'); try { - CtClass c = classPool.get(classname); if (translator != null) - translator.onWrite(classPool, c); + translator.onLoad(classPool, classname); + CtClass c = classPool.get(classname); classfile = c.toBytecode(); if (debugDir != null) c.writeFile(debugDir); |