aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2004-04-16 15:12:45 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2004-04-16 15:12:45 +0000
commita5ddd6104e99fa22a5b1c36f5e3e585400b6e4c7 (patch)
tree8ae21fb63c94b9e58874377a5da414310f807a3c /src
parentf480c5d9122f26f32fa89f44ea7d606fd3df8557 (diff)
downloadjavassist-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.java3
-rw-r--r--src/main/javassist/ClassPool.java81
-rw-r--r--src/main/javassist/CtClass.java4
-rw-r--r--src/main/javassist/Loader.java58
-rw-r--r--src/main/javassist/Translator.java17
-rw-r--r--src/main/javassist/reflect/Compiler.java5
-rw-r--r--src/main/javassist/reflect/Reflection.java5
-rw-r--r--src/main/javassist/rmi/StubGenerator.java10
-rw-r--r--src/main/javassist/web/Webserver.java4
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);