aboutsummaryrefslogtreecommitdiffstats
path: root/src/test/javassist/JvstTest.java
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2011-08-31 10:29:34 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2011-08-31 10:29:34 +0000
commitd72870bfb6b09927e10944bdd129ce18dfcf7366 (patch)
tree27f56e4d1523a8cecc8976df60155e6b8429e504 /src/test/javassist/JvstTest.java
parent76a1cba9c433e8242bb6648e72b3ed43c7a4995a (diff)
downloadjavassist-d72870bfb6b09927e10944bdd129ce18dfcf7366.tar.gz
javassist-d72870bfb6b09927e10944bdd129ce18dfcf7366.zip
JvstTest test case.
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@589 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/test/javassist/JvstTest.java')
-rw-r--r--src/test/javassist/JvstTest.java1123
1 files changed, 1123 insertions, 0 deletions
diff --git a/src/test/javassist/JvstTest.java b/src/test/javassist/JvstTest.java
new file mode 100644
index 00000000..92154b38
--- /dev/null
+++ b/src/test/javassist/JvstTest.java
@@ -0,0 +1,1123 @@
+package javassist;
+
+import junit.framework.*;
+import java.io.FileInputStream;
+import java.lang.reflect.Method;
+import javassist.bytecode.*;
+import javassist.expr.*;
+import javassist.runtime.*;
+
+public class JvstTest extends JvstTestRoot {
+ static {
+ //javassist.bytecode.MethodInfo.doPreverify = true;
+ }
+ public JvstTest(String name) {
+ super(name);
+ }
+
+ public void testConfig() {
+ // is the value of PATH correct?
+ assertTrue("not found " + PATH, new java.io.File(PATH).exists());
+ }
+
+ public void testLoader() throws Exception {
+ Loader loader = new Loader(sloader);
+ loader.delegateLoadingOf("test1.");
+ assertEquals(loader.loadClass("test1.Cflow").getClassLoader(),
+ loader.getParent());
+ assertEquals(loader.loadClass("javassist.Loader").getClassLoader(),
+ loader.getParent());
+ assertEquals(loader.loadClass("javassist.CtClass").getClassLoader(),
+ loader);
+ }
+
+ public void testDefreeze() throws Exception {
+ CtClass cc = sloader.get("test1.Freeze");
+ cc.stopPruning(true);
+ cc.addInterface(sloader.get("java.io.Serializable"));
+ assertTrue(!cc.isFrozen());
+ cc.writeFile();
+ assertTrue(cc.isFrozen());
+ cc.defrost();
+ assertTrue(!cc.isFrozen());
+ }
+
+ public void testClassPath() throws Exception {
+ ClassPool pool = new ClassPool(null);
+ ClassPath cp1 = pool.appendClassPath("d1");
+ ClassPath cp2 = pool.appendClassPath("d2");
+ ClassPath cp3 = pool.appendClassPath("d3");
+ ClassPath cp4 = pool.appendClassPath("d4");
+ print(pool.toString());
+ pool.removeClassPath(cp3);
+ print(pool.toString());
+ pool.removeClassPath(cp4);
+ print(pool.toString());
+ pool.removeClassPath(cp2);
+ print(pool.toString());
+ pool.removeClassPath(cp1);
+ assertTrue("[class path: ]".equals(pool.toString()));
+ }
+
+ public void testSubtype() throws Exception {
+ CtClass cc = sloader.get("test1.Subtype");
+ assertTrue(cc.subtypeOf(cc));
+ assertTrue(cc.subtypeOf(sloader.get("test1.SubtypeA")));
+ assertTrue(cc.subtypeOf(sloader.get("test1.SubtypeB")));
+ assertTrue(cc.subtypeOf(sloader.get("test1.SubtypeC")));
+ assertTrue(cc.subtypeOf(sloader.get("java.lang.Object")));
+ assertTrue(!cc.subtypeOf(sloader.get("java.lang.String")));
+ }
+
+ public void testClassPoolGet() throws Exception {
+ ClassPool pool = ClassPool.getDefault();
+ CtClass cc = pool.makeClass("test1.Point");
+ CtClass cc1 = pool.get("test1.Point"); // cc1 is identical to cc.
+ cc.setName("test1.Pair");
+ CtClass cc2 = pool.get("test1.Pair"); // cc2 is identical to cc.
+ CtClass cc3 = pool.get("test1.Point"); // cc3 is not identical to cc.
+
+ assertTrue(cc == cc1);
+ assertTrue(cc == cc2);
+ assertTrue(cc != cc3);
+
+ assertEquals("test1.Pair", cc.getName());
+ assertEquals("test1.Point", cc3.getName());
+ }
+
+ public static long testFieldInitHash;
+
+ /* test CodeIterator.insertExGap().
+ * The result of this test is checked again by JvstTest3#testFieldInitAgain().
+ */
+ public void testFieldInit() throws Exception {
+ CtClass cc = sloader.get("test1.FieldInit");
+ CtField f1 = new CtField(CtClass.intType, "f1", cc);
+ cc.addField(f1, CtField.Initializer.byCall(cc, "get"));
+ CtField f2 = CtField.make("public int f2 = 3;", cc);
+ cc.addField(f2);
+ CtField f3 = CtField.make("public int f3;", cc);
+ cc.addField(f3);
+ testFieldInitHash = f1.hashCode();
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ int value = obj.getClass().getField("counter").getInt(obj);
+ assertEquals(1, value);
+ int value2 = obj.getClass().getField("f2").getInt(obj);
+ assertEquals(3, value2);
+ int value3 = obj.getClass().getField("f3").getInt(obj);
+ assertEquals(0, value3);
+ }
+
+ /* test CodeIterator.insertExGap().
+ */
+ public void testFieldInit2() throws Exception {
+ CtClass cc = sloader.get("test1.FieldInit2");
+ CtField f = new CtField(CtClass.intType, "f1", cc);
+ cc.addField(f, CtField.Initializer.byCall(cc, "get"));
+ cc.writeFile();
+ try {
+ Object obj = make(cc.getName());
+ fail();
+ }
+ catch (Exception e) {
+ print("testFieldInit2: catch");
+ }
+ }
+
+ public static CtMethod testCalleeBeforeMethod;
+ public static long testCalleeBeforeMethod2;
+
+ /* The test result is checked again by JvstTest3#testCalleeBeforeAgain().
+ */
+ public void testCalleeBefore() throws Exception {
+ CtClass cc = sloader.get("test1.CalleeBefore");
+
+ CtMethod m1 = cc.getDeclaredMethod("m1");
+ m1.insertBefore("{ int k = 1; p = k; }");
+ CtMethod m2 = cc.getDeclaredMethod("m2");
+ testCalleeBeforeMethod = m1;
+ testCalleeBeforeMethod2 = m2.getMethodInfo2().hashCode();
+ m2.insertBefore("{ int k = 3; q = k; }");
+ CtConstructor[] cons = cc.getDeclaredConstructors();
+
+ for (int i = 0; i < cons.length; ++i) {
+ MethodInfo minfo = cons[i].getMethodInfo();
+ CodeAttribute ca = minfo.getCodeAttribute();
+ CodeIterator iterator = ca.iterator();
+ if (cons[i].getParameterTypes().length == 0) {
+ assertTrue(iterator.skipThisConstructor() >= 0);
+ assertTrue(iterator.skipSuperConstructor() < 0);
+ assertTrue(iterator.skipConstructor() >= 0);
+ }
+ else {
+ assertTrue(iterator.skipThisConstructor() < 0);
+ assertTrue(iterator.skipSuperConstructor() >= 0);
+ assertTrue(iterator.skipConstructor() >= 0);
+ }
+
+ cons[i].insertBeforeBody("{ int k = 1; counter += k; }");
+ }
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(0, invoke(obj, "getr"));
+ assertEquals(17, invoke(obj, "test"));
+ }
+
+ public void testCalleeAfter() throws Exception {
+ CtClass cc = sloader.get("test1.CalleeAfter");
+
+ CtMethod m1 = cc.getDeclaredMethod("m1");
+ m1.insertAfter("{ int k = 1; $_ = $_ + k; }", false);
+
+ CtMethod m2 = cc.getDeclaredMethod("m2");
+ m2.insertAfter("{ char k = 1; $_ = $_ + k; }", false);
+
+ CtConstructor[] cons = cc.getDeclaredConstructors();
+ cons[0].insertAfter("{ ++p; $_ = ($r)null; }", false);
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(15, invoke(obj, "test"));
+ }
+
+ public void testCalleeAfter2() throws Exception {
+ CtClass cc = sloader.get("test1.CalleeAfter2");
+
+ CtMethod m1 = cc.getDeclaredMethod("m1");
+ m1.insertAfter("$_ = 7; $_ = ($r)k1(0);", false);
+
+ CtMethod m2 = cc.getDeclaredMethod("m2");
+ m2.insertAfter("$_ = ($r)k2(0);", false);
+
+ CtMethod m3 = cc.getDeclaredMethod("m3");
+ m3.insertAfter("$_ = ($r)k3(0);", false);
+
+ CtMethod m4 = cc.getDeclaredMethod("m4");
+ try {
+ m4.insertAfter("$_ = ($r)1;", false);
+ assertTrue(false);
+ }
+ catch (CannotCompileException e) {
+ }
+
+ CtMethod m5 = cc.getDeclaredMethod("m5");
+ m5.insertAfter("$_ = ($r)k5(0);", false);
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(17, invoke(obj, "test"));
+ }
+
+ public void testCalleeAfter3() throws Exception {
+ CtClass cc = sloader.get("test1.CalleeAfter3");
+ CtMethod m1 = cc.getDeclaredMethod("m1");
+ m1.insertAfter("value++;", true);
+ CtMethod m2 = cc.getDeclaredMethod("m2");
+ m2.insertAfter("value++;", true);
+ CtMethod m3 = cc.getDeclaredMethod("m3");
+ m3.insertAfter("value++;", true);
+ CtMethod m4 = cc.getDeclaredMethod("m4");
+ m4.insertAfter("value++;", true);
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(22, invoke(obj, "test"));
+ }
+
+ public void testCalleeCatch() throws Exception {
+ CtClass cc = sloader.get("test1.CalleeCatch");
+
+ CtMethod m1 = cc.getDeclaredMethod("m1");
+ m1.addCatch("{ System.out.println($e); return p; }",
+ sloader.get("java.lang.Exception"));
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(3, invoke(obj, "test"));
+ }
+
+ public void testSuperclass() throws Exception {
+ CtClass cc = sloader.get("java.lang.Object");
+ assertEquals(null, cc.getSuperclass());
+ }
+
+ public void testProceed() throws Exception {
+ CtClass cc = sloader.get("test1.Proceed");
+
+ CtMethod m1 = CtNewMethod.make(
+ "public int m1() { return $proceed(3); }",
+ cc, "this", "k1");
+ CtMethod m2 = CtNewMethod.make(
+ "public int m2() { return $proceed(3); }",
+ cc, "another", "k2");
+ CtMethod m3 = CtNewMethod.make(
+ "public int q(int i) { return p($1 + 1, $$); }", cc);
+ cc.addMethod(m1);
+ cc.addMethod(m2);
+ cc.addMethod(m3);
+ CtMethod m4 = CtNewMethod.make(
+ "public int q2() { return q(4); }", cc);
+ cc.addMethod(m4);
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(3, invoke(obj, "m1"));
+ assertEquals(4, invoke(obj, "m2"));
+ assertEquals(9, invoke(obj, "q2"));
+ }
+
+ public void testProceed2() throws Exception {
+ CtClass cc = sloader.get("test1.Proceed2");
+ CtMethod m1 = cc.getDeclaredMethod("k1");
+ m1.instrument(new ExprEditor() {
+ public void edit(MethodCall m) throws CannotCompileException {
+ m.replace("{ $_ = $proceed($$); }");
+ }
+ public void edit(NewExpr m) throws CannotCompileException {
+ m.replace("{ $_ = $proceed($$); }");
+ }
+ public void edit(FieldAccess m) throws CannotCompileException {
+ m.replace("{ $_ = $proceed($$); }");
+ }
+ public void edit(Instanceof i) throws CannotCompileException {
+ i.replace("{ $_ = $proceed($$); }");
+ }
+ public void edit(Cast c) throws CannotCompileException {
+ c.replace("{ $_ = $proceed($$); }");
+ }
+ });
+
+ CtMethod m2 = cc.getDeclaredMethod("k2");
+ m2.instrument(new ExprEditor() {
+ public void edit(MethodCall m) throws CannotCompileException {
+ m.replace("{ $proceed(); }");
+ }
+ public void edit(NewExpr m) throws CannotCompileException {
+ m.replace("{ $_ = $proceed(); }");
+ }
+ public void edit(FieldAccess m) throws CannotCompileException {
+ if (m.isReader())
+ m.replace("{ $_ = $proceed(); }");
+ else
+ m.replace("{ $proceed($$); }");
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(2, invoke(obj, "k1"));
+ }
+
+ public void testProceed3() throws Exception {
+ CtClass cc = sloader.get("test1.Proceed3");
+ CtMethod m1 = cc.getDeclaredMethod("p");
+ CtMethod m2 = CtNewMethod.copy(m1, cc, null);
+ m1.setName(m1.getName() + "_orig");
+ m2.setBody("{ return $proceed($1 + 1); }", "this", m1.getName());
+ cc.addMethod(m2);
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(4, invoke(obj, "k1"));
+ }
+
+ public void testSetBody() throws Exception {
+ CtClass cc = sloader.get("test1.SetBody");
+ CtMethod m1 = cc.getDeclaredMethod("m1");
+ m1.setBody("{ int i = $1 * $2; return i; }");
+ CtMethod m2 = cc.getDeclaredMethod("m2");
+ m2.setBody("System.out.println(\"setbody: \" + $1);");
+
+ CtMethod m3 = cc.getDeclaredMethod("m3");
+ try {
+ m3.setBody("value = 1; System.out.println(\"setbody: \" + $1);");
+ fail();
+ }
+ catch (CannotCompileException e) {
+ // System.err.println(e);
+ }
+
+ CtConstructor cons
+ = new CtConstructor(new CtClass[] { CtClass.intType }, cc);
+ cons.setBody(null);
+ cc.addConstructor(cons);
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(12, invoke(obj, "run"));
+ }
+
+ public void testSetStaticConsBody() throws Exception {
+ CtClass cc = sloader.get("test1.StaticConsBody");
+ CtConstructor cons = cc.getClassInitializer();
+ cons.setBody(null);
+
+ cons = cc.getConstructors()[0];
+ cons.setBody(null);
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(0, invoke(obj, "run"));
+ }
+
+ public void testSetConsBody() throws Exception {
+ CtClass superClazz = sloader.get("java.io.File");
+ CtClass cc = sloader.makeClass("test1.SetConsBody");
+ cc.setSuperclass(superClazz);
+ CtConstructor constructor = new CtConstructor(new CtClass[0], cc);
+ constructor.setBody("super(\"MyFile\");");
+ cc.addConstructor(constructor);
+
+ constructor = new CtConstructor(new CtClass[] { CtClass.intType },
+ cc);
+ constructor.setBody("{ super(\"MyFile\"); }");
+ cc.addConstructor(constructor);
+
+ cc.addMethod(CtNewMethod.make(CtClass.voidType, "m1",
+ null, null, null, cc));
+ cc.addMethod(CtNewMethod.make(CtClass.intType, "m2",
+ null, null, null, cc));
+ cc.addMethod(CtNewMethod.make(CtClass.byteType, "m3",
+ null, null, null, cc));
+ cc.addMethod(CtNewMethod.make(CtClass.longType, "m4",
+ null, null, null, cc));
+ cc.addMethod(CtNewMethod.make(CtClass.floatType, "m5",
+ null, null, null, cc));
+ cc.addMethod(CtNewMethod.make(CtClass.doubleType, "m6",
+ null, null, null, cc));
+ cc.addMethod(CtNewMethod.make(sloader.get("int[]"), "m7",
+ null, null, null, cc));
+
+ cc.addMethod(CtNewMethod.make(
+ "public int run() {"
+ + " return (int)(m2() + m3() + m4() + m5() + m6() + 3); }", cc));
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(3, invoke(obj, "run"));
+ }
+
+ public void testEmptyBody() throws Exception {
+ String[] methods = { "m1", "m2", "m3", "m4" };
+ boolean[] results = { true, false, false, false, true };
+ boolean[] cResults = { true, true, false, false, false, true };
+
+ CtClass cc = sloader.get("test1.EmptyBody");
+ for (int i = 0; i < methods.length; ++i) {
+ CtMethod m = cc.getDeclaredMethod(methods[i]);
+ assertEquals(results[i], m.isEmpty());
+ }
+
+ CtConstructor[] cons = cc.getDeclaredConstructors();
+ for (int j = 0; j < cons.length; ++j)
+ assertEquals(cResults[j], cons[j].isEmpty());
+ }
+
+ public void testExprEditor() throws Exception {
+ CtClass cc = sloader.get("test1.ExprEdit");
+
+ CtMethod m1 = cc.getDeclaredMethod("k0");
+ m1.instrument(new ExprEditor() {
+ public void edit(MethodCall m) throws CannotCompileException {
+ if (m.getClassName().equals("test1.ExprEdit")) {
+ String name = m.getMethodName();
+ if (name.equals("k1") || name.equals("k2")) {
+ try {
+ CtMethod cm = m.getMethod();
+ print(cm.getParameterTypes()[0].getName());
+ print(cm.getReturnType().getName());
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ m.replace("{ ++$1; $_ = $proceed($$); }");
+ }
+ else if (name.equals("k3"))
+ m.replace("{ ++$1; $proceed($$); }");
+ }
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(12, invoke(obj, "k0"));
+ }
+
+ public void testExprEditor2() throws Exception {
+ CtClass cc = sloader.get("test1.ExprEdit2");
+
+ CtMethod m1 = cc.getDeclaredMethod("k1");
+ m1.instrument(new ExprEditor() {
+ public void edit(FieldAccess m) throws CannotCompileException {
+ if (m.getClassName().equals("test1.ExprEdit2")) {
+ String name = m.getFieldName();
+ try {
+ CtField cf = m.getField();
+ print(cf.getType().getName());
+ print("file: " + m.getFileName());
+ print("line: " + m.getLineNumber());
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ if (name.equals("df"))
+ if (m.isReader())
+ m.replace("{ $_ = $proceed() + 1; }");
+ else
+ m.replace("{ $proceed($1 + 1); }");
+ else if (name.equals("sf"))
+ if (m.isReader())
+ m.replace("{ $_ = $proceed() + 2; }");
+ else
+ m.replace("{ $proceed($1 + 2); }");
+ }
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(16, invoke(obj, "k1"));
+ }
+
+ public void testExprEditor3() throws Exception {
+ CtClass cc = sloader.get("test1.ExprEdit3");
+
+ CtMethod m1 = cc.getDeclaredMethod("k1");
+ m1.instrument(new ExprEditor() {
+ public void edit(NewExpr m) throws CannotCompileException {
+ System.out.println("new " + m.getClassName());
+ try {
+ CtConstructor cc = m.getConstructor();
+ print(cc.getParameterTypes()[0].getName());
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ if (m.getClassName().equals("test1.ExprEdit3")) {
+ m.replace("{ ++$2; $_ = $proceed($$); }");
+ }
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(4, invoke(obj, "k1"));
+ }
+
+ public void testExprEditor4() throws Exception {
+ CtClass cc = sloader.get("test1.ExprEdit4");
+
+ CtMethod m1 = cc.getDeclaredMethod("k1");
+ m1.instrument(new ExprEditor() {
+ public void edit(NewExpr m) throws CannotCompileException {
+ System.out.println("new " + m.getClassName());
+ if (m.getClassName().equals("test1.ExprEdit4"))
+ m.replace("$_ = null;");
+ }
+
+ public void edit(MethodCall m) throws CannotCompileException {
+ if (m.getClassName().equals("test1.ExprEdit4"))
+ m.replace("{}");
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(1, invoke(obj, "k1"));
+ }
+
+ public void testExprEditor5() throws Exception {
+ CtClass cc = sloader.get("test1.ExprEdit5");
+
+ CtMethod m1 = cc.getDeclaredMethod("k1");
+ m1.instrument(new ExprEditor() {
+ public void edit(NewExpr m) throws CannotCompileException {
+ m.replace("{ $_ = $proceed($$, \"test\"); }");
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(1, invoke(obj, "k1"));
+ }
+
+ public void testExprEditor6() throws Exception {
+ CtClass cc = sloader.get("test1.ExprEdit6");
+ cc.instrument(new ExprEditor() {
+ public void edit(MethodCall m) throws CannotCompileException {
+ assertTrue(m.where().getName().equals("k1"));
+ m.replace("$_ = 3;");
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(3, invoke(obj, "k1"));
+ }
+
+ public void testExprEditor7() throws Exception {
+ CtClass cc = sloader.get("test1.ExprEdit7");
+ cc.instrument(new ExprEditor() {
+ public void edit(Instanceof i) throws CannotCompileException {
+ i.replace("{ this.c1 = $type; $_ = !$proceed($1); }");
+ }
+ public void edit(Cast c) throws CannotCompileException {
+ c.replace("{ this.c2 = $type; $_ = ($r)$1; }");
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(7, invoke(obj, "k1"));
+ }
+
+ public void testExprEditor8() throws Exception {
+ CtClass cc = sloader.get("test1.ExprEdit8");
+ cc.instrument(new ExprEditor() {
+ public void edit(ConstructorCall c) throws CannotCompileException {
+ assertTrue(c.isSuper());
+ c.replace("{ $_ = $proceed($$); value = 7; }");
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(7, invoke(obj, "k1"));
+ }
+
+ public void testCflow() throws Exception {
+ CtClass cc = sloader.get("test1.Cflow");
+ CtMethod m1 = cc.getDeclaredMethod("k1");
+ m1.useCflow("cflow1");
+ m1.insertBefore("System.out.println(\"$cflow1: \" + $cflow(cflow1));");
+ m1.insertAfter("System.out.println(\"*$cflow1: \" + $cflow(cflow1));",
+ true);
+ CtMethod m2 = cc.getDeclaredMethod("k2");
+ m2.useCflow("test1.t.cflow2");
+ m2.insertBefore(
+ "System.out.println(\"$cflow2: \" + $cflow(test1.t.cflow2));");
+ CtMethod m3 = cc.getDeclaredMethod("fact");
+ m3.useCflow("fact");
+ m3.insertBefore("if ($cflow(fact) == 0)"
+ + " System.out.println(\"fact \" + $1);");
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(1, invoke(obj, "run"));
+ assertEquals(120, invoke(obj, "run2"));
+ }
+
+ public void testSigType() throws Exception {
+ CtClass cc = sloader.get("test1.SigType");
+
+ CtMethod m1 = cc.getDeclaredMethod("k1");
+ m1.insertBefore("{ Class[] p = $sig; $1 += p.length; }");
+ m1.insertAfter("System.out.println(\"testSigType: \""
+ + " + $type.getName());", false);
+
+ CtMethod m2 = cc.getDeclaredMethod("k2");
+ m2.instrument(new ExprEditor() {
+ public void edit(FieldAccess m) throws CannotCompileException {
+ m.replace("{ $_ = $proceed($$) + $type.getName().length(); }");
+ }
+
+ public void edit(MethodCall m) throws CannotCompileException {
+ m.replace("{ $_ = $proceed($$) + $sig.length; }");
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(19, invoke(obj, "run"));
+ }
+
+ public void testDollarClass() throws Exception {
+ CtClass cc = sloader.get("test1.DollarClass");
+
+ CtMethod m1 = cc.getDeclaredMethod("k1");
+ m1.insertBefore("{ $1 += $class.getName().length(); }");
+
+ CtMethod m2 = cc.getDeclaredMethod("k2");
+ m2.instrument(new ExprEditor() {
+ public void edit(MethodCall m) throws CannotCompileException {
+ m.replace("{ $_ = $class.getName().length(); }");
+ }
+ });
+ m2.insertBefore("{ $1 += $class.getName().length(); }");
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(58, invoke(obj, "run"));
+ }
+
+ public void testHandler() throws Exception {
+ CtClass cc = sloader.get("test1.Handler");
+
+ CtMethod m1 = cc.getDeclaredMethod("m1");
+ m1.instrument(new ExprEditor() {
+ public void edit(Handler h) throws CannotCompileException {
+ try {
+ print(h.getType().getName());
+ h.insertBefore(
+ "{ p = (($r)$1).getClass().getName().length()"
+ + "+ $type.getName().length(); }");
+ }
+ catch (NotFoundException e) {
+ throw new CannotCompileException(e);
+ }
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(("java.lang.IndexOutOfBoundsException".length()
+ + "java.lang.ClassNotFoundException".length())
+ * 2 + 1,
+ invoke(obj, "test"));
+ }
+
+ public void testInterface() throws Exception {
+ String className = "test1.NewInterface";
+ ClassPool pool = ClassPool.getDefault();
+ CtClass targetCtClass = pool.get(className);
+ CtClass ctInterface
+ = pool.makeInterface(className + "2");
+ CtMethod[] ctMethods = targetCtClass.getDeclaredMethods();
+ for (int i = 0;i < ctMethods.length; i++) {
+ String code = Modifier.toString(ctMethods[i].getModifiers())
+ + " " + ctMethods[i].getReturnType().getName()
+ + " " + ctMethods[i].getName() + "();";
+
+ System.out.println(code);
+ CtMethod m = CtNewMethod.make(code, ctInterface);
+ ctInterface.addMethod(m);
+ }
+
+ targetCtClass.addInterface(ctInterface);
+ targetCtClass.stopPruning(true);
+ targetCtClass.writeFile();
+
+ ctInterface.stopPruning(true);
+ ctInterface.writeFile();
+ ctInterface.toClass();
+ targetCtClass.toClass();
+ }
+
+ public void testDispatch() throws Exception {
+ CtClass cc = sloader.get("test1.Dispatch");
+
+ CtMethod m1 = cc.getDeclaredMethod("run");
+ m1.insertAfter("$_ += f(new Object[1]);");
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(7, invoke(obj, "run"));
+ }
+
+ public void testMakeClass()throws Exception {
+ CtClass cc = sloader.makeClass(
+ new FileInputStream(PATH + "test1/MakeClass.class"));
+ assertEquals("test1.MakeClass", cc.getName());
+ assertEquals(cc, sloader.get(cc.getName()));
+ cc.toBytecode();
+ assertTrue(cc.isFrozen());
+ try {
+ cc = sloader.makeClass(
+ new FileInputStream(PATH + "test1/MakeClass.class"));
+ assertTrue(false);
+ }
+ catch (RuntimeException e) {
+ print(e.getMessage());
+ }
+ }
+
+ public void testMakeMethod() throws Exception {
+ CtClass cc = sloader.makeClass("test1.MakeMethod");
+ cc.addField(new CtField(CtClass.intType, "i", cc));
+ String cons_body = "{ i = 3; }";
+ CtConstructor cons = CtNewConstructor.make(null, null,
+ cons_body, cc);
+ cc.addConstructor(cons);
+ CtMethod m = CtNewMethod.make(CtClass.intType, "run", null, null,
+ "{ return i; }", cc);
+ cc.addMethod(m);
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(3, invoke(obj, "run"));
+ }
+
+ public void testDesc() throws Exception {
+ Class[] sig;
+
+ assertEquals(int.class, Desc.getType("I"));
+ assertEquals(String.class, Desc.getType("Ljava/lang/String;"));
+ assertEquals(String[].class, Desc.getType("[Ljava/lang/String;"));
+ assertEquals(int[].class, Desc.getType("[I"));
+
+ sig = Desc.getParams("()V");
+ assertEquals(0, sig.length);
+
+ sig = Desc.getParams("(I)V");
+ assertEquals(int.class, sig[0]);
+ assertEquals(1, sig.length);
+
+ sig = Desc.getParams("(IJ)V");
+ assertEquals(long.class, sig[1]);
+ assertEquals(2, sig.length);
+
+ sig = Desc.getParams("(Ljava/lang/String;)V");
+ assertEquals(String.class, sig[0]);
+ assertEquals(1, sig.length);
+
+ sig = Desc.getParams("([Ljava/lang/String;I)V");
+ assertEquals(String[].class, sig[0]);
+ assertEquals(2, sig.length);
+
+ sig = Desc.getParams("(Ljava/lang/String;[Ljava/lang/String;)V");
+ assertEquals(String[].class, sig[1]);
+ assertEquals(2, sig.length);
+ }
+
+ public void testCast() throws Exception {
+ CtClass cc = sloader.makeClass("test1.CastTest");
+
+ StringBuffer src = new StringBuffer();
+ src.append("public void test(java.lang.String[] strValues)\n");
+ src.append("{\n");
+ src.append("\tObject[] values = new Object[2];");
+ src.append("\tvalues[0] = strValues;");
+ src.append("\tvalues[1] = strValues;");
+ src.append("\tstrValues = (String[])values[0];");
+ src.append("}\n");
+
+ CtMethod m = CtNewMethod.make(src.toString(), cc);
+ }
+
+ static final long svUID = 6006955401253799668L;
+
+ public void testSerialVUID() throws Exception {
+ CtClass cc = sloader.get("test1.MySerializableClass");
+ assertEquals(svUID, SerialVersionUID.calculateDefault(cc));
+ SerialVersionUID.setSerialVersionUID(cc);
+ cc.writeFile();
+ }
+
+ public void testInvokeInt() throws Exception {
+ CtClass cc = sloader.get("test1.InvokeInt");
+ CtMethod m1 = cc.getDeclaredMethod("check");
+
+ m1.instrument(new ExprEditor() {
+ public void edit(MethodCall m) throws CannotCompileException {
+ m.replace("$_ = $proceed($$) + k(1);");
+ }
+ });
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(6, invoke(obj, "run"));
+ }
+
+ public void testSubtypeOf() throws Exception {
+ testSubtypeOf2("java.lang.Object", "int", false);
+ testSubtypeOf2("int[]", "java.lang.Object", true);
+ testSubtypeOf2("int[]", "java.lang.Cloneable", true);
+ testSubtypeOf2("java.lang.Object", "int[]", false);
+ testSubtypeOf2("java.lang.Integer", "java.lang.Number", true);
+ testSubtypeOf2("java.lang.Number", "java.lang.Integer", false);
+ testSubtypeOf2("java.lang.Integer[]", "java.lang.Number[]", true);
+ testSubtypeOf2("java.lang.Number[]", "java.lang.Integer[]", false);
+ testSubtypeOf2("java.lang.Integer", "java.io.Serializable", true);
+ testSubtypeOf2("java.lang.Integer", "java.lang.Object", true);
+ }
+
+ private void testSubtypeOf2(String s, String t, boolean b)
+ throws Exception
+ {
+ assertTrue(sloader.get(s).subtypeOf(sloader.get(t)) == b);
+ }
+
+ public void testMakeInterface() throws Exception {
+ CtClass cc = sloader.makeInterface("test1.MkInterface");
+ CtMethod m = CtNewMethod.make("public abstract void ready();", cc);
+ cc.addMethod(m);
+ cc.writeFile();
+ // cloader.loadClass(cc.getName());
+ java.io.File genDir = new java.io.File(".");
+ java.net.URLClassLoader ucl = new java.net.URLClassLoader(
+ new java.net.URL[] { genDir.toURL() }, null);
+ Class intf = ucl.loadClass("test1.MkInterface");
+ }
+
+ public void testCodeConv() throws Exception {
+ CtClass cc = sloader.get("test1.CodeConv");
+ CtClass pc = sloader.get("test1.CodeConvP");
+
+ CodeConverter conv = new CodeConverter();
+ conv.replaceFieldRead(pc.getDeclaredField("a1"), cc, "getA1");
+ conv.replaceFieldRead(pc.getDeclaredField("a2"), cc, "getA2");
+ conv.redirectFieldAccess(pc.getDeclaredField("a3"), cc, "a4");
+ conv.replaceFieldWrite(pc.getDeclaredField("b1"), cc, "putB1");
+
+ cc.instrument(conv);
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(51, invoke(obj, "run"));
+ }
+
+ public void testTryCatch() throws Exception {
+ CtClass cc = sloader.get("test1.TryCatch");
+ CtMethod m1 = cc.getDeclaredMethod("m1");
+
+ m1.instrument(new ExprEditor() {
+ public void edit(MethodCall m) throws CannotCompileException {
+ m.replace(
+ "try { doit(); }"
+ + "catch(NullPointerException e){ init(); doit(); }");
+ }
+ });
+
+ final String src =
+ "try { doit(); }"
+ + "catch(NullPointerException e){ init(); doit(); return a; }";
+
+ CtMethod p1 = cc.getDeclaredMethod("p1");
+ p1.insertAfter(src, true);
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(4, invoke(obj, "run"));
+ Object obj2 = make(cc.getName());
+ assertEquals(4, invoke(obj2, "p1"));
+ }
+
+ private CtClass[] throwablesList = null;
+
+ public void testGetThrowables() throws Exception {
+ CtClass cc = sloader.get("test1.GetThrowables");
+ CtMethod m1 = cc.getDeclaredMethod("run");
+ m1.instrument(new ExprEditor() {
+ public void edit(MethodCall m) throws CannotCompileException {
+ throwablesList = m.mayThrow();
+ }
+ });
+
+ System.out.println(throwablesList[0].getName());
+ System.out.println(throwablesList[1].getName());
+ assertEquals(2, throwablesList.length);
+ }
+
+ public void testArrayAccess() throws Exception {
+ CtClass cc = sloader.get("test1.ArrayAccess");
+ CtMethod m1 = cc.getDeclaredMethod("test");
+ m1.insertBefore("{ ia[0] += 1; iaa[1] = iaa[0]; }");
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(8, invoke(obj, "test"));
+ }
+
+ public void testClinit() throws Exception {
+ CtClass cc = sloader.get("test1.Clinit");
+ CtConstructor clinit = cc.getClassInitializer();
+ assertTrue(clinit != null);
+ try {
+ clinit.insertBeforeBody(";");
+ assertTrue(false);
+ }
+ catch (CannotCompileException e) {
+ print(e.toString());
+ assertEquals("class initializer", e.getReason());
+ }
+
+ CtConstructor[] init = cc.getConstructors();
+ assertEquals(1, init.length);
+ clinit.insertAfter("j += 1;");
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(457, invoke(obj, "run"));
+ }
+
+ public void testClinit2() throws Exception {
+ CtClass cc = sloader.get("test1.Clinit2");
+ CtConstructor clinit = cc.makeClassInitializer();
+ clinit.insertAfter("j = 7;");
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(7, invoke(obj, "run"));
+ }
+
+ // by yamazaki
+ public void testCondExpr() throws Exception {
+ CtClass cc = sloader.makeClass("test1.CondExpr");
+ CtMethod methodM = new CtMethod(CtClass.intType, "m",
+ new CtClass[]{ CtClass.intType }, cc);
+ methodM.setModifiers(methodM.getModifiers() | Modifier.STATIC);
+ methodM.setBody("{if($1 <= 0) return 1; else return 0;}");
+ cc.addMethod(methodM);
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(0, invoke(obj, "m", 3));
+ }
+
+ // by yamazaki
+ public void testCondExpr2() throws Exception {
+ CtClass cc = sloader.makeClass("test1.CondExpr2");
+ CtMethod methodM = new CtMethod(CtClass.intType, "m",
+ new CtClass[]{ CtClass.intType }, cc);
+ methodM.setModifiers(methodM.getModifiers() | Modifier.STATIC);
+ methodM.setBody("{return ($1 <= 0) ? 1 : (m($1 - 1) * $1);}");
+ cc.addMethod(methodM);
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(6, invoke(obj, "m", 3));
+ }
+
+ // by yamazaki
+ public void testCondExpr3() throws Exception {
+ CtClass cc = sloader.makeClass("test1.CondExpr3");
+
+ CtMethod methodM = CtNewMethod.make(
+ "public abstract int m(int i);", cc);
+ CtMethod methodN = CtNewMethod.make(
+ "public abstract int n(int i);", cc);
+ cc.addMethod(methodM);
+ cc.addMethod(methodN);
+
+ methodM.setBody("{return ($1 <= 0) ? 1 : (n($1 - 1) * $1);}");
+ methodN.setBody("{return m($1);}");
+
+ cc.setModifiers(cc.getModifiers() & ~Modifier.ABSTRACT);
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(6, invoke(obj, "m", 3));
+ }
+
+ public void testDelegator() throws Exception {
+ CtClass cc = sloader.get("test1.Delegator");
+
+ assertEquals("test1.SuperDelegator", cc.getSuperclass().getName());
+
+ CtMethod f = sloader.getMethod("test1.SuperDelegator", "f");
+ CtMethod g = sloader.getMethod("test1.SuperDelegator", "g");
+
+ cc.addMethod(CtNewMethod.delegator(f, cc));
+ cc.addMethod(CtNewMethod.delegator(g, cc));
+
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(15, invoke(obj, "run"));
+ }
+
+ public void testSetName() throws Exception {
+ CtClass cc = sloader.get("test1.SetName");
+ CtMethod m0 = cc.getDeclaredMethod("foo");
+ cc.setName("test1.SetName2");
+ assertEquals(cc, sloader.get("test1.SetName2"));
+ assertEquals("foo(Ltest1/SetName2;)", m0.getStringRep());
+ CtClass cc2 = sloader.makeClass("test1.SetName3");
+ CtMethod m = CtNewMethod.make(
+ "public int m(test1.SetName2 obj) { return ((test1.SetName2)obj).i; }",
+ cc2);
+ cc2.addMethod(m);
+ cc.writeFile();
+ cc2.writeFile();
+ }
+
+ public void testFieldModifier() throws Exception {
+ CtClass cc = sloader.get("test1.FieldMod");
+ CtField f = cc.getField("text");
+ f.setModifiers(Modifier.PUBLIC);
+ f = cc.getField("i");
+ f.setName("j");
+ cc.writeFile();
+
+ Object obj = make(cc.getName());
+ assertEquals(java.lang.reflect.Modifier.PUBLIC,
+ obj.getClass().getField("text").getModifiers());
+ assertTrue(obj.getClass().getField("j") != null);
+ }
+
+ public void testToString() throws Exception {
+ System.out.println(sloader.get("test1.FieldMod"));
+ System.out.println(sloader.get("java.lang.Object"));
+ }
+
+ public void testPackage() throws Exception {
+ Object obj = new Loader().loadClass("test1.Pac").newInstance();
+ assertEquals(1, invoke(obj, "run"));
+ }
+
+ public void testHoward() throws Exception {
+ String head =
+ "public Object lookup() throws java.rmi.RemoteException ";
+ String src =
+ "{ if (_remote != null) return _remote;"
+ + " test1.HowardHome h = (test1.HowardHome)lookup(\"Howard\");"
+ + " try { _remote = h.create(); }"
+ + " catch (java.io.IOException e) { throw new java.rmi.RemoteException(e.getMessage(), e); }"
+ + " return _remote; }";
+
+ String src2 =
+ "public void lookup2() {"
+ + " try {}"
+ + " catch (java.io.IOException e) { throw new Exception(e); }"
+ + "}";
+
+ CtClass cc = sloader.get("test1.Howard");
+ CtMethod m = CtNewMethod.make(head + src, cc);
+ cc.addMethod(m);
+ try {
+ CtMethod m2 = CtNewMethod.make(src2, cc);
+ cc.addMethod(m2);
+ assertTrue(false);
+ }
+ catch (CannotCompileException e) {}
+
+ m = new CtMethod(sloader.get("java.lang.Object"),
+ "lookup3", null, cc);
+ m.setBody(src);
+ m.setModifiers(Modifier.PUBLIC);
+ m.setExceptionTypes(new CtClass[] {
+ sloader.get("java.rmi.RemoteException") });
+ cc.addMethod(m);
+
+ cc.writeFile();
+ Object target = make(cc.getName());
+ Method mth = target.getClass().getMethod("lookup", new Class[0]);
+ Object res = mth.invoke(target, new Object[0]);
+ assertEquals("howard4", res);
+
+ mth = target.getClass().getMethod("lookup3", new Class[0]);
+ res = mth.invoke(target, new Object[0]);
+ assertEquals("howard4", res);
+ }
+
+ public void testLoop() throws Exception {
+ CtClass cc = sloader.makeClass("test1.Loop");
+ CtMethod m = CtNewMethod.make(
+ "public int run(int i) { int k = 0;"
+ + "while (true) { if (k++ > 10) return i; } }",
+ cc);
+ cc.addMethod(m);
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(3, invoke(obj, "run", 3));
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite("Javassist Tests");
+ suite.addTestSuite(JvstTest.class);
+ suite.addTestSuite(JvstTest2.class);
+ suite.addTestSuite(JvstTest3.class);
+ suite.addTestSuite(JvstTest4.class);
+ suite.addTestSuite(LoaderTestByRandall.class);
+ suite.addTestSuite(javassist.bytecode.BytecodeTest.class);
+ // suite.addTestSuite(javassist.bytecode.StackMapTest.class);
+ suite.addTestSuite(javassist.compiler.CompTest.class);
+ suite.addTestSuite(javassist.SetterTest.class);
+ suite.addTestSuite(javassist.bytecode.InsertGap0.class);
+ suite.addTestSuite(javassist.tools.reflect.LoaderTest.class);
+ suite.addTestSuite(testproxy.ProxyTester.class);
+ // suite.addTestSuite(testproxy.ProxyFactoryPerformanceTest.class);
+ suite.addTestSuite(javassist.proxyfactory.ProxyFactoryTest.class);
+ return suite;
+ }
+}