diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2011-08-31 10:29:34 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2011-08-31 10:29:34 +0000 |
commit | d72870bfb6b09927e10944bdd129ce18dfcf7366 (patch) | |
tree | 27f56e4d1523a8cecc8976df60155e6b8429e504 /src/test/javassist/JvstTest.java | |
parent | 76a1cba9c433e8242bb6648e72b3ed43c7a4995a (diff) | |
download | javassist-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.java | 1123 |
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; + } +} |