aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sample/evolve/DemoLoader.java2
-rw-r--r--sample/evolve/DemoServer.java1
-rw-r--r--sample/evolve/Evolution.java309
-rw-r--r--sample/evolve/VersionManager.java116
-rw-r--r--sample/reflect/Main.java11
-rw-r--r--sample/reflect/Person.java54
-rw-r--r--sample/reflect/VerboseMetaobj.java22
7 files changed, 249 insertions, 266 deletions
diff --git a/sample/evolve/DemoLoader.java b/sample/evolve/DemoLoader.java
index f1474a1f..7c770bd5 100644
--- a/sample/evolve/DemoLoader.java
+++ b/sample/evolve/DemoLoader.java
@@ -1,8 +1,6 @@
package sample.evolve;
import javassist.*;
-import java.io.*;
-import java.util.Hashtable;
/**
* DemoLoader is a class loader for running a program including
diff --git a/sample/evolve/DemoServer.java b/sample/evolve/DemoServer.java
index 943c509c..d69d055f 100644
--- a/sample/evolve/DemoServer.java
+++ b/sample/evolve/DemoServer.java
@@ -1,6 +1,5 @@
package sample.evolve;
-import javassist.*;
import javassist.web.*;
import java.io.*;
diff --git a/sample/evolve/Evolution.java b/sample/evolve/Evolution.java
index 110e9332..ecae0921 100644
--- a/sample/evolve/Evolution.java
+++ b/sample/evolve/Evolution.java
@@ -1,202 +1,189 @@
package sample.evolve;
import javassist.*;
-import java.io.IOException;
/**
* Evolution provides a set of methods for instrumenting bytecodes.
- *
- * For class evolution, updatable class A is renamed to B. Then an
- * abstract class named A is produced as the super class of B. If the
- * original class A has a public method m(), then the abstract class A
- * has an abstract method m().
- *
- * abstract class A
- * abstract m()
- * _makeInstance()
- * |
- * class A --------> class B
- * m() m()
- *
- * Also, all the other classes are translated so that "new A(i)"
- * in the methods is replaced with "_makeInstance(i)". This makes
- * it possible to change the behavior of the instantiation of
- * the class A.
+ *
+ * For class evolution, updatable class A is renamed to B. Then an abstract
+ * class named A is produced as the super class of B. If the original class A
+ * has a public method m(), then the abstract class A has an abstract method
+ * m().
+ *
+ * abstract class A abstract m() _makeInstance() | class A --------> class B m()
+ * m()
+ *
+ * Also, all the other classes are translated so that "new A(i)" in the methods
+ * is replaced with "_makeInstance(i)". This makes it possible to change the
+ * behavior of the instantiation of the class A.
*/
public class Evolution implements Translator {
public final static String handlerMethod = "_makeInstance";
- public final static String latestVersionField
- = VersionManager.latestVersionField;
+
+ public final static String latestVersionField = VersionManager.latestVersionField;
+
public final static String versionManagerMethod = "initialVersion";
private static CtMethod trapMethod;
+
private static final int initialVersion = 0;
+
private ClassPool pool;
+
private String updatableClassName = null;
+
private CtClass updatableClass = null;
public void start(ClassPool _pool) throws NotFoundException {
- pool = _pool;
+ pool = _pool;
- // Get the definition of Sample.make() and store it into trapMethod
- // for later use.
- trapMethod = _pool.getMethod("sample.evolve.Sample", "make");
+ // Get the definition of Sample.make() and store it into trapMethod
+ // for later use.
+ trapMethod = _pool.getMethod("sample.evolve.Sample", "make");
}
public void onLoad(ClassPool _pool, String classname)
- throws NotFoundException, CannotCompileException
- {
- 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);
+ throws NotFoundException, CannotCompileException {
+ 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 onLoadUpdatable(String classname)
- throws NotFoundException, CannotCompileException
- {
- // if the class is a concrete class,
- // classname is <updatableClassName>$<version>.
-
- int i = classname.lastIndexOf('$');
- if (i <= 0)
- return;
-
- String orgname = classname.substring(0, i);
- if (!orgname.equals(updatableClassName))
- return;
-
- int version;
- try {
- version = Integer.parseInt(classname.substring(i + 1));
- }
- catch (NumberFormatException e) {
- throw new NotFoundException(classname, e);
- }
-
- CtClass clazz = pool.getAndRename(orgname, classname);
- makeConcreteClass(clazz, updatableClass, version);
+ private void onLoadUpdatable(String classname) throws NotFoundException,
+ CannotCompileException {
+ // if the class is a concrete class,
+ // classname is <updatableClassName>$<version>.
+
+ int i = classname.lastIndexOf('$');
+ if (i <= 0)
+ return;
+
+ String orgname = classname.substring(0, i);
+ if (!orgname.equals(updatableClassName))
+ return;
+
+ int version;
+ try {
+ version = Integer.parseInt(classname.substring(i + 1));
+ }
+ catch (NumberFormatException e) {
+ throw new NotFoundException(classname, e);
+ }
+
+ CtClass clazz = pool.getAndRename(orgname, classname);
+ makeConcreteClass(clazz, updatableClass, version);
}
- /* Register an updatable class.
+ /*
+ * Register an updatable class.
*/
- public void makeUpdatable(String classname)
- throws NotFoundException, CannotCompileException
- {
- if (pool == null)
- throw new RuntimeException(
- "Evolution has not been linked to ClassPool.");
-
- CtClass c = pool.get(classname);
- updatableClassName = classname;
- updatableClass = makeAbstractClass(c);
+ public void makeUpdatable(String classname) throws NotFoundException,
+ CannotCompileException {
+ if (pool == null)
+ throw new RuntimeException(
+ "Evolution has not been linked to ClassPool.");
+
+ CtClass c = pool.get(classname);
+ updatableClassName = classname;
+ updatableClass = makeAbstractClass(c);
}
/**
* Produces an abstract class.
*/
protected CtClass makeAbstractClass(CtClass clazz)
- throws CannotCompileException, NotFoundException
- {
- int i;
-
- CtClass absClass = pool.makeClass(clazz.getName());
- absClass.setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT);
- absClass.setSuperclass(clazz.getSuperclass());
- absClass.setInterfaces(clazz.getInterfaces());
-
- // absClass.inheritAllConstructors();
-
- CtField fld = new CtField(pool.get("java.lang.Class"),
- latestVersionField, absClass);
- fld.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
-
- CtField.Initializer finit
- = CtField.Initializer.byCall(
- pool.get("sample.evolve.VersionManager"),
- versionManagerMethod,
- new String[] { clazz.getName() });
- absClass.addField(fld, finit);
-
- CtField[] fs = clazz.getDeclaredFields();
- for (i = 0; i < fs.length; ++i) {
- CtField f = fs[i];
- if (Modifier.isPublic(f.getModifiers()))
- absClass.addField(new CtField(f.getType(), f.getName(),
- absClass));
- }
-
- CtConstructor[] cs = clazz.getDeclaredConstructors();
- for (i = 0; i < cs.length; ++i) {
- CtConstructor c = cs[i];
- int mod = c.getModifiers();
- if (Modifier.isPublic(mod)) {
- CtMethod wm
- = CtNewMethod.wrapped(absClass, handlerMethod,
- c.getParameterTypes(),
- c.getExceptionTypes(),
- trapMethod, null, absClass);
- wm.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
- absClass.addMethod(wm);
- }
- }
-
- CtMethod[] ms = clazz.getDeclaredMethods();
- for (i = 0; i < ms.length; ++i) {
- CtMethod m = ms[i];
- int mod = m.getModifiers();
- if (Modifier.isPublic(mod))
- if (Modifier.isStatic(mod))
- throw new CannotCompileException(
- "static methods are not supported.");
- else {
- CtMethod m2
- = CtNewMethod.abstractMethod(m.getReturnType(),
- m.getName(),
- m.getParameterTypes(),
- m.getExceptionTypes(),
- absClass);
- absClass.addMethod(m2);
- }
- }
-
- return absClass;
+ throws CannotCompileException, NotFoundException {
+ int i;
+
+ CtClass absClass = pool.makeClass(clazz.getName());
+ absClass.setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT);
+ absClass.setSuperclass(clazz.getSuperclass());
+ absClass.setInterfaces(clazz.getInterfaces());
+
+ // absClass.inheritAllConstructors();
+
+ CtField fld = new CtField(pool.get("java.lang.Class"),
+ latestVersionField, absClass);
+ fld.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
+
+ CtField.Initializer finit = CtField.Initializer.byCall(pool
+ .get("sample.evolve.VersionManager"), versionManagerMethod,
+ new String[] { clazz.getName() });
+ absClass.addField(fld, finit);
+
+ CtField[] fs = clazz.getDeclaredFields();
+ for (i = 0; i < fs.length; ++i) {
+ CtField f = fs[i];
+ if (Modifier.isPublic(f.getModifiers()))
+ absClass.addField(new CtField(f.getType(), f.getName(),
+ absClass));
+ }
+
+ CtConstructor[] cs = clazz.getDeclaredConstructors();
+ for (i = 0; i < cs.length; ++i) {
+ CtConstructor c = cs[i];
+ int mod = c.getModifiers();
+ if (Modifier.isPublic(mod)) {
+ CtMethod wm = CtNewMethod.wrapped(absClass, handlerMethod, c
+ .getParameterTypes(), c.getExceptionTypes(),
+ trapMethod, null, absClass);
+ wm.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
+ absClass.addMethod(wm);
+ }
+ }
+
+ CtMethod[] ms = clazz.getDeclaredMethods();
+ for (i = 0; i < ms.length; ++i) {
+ CtMethod m = ms[i];
+ int mod = m.getModifiers();
+ if (Modifier.isPublic(mod))
+ if (Modifier.isStatic(mod))
+ throw new CannotCompileException(
+ "static methods are not supported.");
+ else {
+ CtMethod m2 = CtNewMethod.abstractMethod(m.getReturnType(),
+ m.getName(), m.getParameterTypes(), m
+ .getExceptionTypes(), absClass);
+ absClass.addMethod(m2);
+ }
+ }
+
+ return absClass;
}
/**
- * Modifies the given class file so that it is a subclass of the
- * abstract class produced by makeAbstractClass().
- *
+ * Modifies the given class file so that it is a subclass of the abstract
+ * class produced by makeAbstractClass().
+ *
* Note: the naming convention must be consistent with
* VersionManager.update().
*/
- protected void makeConcreteClass(CtClass clazz,
- CtClass abstractClass, int version)
- throws CannotCompileException, NotFoundException
- {
- int i;
- clazz.setSuperclass(abstractClass);
- CodeConverter converter = new CodeConverter();
- CtField[] fs = clazz.getDeclaredFields();
- for (i = 0; i < fs.length; ++i) {
- CtField f = fs[i];
- if (Modifier.isPublic(f.getModifiers()))
- converter.redirectFieldAccess(f, abstractClass, f.getName());
- }
-
- CtConstructor[] cs = clazz.getDeclaredConstructors();
- for (i = 0; i < cs.length; ++i)
- cs[i].instrument(converter);
-
- CtMethod[] ms = clazz.getDeclaredMethods();
- for (i = 0; i < ms.length; ++i)
- ms[i].instrument(converter);
+ protected void makeConcreteClass(CtClass clazz, CtClass abstractClass,
+ int version) throws CannotCompileException, NotFoundException {
+ int i;
+ clazz.setSuperclass(abstractClass);
+ CodeConverter converter = new CodeConverter();
+ CtField[] fs = clazz.getDeclaredFields();
+ for (i = 0; i < fs.length; ++i) {
+ CtField f = fs[i];
+ if (Modifier.isPublic(f.getModifiers()))
+ converter.redirectFieldAccess(f, abstractClass, f.getName());
+ }
+
+ CtConstructor[] cs = clazz.getDeclaredConstructors();
+ for (i = 0; i < cs.length; ++i)
+ cs[i].instrument(converter);
+
+ CtMethod[] ms = clazz.getDeclaredMethods();
+ for (i = 0; i < ms.length; ++i)
+ ms[i].instrument(converter);
}
}
diff --git a/sample/evolve/VersionManager.java b/sample/evolve/VersionManager.java
index d95268b8..184397fd 100644
--- a/sample/evolve/VersionManager.java
+++ b/sample/evolve/VersionManager.java
@@ -2,89 +2,89 @@ package sample.evolve;
import java.util.Hashtable;
import java.lang.reflect.*;
-import javassist.CtClass;
/**
* Runtime system for class evolution
*/
public class VersionManager {
private static Hashtable versionNo = new Hashtable();
+
public final static String latestVersionField = "_version";
/**
* For updating the definition of class my.X, say:
- *
+ *
* VersionManager.update("my.X");
*/
public static void update(String qualifiedClassname)
- throws CannotUpdateException
- {
- try {
- Class c = getUpdatedClass(qualifiedClassname);
- Field f = c.getField(latestVersionField);
- f.set(null, c);
- }
- catch (ClassNotFoundException e) {
- throw new CannotUpdateException("cannot update class: "
- + qualifiedClassname);
- }
- catch (Exception e) {
- throw new CannotUpdateException(e);
- }
+ throws CannotUpdateException {
+ try {
+ Class c = getUpdatedClass(qualifiedClassname);
+ Field f = c.getField(latestVersionField);
+ f.set(null, c);
+ }
+ catch (ClassNotFoundException e) {
+ throw new CannotUpdateException("cannot update class: "
+ + qualifiedClassname);
+ }
+ catch (Exception e) {
+ throw new CannotUpdateException(e);
+ }
}
private static Class getUpdatedClass(String qualifiedClassname)
- throws ClassNotFoundException
- {
- int version;
- Object found = versionNo.get(qualifiedClassname);
- if (found == null)
- version = 0;
- else
- version = ((Integer)found).intValue() + 1;
+ throws ClassNotFoundException {
+ int version;
+ Object found = versionNo.get(qualifiedClassname);
+ if (found == null)
+ version = 0;
+ else
+ version = ((Integer)found).intValue() + 1;
- Class c = Class.forName(qualifiedClassname + '$' + version);
- versionNo.put(qualifiedClassname, new Integer(version));
- return c;
+ Class c = Class.forName(qualifiedClassname + '$' + version);
+ versionNo.put(qualifiedClassname, new Integer(version));
+ return c;
}
- /* initiaVersion() is used to initialize the _version field of
- * the updatable classes.
+ /*
+ * initiaVersion() is used to initialize the _version field of the updatable
+ * classes.
*/
public static Class initialVersion(String[] params) {
- try {
- return getUpdatedClass(params[0]);
- }
- catch (ClassNotFoundException e) {
- throw new RuntimeException("cannot initialize " + params[0]);
- }
+ try {
+ return getUpdatedClass(params[0]);
+ }
+ catch (ClassNotFoundException e) {
+ throw new RuntimeException("cannot initialize " + params[0]);
+ }
}
- /** make() performs the object creation of the updatable classes.
- * The expression "new <updatable class>" is replaced with a call
- * to this method.
+ /**
+ * make() performs the object creation of the updatable classes. The
+ * expression "new <updatable class>" is replaced with a call to this
+ * method.
*/
public static Object make(Class clazz, Object[] args) {
- Constructor[] constructors = clazz.getConstructors();
- int n = constructors.length;
- for (int i = 0; i < n; ++i) {
- try {
- return constructors[i].newInstance(args);
- }
- catch (IllegalArgumentException e) {
- // try again
- }
- catch (InstantiationException e) {
- throw new CannotCreateException(e);
- }
- catch (IllegalAccessException e) {
- throw new CannotCreateException(e);
- }
- catch (InvocationTargetException e) {
- throw new CannotCreateException(e);
- }
- }
+ Constructor[] constructors = clazz.getConstructors();
+ int n = constructors.length;
+ for (int i = 0; i < n; ++i) {
+ try {
+ return constructors[i].newInstance(args);
+ }
+ catch (IllegalArgumentException e) {
+ // try again
+ }
+ catch (InstantiationException e) {
+ throw new CannotCreateException(e);
+ }
+ catch (IllegalAccessException e) {
+ throw new CannotCreateException(e);
+ }
+ catch (InvocationTargetException e) {
+ throw new CannotCreateException(e);
+ }
+ }
- throw new CannotCreateException("no constructor matches");
+ throw new CannotCreateException("no constructor matches");
}
}
diff --git a/sample/reflect/Main.java b/sample/reflect/Main.java
index 6086d9f8..d9733abc 100644
--- a/sample/reflect/Main.java
+++ b/sample/reflect/Main.java
@@ -1,6 +1,5 @@
package sample.reflect;
-import javassist.reflect.ClassMetaobject;
import javassist.reflect.Loader;
/*
@@ -23,11 +22,11 @@ import javassist.reflect.Loader;
*/
public class Main {
public static void main(String[] args) throws Throwable {
- Loader cl = (Loader)Main.class.getClassLoader();
- cl.makeReflective("sample.reflect.Person",
- "sample.reflect.VerboseMetaobj",
- "javassist.reflect.ClassMetaobject");
+ Loader cl = (Loader)Main.class.getClassLoader();
+ cl.makeReflective("sample.reflect.Person",
+ "sample.reflect.VerboseMetaobj",
+ "javassist.reflect.ClassMetaobject");
- cl.run("sample.reflect.Person", args);
+ cl.run("sample.reflect.Person", args);
}
}
diff --git a/sample/reflect/Person.java b/sample/reflect/Person.java
index 5e0e2ad8..445d3807 100644
--- a/sample/reflect/Person.java
+++ b/sample/reflect/Person.java
@@ -1,6 +1,6 @@
/*
- A base-level class controlled by VerboseMetaobj.
-*/
+ * A base-level class controlled by VerboseMetaobj.
+ */
package sample.reflect;
@@ -9,43 +9,45 @@ import javassist.reflect.Metaobject;
public class Person {
public String name;
+
public static int birth = 3;
+
public static final String defaultName = "John";
public Person(String name, int birthYear) {
- if (name == null)
- this.name = defaultName;
- else
- this.name = name;
+ if (name == null)
+ this.name = defaultName;
+ else
+ this.name = name;
- this.birth = birthYear;
+ birth = birthYear;
}
public String getName() {
- return name;
+ return name;
}
public int getAge(int year) {
- return year - birth;
+ return year - birth;
}
public static void main(String[] args) {
- String name;
- if (args.length > 0)
- name = args[0];
- else
- name = "Bill";
-
- Person p = new Person(name, 1960);
- System.out.println("name: " + p.getName());
- System.out.println("object: " + p.toString());
-
- // change the metaobject of p.
- if (p instanceof Metalevel) {
- ((Metalevel)p)._setMetaobject(new Metaobject(p, null));
- System.out.println("<< the metaobject was changed.>>");
- }
-
- System.out.println("age: " + p.getAge(1999));
+ String name;
+ if (args.length > 0)
+ name = args[0];
+ else
+ name = "Bill";
+
+ Person p = new Person(name, 1960);
+ System.out.println("name: " + p.getName());
+ System.out.println("object: " + p.toString());
+
+ // change the metaobject of p.
+ if (p instanceof Metalevel) {
+ ((Metalevel)p)._setMetaobject(new Metaobject(p, null));
+ System.out.println("<< the metaobject was changed.>>");
+ }
+
+ System.out.println("age: " + p.getAge(1999));
}
}
diff --git a/sample/reflect/VerboseMetaobj.java b/sample/reflect/VerboseMetaobj.java
index a9f75dd1..91dba579 100644
--- a/sample/reflect/VerboseMetaobj.java
+++ b/sample/reflect/VerboseMetaobj.java
@@ -1,29 +1,27 @@
package sample.reflect;
-import javassist.*;
import javassist.reflect.*;
public class VerboseMetaobj extends Metaobject {
public VerboseMetaobj(Object self, Object[] args) {
- super(self, args);
- System.out.println("** constructed: " + self.getClass().getName());
+ super(self, args);
+ System.out.println("** constructed: " + self.getClass().getName());
}
public Object trapFieldRead(String name) {
- System.out.println("** field read: " + name);
- return super.trapFieldRead(name);
+ System.out.println("** field read: " + name);
+ return super.trapFieldRead(name);
}
public void trapFieldWrite(String name, Object value) {
- System.out.println("** field write: " + name);
- super.trapFieldWrite(name, value);
+ System.out.println("** field write: " + name);
+ super.trapFieldWrite(name, value);
}
public Object trapMethodcall(int identifier, Object[] args)
- throws Throwable
- {
- System.out.println("** trap: " + getMethodName(identifier)
- + "() in " + getClassMetaobject().getName());
- return super.trapMethodcall(identifier, args);
+ throws Throwable {
+ System.out.println("** trap: " + getMethodName(identifier) + "() in "
+ + getClassMetaobject().getName());
+ return super.trapMethodcall(identifier, args);
}
}