1 package javassist; 2 3 import java.io.*; 4 import java.net.URL; 5 6 import org.junit.FixMethodOrder; 7 import org.junit.runners.MethodSorters; 8 9 import java.lang.reflect.Method; 10 11 import javassist.expr.*; 12 import test2.DefineClassCapability; 13 14 @SuppressWarnings({"rawtypes","unused"}) 15 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 16 public class JvstTest2 extends JvstTestRoot { JvstTest2(String name)17 public JvstTest2(String name) { 18 super(name); 19 } 20 testInsertAt()21 public void testInsertAt() throws Exception { 22 CtClass cc = sloader.get("test2.InsertAt"); 23 CtMethod m1 = cc.getDeclaredMethod("foo"); 24 int line = 6; 25 int ln = m1.insertAt(line, false, null); 26 int ln2 = m1.insertAt(line, "counter++;"); 27 assertEquals(ln, ln2); 28 assertEquals(7, ln2); 29 30 line = 8; 31 ln = m1.insertAt(line, false, null); 32 ln2 = m1.insertAt(line, "counter++;"); 33 assertEquals(ln, ln2); 34 assertEquals(8, ln2); 35 36 CtMethod m2 = cc.getDeclaredMethod("bar2"); 37 int ln3 = m2.insertAt(20, "{ int m = 13; j += m; }"); 38 assertEquals(20, ln3); 39 40 cc.writeFile(); 41 Object obj = make(cc.getName()); 42 assertEquals(7, invoke(obj, "foo")); 43 assertEquals(25, invoke(obj, "bar")); 44 } 45 testInsertLocal()46 public void testInsertLocal() throws Exception { 47 CtClass cc = sloader.get("test2.InsertLocal"); 48 CtMethod m1 = cc.getDeclaredMethod("foo"); 49 m1.insertBefore("{ i = s.length(); d = 0.14; }"); 50 m1.insertAfter("{ field = i; }"); 51 52 CtMethod m2 = cc.getDeclaredMethod("run2"); 53 m2.insertAt(22, "{ s = \"12\"; k = 5; }"); 54 55 CtMethod m3 = cc.getDeclaredMethod("run3"); 56 m3.instrument(new ExprEditor() { 57 public void edit(NewExpr n) throws CannotCompileException { 58 n.replace("{ i++; $_ = $proceed($$); }"); 59 } 60 public void edit(FieldAccess f) throws CannotCompileException { 61 f.replace("{ i++; $_ = $proceed($$); }"); 62 } 63 public void edit(MethodCall m) throws CannotCompileException { 64 m.replace("{ i++; $_ = $proceed($$); }"); 65 } 66 }); 67 68 cc.writeFile(); 69 Object obj = make(cc.getName()); 70 assertEquals(317, invoke(obj, "run")); 71 assertEquals(7, invoke(obj, "run2")); 72 assertEquals(3, invoke(obj, "run3")); 73 } 74 testStaticMember()75 public void testStaticMember() throws Exception { 76 CtClass cc = sloader.get("test2.StaticMember"); 77 CtMethod m = CtNewMethod.make( 78 "public int run() {" + 79 "return test2.StaticMember#k + test2.StaticMember#foo(); }", cc); 80 cc.addMethod(m); 81 82 m = CtNewMethod.make( 83 "public int run2() {" + 84 "return k + foo(); }", cc); 85 cc.addMethod(m); 86 87 m = CtNewMethod.make( 88 "public int run3() {" + 89 " test2.StaticMember sm = this;" + 90 " return sm.k + sm.foo(); }", cc); 91 cc.addMethod(m); 92 93 m = CtNewMethod.make( 94 "public int run4() {" + 95 " return this.k + this.foo(); }", cc); 96 cc.addMethod(m); 97 98 m = CtNewMethod.make( 99 "public static int run5() {" + 100 " return k + foo(); }", cc); 101 cc.addMethod(m); 102 103 m = CtNewMethod.make( 104 "public int run6() {" + 105 " test2.IStaticMember i = this; return i.bar(); }", cc); 106 cc.addMethod(m); 107 108 cc.writeFile(); 109 Object obj = make(cc.getName()); 110 assertEquals(10, invoke(obj, "run")); 111 assertEquals(10, invoke(obj, "run2")); 112 assertEquals(10, invoke(obj, "run3")); 113 assertEquals(10, invoke(obj, "run4")); 114 assertEquals(10, invoke(obj, "run5")); 115 assertEquals(3, invoke(obj, "run6")); 116 } 117 testStaticMember2()118 public void testStaticMember2() throws Exception { 119 CtClass cc = sloader.get("test2.StaticMember2"); 120 121 cc.addMethod(CtNewMethod.make( 122 "public int run() {" 123 + " return test2.StaticMember2.k + test2.StaticMember2.seven()" 124 + " + (test2.StaticMember2.f + f)" 125 + " + test2.StaticMember2.f + f; }", 126 cc)); 127 128 cc.addMethod(CtNewMethod.make( 129 "public int run1() {" 130 + " long j = 1L;" 131 + " return (int)(j + (test2.StaticMember2.fj + fj)" 132 + " + test2.StaticMember2.fj + fj); }", 133 cc)); 134 135 cc.addMethod(CtNewMethod.make( 136 "public int run2() {" 137 + " double x = 1.0;" 138 + " double d = x + test2.StaticMember2.fd + fd" 139 + " + (test2.StaticMember2.fd + fd);" 140 + " return (int)(d * 10); }", 141 cc)); 142 143 cc.addMethod(CtNewMethod.make( 144 "public int run3() {" 145 + " return (test2.StaticMember2.fb & fb) ? 1 : 0; }", 146 cc)); 147 148 cc.writeFile(); 149 Object obj = make(cc.getName()); 150 assertEquals(54, invoke(obj, "run")); 151 assertEquals(53, invoke(obj, "run1")); 152 assertEquals(958, invoke(obj, "run2")); 153 assertEquals(0, invoke(obj, "run3")); 154 } 155 testSuperCall()156 public void testSuperCall() throws Exception { 157 CtClass cc = sloader.get("test2.SuperCall"); 158 CtMethod m1 = cc.getDeclaredMethod("foo"); 159 m1.instrument(new ExprEditor() { 160 public void edit(MethodCall m) throws CannotCompileException { 161 m.replace("{ $_ = $proceed($$); }"); 162 } 163 }); 164 cc.writeFile(); 165 Object obj = make(cc.getName()); 166 invoke(obj, "bar"); 167 } 168 testSetSuper()169 public void testSetSuper() throws Exception { 170 CtClass cc = sloader.makeClass("test2.SetSuper"); 171 CtClass cc2 = sloader.makeClass("test2.SetSuperParent"); 172 CtClass intf = sloader.makeInterface("test2.SetSuperIntf"); 173 CtClass remote = sloader.get("java.rmi.Remote"); 174 175 cc.setSuperclass(cc2); 176 cc.setInterfaces(new CtClass[] { intf }); 177 intf.setSuperclass(remote); 178 intf.writeFile(); 179 cc2.writeFile(); 180 cc.writeFile(); 181 182 assertEquals(cc2, cc.getSuperclass()); 183 assertEquals(intf, cc.getInterfaces()[0]); 184 assertEquals(sloader.get("java.lang.Object"), intf.getSuperclass()); 185 assertEquals(remote, intf.getInterfaces()[0]); 186 187 make(cc.getName()); 188 } 189 testReplaceClassName()190 public void testReplaceClassName() throws Exception { 191 String oldName = "test2.ReplaceClassName2"; 192 String newName = "test2.ReplaceClassName3"; 193 CtClass cc = sloader.get("test2.ReplaceClassName"); 194 cc.replaceClassName(oldName, newName); 195 cc.writeFile(); 196 CtClass cc2 = dloader.get(cc.getName()); 197 CtMethod m = cc2.getDeclaredMethod("foo"); 198 assertEquals(newName, m.getParameterTypes()[0].getName()); 199 } 200 testCodeGen()201 public void testCodeGen() throws Exception { 202 CtClass cc = sloader.get("test2.CodeGen"); 203 CtMethod m1 = cc.getDeclaredMethod("run"); 204 m1.insertBefore( 205 "{ double d = true ? 1 : 0.1; " 206 + " d = d > 0.5 ? 0.0 : - 1.0; " 207 + " System.out.println(d); " 208 + " String s = \"foo\"; " 209 + " s = 1 + 2 + s + \"bar\"; " 210 + " s += \"poi\" + 3 + seven() + seven(\":\" + ' '); " 211 + " s += .14; " 212 + " msg = s; " 213 + " System.out.println(s); }"); 214 215 // recursive type check is done if $proceed is used. 216 CtMethod m2 = CtNewMethod.make( 217 "public int test() {" 218 + " String s = $proceed(\"int\" + (3 + 0.14)) + '.'; " 219 + " System.out.println(s); return s.length(); }", 220 cc, "this", "seven"); 221 cc.addMethod(m2); 222 cc.writeFile(); 223 Object obj = make(cc.getName()); 224 assertEquals(19, invoke(obj, "run")); 225 assertEquals(9, invoke(obj, "test")); 226 } 227 testCodeGen2()228 public void testCodeGen2() throws Exception { 229 CtClass cc = sloader.makeClass("test2.CodeGen2"); 230 231 CtMethod m1 = CtNewMethod.make( 232 "public int test() {" 233 + " int len;" 234 + " String s = \"foo\" + \"bar\" + 3;" 235 + " System.out.println(s); len = s.length();" 236 + " len = -3 + len; len = len - (7 - 2 + -1);" 237 + " int k = 3; len += ~k - ~3;" 238 + " return len; }", 239 cc); 240 cc.addMethod(m1); 241 242 CtMethod m2 = CtNewMethod.make( 243 "public int test2() {" 244 + " double d = 0.2 - -0.1;" 245 + " d += (0.2 + 0.3) * 1.0;" 246 + " return (int)(d * 10); }", 247 cc); 248 cc.addMethod(m2); 249 250 cc.writeFile(); 251 Object obj = make(cc.getName()); 252 assertEquals(0, invoke(obj, "test")); 253 assertEquals(8, invoke(obj, "test2")); 254 } 255 256 // not used anymore. notTestGetInner()257 private void notTestGetInner() throws Exception { 258 ClassPool pool = ClassPool.getDefault(); 259 CtClass c = pool.get("javassist.CtMethod.ConstParameter"); 260 CtClass d = pool.get("javassist.CtMethod.ConstParameter"); 261 CtClass e = pool.get("javassist.CtMethod$ConstParameter"); 262 assertSame(c, d); 263 assertSame(c, e); 264 try { 265 c = pool.get("test2.Inner.Fake"); 266 fail("found not-existing class"); 267 } 268 catch (NotFoundException ex) {} 269 } 270 testInner()271 public void testInner() throws Exception { 272 ClassPool pool = ClassPool.getDefault(); 273 String classname = "test2.Inner"; 274 CtClass target = pool.get(classname); 275 String src = 276 "public void sampleMethod() throws Exception {" 277 + "java.util.Properties props = new java.util.Properties();" 278 + "java.rmi.activation.ActivationGroupDesc.CommandEnvironment ace " 279 + " = null;" 280 + "java.rmi.activation.ActivationGroupDesc agd " 281 + " = new java.rmi.activation.ActivationGroupDesc(props,ace);}"; 282 CtMethod newmethod = CtNewMethod.make(src, target); 283 target.addMethod(newmethod); 284 285 String src2 = 286 "public java.lang.Character.Subset sampleMethod2() {" 287 + " java.lang.Character.Subset s " 288 + " = Character.UnicodeBlock.HIRAGANA; " 289 + " return s; }"; 290 CtMethod newmethod2 = CtNewMethod.make(src2, target); 291 target.addMethod(newmethod2); 292 293 target.writeFile(); 294 } 295 testURL()296 public void testURL() throws Exception { 297 String url; 298 299 ClassPool cp = new ClassPool(null); 300 cp.appendSystemPath(); 301 302 url = cp.find("java.lang.Object").toString(); 303 System.out.println(url); 304 if (JvstTest.java9) 305 assertEquals("jrt:/java.base/java/lang/Object.class", url); 306 else { 307 assertTrue(url.startsWith("jar:file:")); 308 assertTrue(url.endsWith(".jar!/java/lang/Object.class")); 309 } 310 311 assertNull(cp.find("class.not.Exist")); 312 313 cp = new ClassPool(null); 314 cp.insertClassPath("."); 315 316 url = cp.find("test2.Inner").toString(); 317 System.out.println("testURL: " + url); 318 assertTrue(url.startsWith("file:/")); 319 assertTrue(url.endsWith("/test2/Inner.class")); 320 321 assertNull(cp.find("test2.TestURL")); 322 323 cp = new ClassPool(null); 324 cp.insertClassPath(JAR_PATH + "javassist.jar"); 325 326 url = cp.find("javassist.CtClass").toString(); 327 System.out.println("testURL: " + url); 328 assertTrue(url.startsWith("jar:file:")); 329 assertTrue(url.endsWith("javassist.jar!/javassist/CtClass.class")); 330 331 assertNull(cp.find("javassist.TestURL")); 332 333 cp = new ClassPool(null); 334 cp.insertClassPath(new LoaderClassPath(cloader)); 335 336 url = cp.find("javassist.CtMethod").toString(); 337 System.out.println("testURL: " + url); 338 assertTrue(url.startsWith("file:")); 339 assertTrue(url.endsWith("/javassist/CtMethod.class")); 340 341 assertNull(cp.find("javassist.TestURL")); 342 343 cp = new ClassPool(null); 344 cp.insertClassPath(new ByteArrayClassPath("test2.ByteArray", null)); 345 346 url = cp.find("test2.ByteArray").toString(); 347 System.out.println("testURL: " + url); 348 assertTrue( 349 url.equals("file:/ByteArrayClassPath/test2/ByteArray.class")); 350 351 assertNull(cp.find("test2.TestURL")); 352 } 353 not_testURLClassPath()354 public void not_testURLClassPath() throws Exception { 355 String host = "www.csg.is.titech.ac.jp"; 356 String path = "/~chiba/tmp/"; 357 String url; 358 359 ClassPool cp = new ClassPool(null); 360 cp.insertClassPath(new URLClassPath(host, 80, path, "test")); 361 362 url = cp.find("test.TestClassPath").toString(); 363 System.out.println(url); 364 assertEquals("http://" + host + ":80" + path 365 + "test/TestClassPath.class", url); 366 367 assertNull(cp.find("test.No")); 368 } 369 testGetURL()370 public void testGetURL() throws Exception { 371 CtClass cc = sloader.get("java.lang.String"); 372 String url = cc.getURL().toString(); 373 System.out.println(url); 374 if (JvstTest.java9) { 375 assertEquals("jrt:/java.base/java/lang/String.class", url); 376 } 377 else { 378 assertTrue(url.startsWith("jar:file:")); 379 assertTrue(url.endsWith(".jar!/java/lang/String.class")); 380 } 381 382 cc = sloader.get("int"); 383 try { 384 URL u = cc.getURL(); 385 fail(); 386 } 387 catch (NotFoundException e) { 388 assertEquals("int", e.getMessage()); 389 } 390 } 391 testInheritance()392 public void testInheritance() throws Exception { 393 ClassPool pool = ClassPool.getDefault(); 394 String classname = "test2.Inherit"; 395 CtClass target = pool.get(classname); 396 String src = 397 "public void sampleMethod() {" + 398 " test2.Inherit i = new test2.Inherit();" + 399 " test2.Inherit2 i2 = i;" + 400 " test2.Inherit3 i3 = i;" + 401 " i3.foo2(); i3.foo2(); i2.foo1(); }"; 402 403 CtMethod newmethod = CtNewMethod.make(src, target); 404 target.addMethod(newmethod); 405 target.writeFile(); 406 } 407 testIncOp()408 public void testIncOp() throws Exception { 409 CtClass target = sloader.makeClass("test2.IncOp"); 410 String src = 411 "public int sample() {" 412 + " int ia[] = new int[50];" 413 + " ia[0] = 1;" 414 + " int v = ++(ia[0]);" 415 + " return v; }"; 416 417 CtMethod newmethod = CtNewMethod.make(src, target); 418 target.addMethod(newmethod); 419 target.writeFile(); 420 Object obj = make(target.getName()); 421 assertEquals(2, invoke(obj, "sample")); 422 } 423 testSetExceptions()424 public void testSetExceptions() throws Exception { 425 CtClass cc = sloader.get("test2.SetExceptions"); 426 CtMethod m = cc.getDeclaredMethod("f"); 427 CtClass ex = m.getExceptionTypes()[0]; 428 assertEquals("java.lang.Exception", ex.getName()); 429 m.setExceptionTypes(null); 430 assertEquals(0, m.getExceptionTypes().length); 431 m.setExceptionTypes(new CtClass[0]); 432 assertEquals(0, m.getExceptionTypes().length); 433 m.setExceptionTypes(new CtClass[] { ex }); 434 assertEquals(ex, m.getExceptionTypes()[0]); 435 } 436 testNullArg()437 public void testNullArg() throws Exception { 438 CtClass cc = sloader.makeClass("test2.NullArgTest"); 439 CtMethod m1 = CtNewMethod.make( 440 "public Object foo(Object[] obj, int idx) throws Throwable {" + 441 " return null; }", cc); 442 cc.addMethod(m1); 443 CtMethod m2 = CtNewMethod.make( 444 "public void bar() { this.foo(null, 0); }", cc); 445 cc.addMethod(m2); 446 CtMethod m3 = CtNewMethod.make( 447 "public void bar2() { this.foo((Object[])null, 0); }", cc); 448 cc.addMethod(m3); 449 cc.writeFile(); 450 } 451 testAddMethod()452 public void testAddMethod() throws Exception { 453 CtClass cc = sloader.get("test2.AddMethod"); 454 CtMethod m = CtNewMethod.make( 455 "public int f() { return 1; }", cc); 456 try { 457 cc.addMethod(m); 458 fail(); 459 } 460 catch (CannotCompileException e) {} 461 CtMethod m2 = CtNewMethod.make( 462 "public void f(int i, int j) { return 1; }", cc); 463 cc.addMethod(m2); 464 try { 465 cc.addField(new CtField(CtClass.longType, "f", cc)); 466 fail(); 467 } 468 catch (CannotCompileException e) {} 469 } 470 testCopyStream()471 public void testCopyStream() throws Exception { 472 int[] size = { 100, 4096, 8000, 1023, 1024, 1025, 2047, 473 4096*3, 4096*6, 4096*6-1, 4096*256*3, 4096*256*6 }; 474 for (int i = 0; i < size.length; i++) { 475 byte[] data = new byte[size[i]]; 476 for (int j = 0; j < data.length; j++) 477 data[j] = (byte)j; 478 479 InputStream ins = new ByteArrayInputStream(data); 480 ByteArrayOutputStream outs = new ByteArrayOutputStream(); 481 ClassPoolTail.copyStream(ins, outs); 482 byte[] data2 = outs.toByteArray(); 483 if (data2.length != data.length) 484 throw new Exception("bad size"); 485 486 for (int k = 0; k < data.length; k++) 487 if (data[k] != data2[k]) 488 throw new Exception("bad element"); 489 } 490 } 491 testDeclaringClass()492 public void testDeclaringClass() throws Exception { 493 try { 494 CtClass cc = sloader.get("test2.NotExistingClass"); 495 } 496 catch (NotFoundException e) { System.out.println(e); } 497 CtClass inner = sloader.get("test2.Nested$Inner"); 498 CtClass outer = sloader.get("test2.Nested"); 499 assertEquals(outer, inner.getDeclaringClass()); 500 assertEquals(null, outer.getDeclaringClass()); 501 assertEquals(null, CtClass.intType.getDeclaringClass()); 502 503 CtClass inner3 = sloader.get("test2.Nested$Inner3"); 504 outer.writeFile(); 505 try { 506 CtMethod m = CtNewMethod.make( 507 "public void f(test2.Nested n) { return n.geti(); }", 508 inner3); 509 fail(); 510 } 511 catch (RuntimeException e) {} 512 outer.defrost(); 513 CtMethod m = CtNewMethod.make( 514 "public int f(test2.Nested n) { " + 515 "return n.geti() + test2.Nested.getj(1) + f() + g(); } ", 516 inner3); 517 inner3.addMethod(m); 518 inner3.writeFile(); 519 outer.writeFile(); 520 521 Object nobj = make(outer.getName()); 522 Object iobj = make(inner3.getName()); 523 Method mth = iobj.getClass().getMethod("f", 524 new Class[] { nobj.getClass() }); 525 Object resobj = mth.invoke(iobj, new Object[] { nobj }); 526 int res = ((Integer) resobj).intValue(); 527 assertEquals(6, res); 528 } 529 testDeclaringClass2()530 public void testDeclaringClass2() throws Exception { 531 CtClass out = sloader.get("test2.Anon"); 532 CtClass inner = sloader.get("test2.Anon$1"); 533 if (System.getProperty("java.vm.version").startsWith("1.4")) 534 assertTrue(inner.getEnclosingBehavior() == null); 535 else { 536 assertEquals("make", inner.getEnclosingBehavior().getName()); 537 assertEquals(out, inner.getDeclaringClass()); 538 assertEquals(out, 539 inner.getEnclosingBehavior().getDeclaringClass()); 540 } 541 542 assertNull(out.getEnclosingBehavior()); 543 assertNull(out.getEnclosingBehavior()); 544 545 CtClass inner2 = sloader.get("test2.Anon$Anon2$1"); 546 assertTrue(inner2.getEnclosingBehavior() instanceof CtConstructor); 547 assertEquals(sloader.get("test2.Anon$Anon2"), inner2.getEnclosingBehavior().getDeclaringClass()); 548 CtClass inner3 = sloader.get("test2.Anon$Anon3$1"); 549 assertTrue(inner3.getEnclosingBehavior() instanceof CtConstructor); 550 assertTrue(((CtConstructor)inner3.getEnclosingBehavior()).isClassInitializer()); 551 assertEquals(sloader.get("test2.Anon$Anon3"), inner3.getEnclosingBehavior().getDeclaringClass()); 552 } 553 testMethodInInner()554 public void testMethodInInner() throws Exception { 555 CtClass inner = sloader.get("test2.Nested2$Inner"); 556 CtClass outer = sloader.get("test2.Nested2"); 557 String src = 558 "public int f(test2.Nested2 n) {" + 559 " n.i = 1; n.i++; n.i += 2; return n.i; }"; 560 561 outer.writeFile(); 562 try { 563 CtMethod m = CtNewMethod.make(src, inner); 564 fail(); 565 } 566 catch (RuntimeException e) {} 567 outer.defrost(); 568 569 CtMethod m = CtNewMethod.make(src, inner); 570 inner.addMethod(m); 571 572 src = "public int g(test2.Nested2 n) {" + 573 " n.d = 1.0; n.d++; n.d += 2.0;" + 574 " return n.d == 4.0 ? 7 : 8; }"; 575 m = CtNewMethod.make(src, inner); 576 inner.addMethod(m); 577 578 src = "public int h(test2.Nested2 n) {" + 579 " n.s = \"poi\";" + 580 "return n.s.length() + f(n) + g(n); }"; 581 m = CtNewMethod.make(src, inner); 582 inner.addMethod(m); 583 584 inner.writeFile(); 585 outer.writeFile(); 586 587 Object nobj = make(outer.getName()); 588 Object iobj = make(inner.getName()); 589 Method mth = iobj.getClass().getMethod("h", 590 new Class[] { nobj.getClass() }); 591 Object resobj = mth.invoke(iobj, new Object[] { nobj }); 592 int res = ((Integer) resobj).intValue(); 593 assertEquals(14, res); 594 } 595 testMethodInInner2()596 public void testMethodInInner2() throws Exception { 597 CtClass inner = sloader.get("test2.Nested3$Inner"); 598 CtClass outer = sloader.get("test2.Nested3"); 599 String src = 600 "public int f() {" + 601 " int k = 0;" + 602 " test2.Nested3 n = new test2.Nested3(3);" + 603 " k += n.geti();" + 604 " n = new test2.Nested3();" + 605 " k += n.geti();" + 606 " n = new test2.Nested3(\"foo\");" + 607 " k += n.geti();" + 608 " return k; }"; 609 610 outer.stopPruning(true); 611 outer.writeFile(); 612 try { 613 CtMethod m = CtNewMethod.make(src, inner); 614 fail(); 615 } 616 catch (RuntimeException e) {} 617 outer.defrost(); 618 619 CtMethod m = CtNewMethod.make(src, inner); 620 inner.addMethod(m); 621 622 inner.writeFile(); 623 outer.writeFile(); 624 625 Object iobj = make(inner.getName()); 626 assertEquals(6, invoke(iobj, "f")); 627 } 628 testMakeNestedClass()629 public void testMakeNestedClass() throws Exception { 630 CtClass outer = sloader.get("test2.Nested4"); 631 try { 632 CtClass inner = outer.makeNestedClass("Inner", false); 633 fail(); 634 } 635 catch (RuntimeException e) { 636 print(e.getMessage()); 637 } 638 639 CtClass nested = outer.makeNestedClass("Inner", true); 640 outer.stopPruning(true); 641 outer.writeFile(); 642 outer.defrost(); 643 String src = 644 "public int f() { return test2.Nested4.value; }"; 645 646 CtMethod m = CtNewMethod.make(src, nested); 647 nested.addMethod(m); 648 nested.writeFile(); 649 outer.writeFile(); 650 651 Object iobj = make(nested.getName()); 652 assertEquals(6, invoke(iobj, "f")); 653 } 654 testPrivateMethod()655 public void testPrivateMethod() throws Exception { 656 CtClass cc = sloader.get("test2.PrivateMethod"); 657 try { 658 CtMethod m = CtNewMethod.make( 659 "public int f(test2.PrivateMethod2 p) { return p.f(); }", 660 cc); 661 fail(); 662 } 663 catch (CannotCompileException e) {} 664 } 665 testArrayLength()666 public void testArrayLength() throws Exception { 667 CtClass cc = sloader.makeClass("test2.ArrayLength"); 668 CtMethod m2 = CtNewMethod.make( 669 "public int f() { String[] s = new String[3]; " + 670 "return s.length; }", cc); 671 cc.addMethod(m2); 672 cc.writeFile(); 673 Object obj = make(cc.getName()); 674 assertEquals(3, invoke(obj, "f")); 675 } 676 testMakeStaticMethod()677 public void testMakeStaticMethod() throws Exception { 678 CtClass cc = sloader.makeClass("test2.MakeStaticMethod"); 679 CtMethod m = CtNewMethod.make(Modifier.PUBLIC | Modifier.STATIC, 680 CtClass.intType, "create", 681 new CtClass[] { CtClass.intType }, null, 682 "{ return $1; }", cc); 683 cc.addMethod(m); 684 cc.addMethod(CtNewMethod.make( 685 "public int test() { return create(13); }", cc)); 686 cc.writeFile(); 687 Object obj = make(cc.getName()); 688 assertEquals(13, invoke(obj, "test")); 689 } 690 testNewExprTry()691 public void testNewExprTry() throws Exception { 692 ExprEditor ed = new ExprEditor() { 693 public void edit(NewExpr expr) throws CannotCompileException { 694 StringBuffer code = new StringBuffer(300); 695 code.append("{ try "); 696 code.append("{ $_ = $proceed($$); }"); 697 code.append("catch (OutOfMemoryError e) {}}"); 698 expr.replace(code.toString()); 699 } 700 }; 701 702 CtClass cc = sloader.get("test2.NewExprTry"); 703 CtMethod m1 = cc.getDeclaredMethod("foo"); 704 m1.instrument(ed); 705 cc.writeFile(); 706 Object obj = make(cc.getName()); 707 assertEquals(16, invoke(obj, "run")); 708 } 709 testToClass()710 public void testToClass() throws Exception { 711 ClassPool cp = ClassPool.getDefault(); 712 CtClass cc = cp.makeClass("test2.ToClassTest"); 713 Class c = cc.toClass(DefineClassCapability.class); 714 assertEquals(getClass().getClassLoader(), c.getClassLoader()); 715 } 716 testAddCatchForConstructor()717 public void testAddCatchForConstructor() throws Exception { 718 CtClass cc = sloader.get("test2.AddCatchForConstructor"); 719 CtConstructor m1 = cc.getDeclaredConstructors()[0]; 720 m1.addCatch("return;", sloader.get("java.lang.Exception")); 721 cc.writeFile(); 722 Object obj = make(cc.getName()); 723 } 724 testAddLocalVar()725 public void testAddLocalVar() throws Exception { 726 CtClass cc = sloader.get("test2.AddLocalVar"); 727 CtMethod m1 = cc.getDeclaredMethod("foo"); 728 m1.addLocalVariable("i", CtClass.intType); 729 m1.insertBefore("i = 3;"); 730 m1.insertAfter("$_ = i + 1;"); 731 cc.writeFile(); 732 Object obj = make(cc.getName()); 733 assertEquals(4, invoke(obj, "foo")); 734 } 735 testNewArray()736 public void testNewArray() throws Exception { 737 ExprEditor ed = new ExprEditor() { 738 int dim[] = { 1, 2, 2, 1, 2, 2, 3 }; 739 int cdim[] = { 1, 1, 2, 1, 1, 2, 2 }; 740 int counter = 0; 741 public void edit(NewArray expr) throws CannotCompileException { 742 try { 743 CtClass str = sloader.get("java.lang.String"); 744 if (counter < 3) 745 assertEquals(str, expr.getComponentType()); 746 else 747 assertEquals(CtClass.intType, expr.getComponentType()); 748 749 assertEquals(dim[counter], expr.getDimension()); 750 assertEquals(cdim[counter], expr.getCreatedDimensions()); 751 expr.replace("{ i += $1; $_ = $proceed($$); }"); 752 ++counter; 753 } 754 catch (NotFoundException e) { 755 throw new CannotCompileException(e); 756 } 757 } 758 }; 759 760 CtClass cc = sloader.get("test2.NewArray"); 761 CtMethod m1 = cc.getDeclaredMethod("foo"); 762 m1.instrument(ed); 763 cc.writeFile(); 764 Object obj = make(cc.getName()); 765 assertEquals(48, invoke(obj, "run")); 766 } 767 testToString()768 public void testToString() throws Exception { 769 System.out.println(sloader.get("int")); 770 System.out.println(sloader.get("int[]")); 771 System.out.println(sloader.get("java.lang.Object")); 772 System.out.println(sloader.get("java.lang.String")); 773 System.out.println(sloader.get("javassist.CtNewClass")); 774 } 775 testDotClass()776 public void testDotClass() throws Exception { 777 testDotClass("test2.DotClass", false); 778 testDotClass("test2.DotClass_", true); 779 } 780 testDotClass(String cname, boolean java5)781 private void testDotClass(String cname, boolean java5) throws Exception { 782 CtClass cc = sloader.makeClass(cname); 783 if (java5) 784 cc.getClassFile2().setVersionToJava5(); 785 786 CtMethod m = CtNewMethod.make( 787 "public String getclass() {" + 788 " return int.class.getName() + int[].class.getName()" + 789 " + String.class.getName() + String[].class.getName()" + 790 " + java.lang.Object.class.getName()" + 791 " + java.util.Vector.class.getName(); }", cc); 792 cc.addMethod(m); 793 CtMethod m2 = CtNewMethod.make( 794 "public int test() {" + 795 " String s = getclass(); System.out.println(s);" + 796 " return s.length(); }", cc); 797 cc.addMethod(m2); 798 cc.writeFile(); 799 Object obj = make(cc.getName()); 800 assertEquals(72, invoke(obj, "test")); 801 } 802 testDotClass2()803 public void testDotClass2() throws Exception { 804 testDotClass2("test2.DotClass2", false); 805 testDotClass2("test2.DotClass2_", true); 806 } 807 testDotClass2(String cname, boolean java5)808 private void testDotClass2(String cname, boolean java5) throws Exception { 809 CtClass cc = sloader.makeClass(cname); 810 CtClass cc3 = sloader.makeClass("test2.DotClass3"); 811 if (java5) 812 cc.getClassFile2().setVersionToJava5(); 813 814 CtMethod m = CtNewMethod.make( 815 "public int test() {" + 816 " return test2.DotClass3.class.getName().length(); }", cc); 817 cc.addMethod(m); 818 cc.writeFile(); 819 // don't execute cc3.writeFile(); 820 Object obj = make(cc.getName()); 821 try { 822 assertEquals(15, invoke(obj, "test")); 823 } 824 catch (java.lang.reflect.InvocationTargetException e) { 825 Throwable t = e.getCause(); 826 assertTrue(t instanceof java.lang.NoClassDefFoundError); 827 } 828 } 829 testDotClass4()830 public void testDotClass4() throws Exception { 831 testDotClass4("test2.DotClass4", false); 832 testDotClass4("test2.DotClass4_", true); 833 } 834 testDotClass4(String cname, boolean java5)835 private void testDotClass4(String cname, boolean java5) throws Exception { 836 CtClass cc = sloader.makeClass(cname); 837 if (java5) 838 cc.getClassFile2().setVersionToJava5(); 839 840 CtMethod m = CtNewMethod.make( 841 "public int test() {" + 842 " String s = Object.class.getName()" + 843 " + Object[].class.getName();" + 844 " return s.length(); }", cc); 845 cc.addMethod(m); 846 cc.writeFile(); 847 Object obj = make(cc.getName()); 848 assertEquals(35, invoke(obj, "test")); 849 } 850 testSuperInterface()851 public void testSuperInterface() throws Exception { 852 CtClass cc = sloader.makeClass("test2.SuperInterface3"); 853 CtClass cc2 = sloader.get("test2.SuperInterface2"); 854 cc.addInterface(cc2); 855 cc.addField(new CtField(cc2, "inner", cc)); 856 CtMethod m = CtNewMethod.make( 857 "public int getAge() { return inner.getAge(); }", cc); 858 cc.addMethod(m); 859 cc.writeFile(); 860 } 861 testPrune()862 public void testPrune() throws Exception { 863 CtClass cc = sloader.get("test2.Prune"); 864 cc.stopPruning(false); 865 System.out.println(cc); 866 cc.addField(new CtField(CtClass.intType, "f", cc)); 867 cc.toBytecode(); 868 try { 869 cc.defrost(); 870 fail("can call defrost()"); 871 } 872 catch (RuntimeException e) { 873 assertTrue(e.getMessage().indexOf("prune") >= 0); 874 } 875 876 System.out.println(cc); 877 } 878 testNewExprInTry()879 public void testNewExprInTry() throws Exception { 880 ExprEditor ed = new ExprEditor() { 881 public void edit(NewExpr expr) throws CannotCompileException { 882 expr.replace("$_ = new test2.HashMapWrapper($1, 1);"); 883 } 884 }; 885 886 CtClass cc = sloader.get("test2.NewExprInTry"); 887 CtMethod m1 = cc.getDeclaredMethod("foo"); 888 m1.instrument(ed); 889 cc.writeFile(); 890 Object obj = make(cc.getName()); 891 assertEquals(1, invoke(obj, "run")); 892 } 893 testConstField()894 public void testConstField() throws Exception { 895 CtClass cc = sloader.get("test2.ConstField"); 896 CtField f; 897 f = cc.getField("b"); 898 assertEquals(true, ((Boolean)f.getConstantValue()).booleanValue()); 899 f = cc.getField("i"); 900 assertEquals(3, ((Integer)f.getConstantValue()).intValue()); 901 f = cc.getField("j"); 902 assertEquals(7L, ((Long)f.getConstantValue()).longValue()); 903 f = cc.getField("f"); 904 assertEquals(8.0F, ((Float)f.getConstantValue()).floatValue(), 0.0); 905 f = cc.getField("d"); 906 assertEquals(9.0, ((Double)f.getConstantValue()).doubleValue(), 0.0); 907 f = cc.getField("s"); 908 assertEquals("const", f.getConstantValue()); 909 f = cc.getField("obj"); 910 assertEquals(null, f.getConstantValue()); 911 f = cc.getField("integer"); 912 assertEquals(null, f.getConstantValue()); 913 f = cc.getField("k"); 914 assertEquals(null, f.getConstantValue()); 915 916 cc.getClassFile().prune(); 917 918 f = cc.getField("i"); 919 assertEquals(3, ((Integer)f.getConstantValue()).intValue()); 920 f = cc.getField("k"); 921 assertEquals(null, f.getConstantValue()); 922 } 923 testWhere()924 public void testWhere() throws Exception { 925 CtClass cc = sloader.get("test2.Where"); 926 CtConstructor cons = cc.getClassInitializer(); 927 cons.instrument(new ExprEditor() { 928 public void edit(MethodCall m) throws CannotCompileException { 929 System.out.println(m.where().getName()); 930 } 931 }); 932 933 } 934 testNewOp()935 public void testNewOp() throws Exception { 936 CtClass cc = sloader.get("test2.NewOp"); 937 938 CtMethod add = CtNewMethod.make( 939 "public test2.NewOp2 " + 940 " addMonitoringRemoteEventListener(" + 941 " test2.NewOp2 listener)" + 942 " throws java.rmi.RemoteException {" + 943 " $0.listenerList.addElement(listener);" + 944 " return new test2.NewOp2(0L, this, null, 0L);" + 945 "}", cc); 946 947 add.setModifiers(Modifier.PUBLIC); 948 cc.addMethod(add); 949 /* 950 CtMethod type= CtNewMethod.make( 951 "public test2.Where getNewType() { return new test2.Where(); }", 952 cc); 953 cc.addMethod(type); 954 */ 955 cc.writeFile(); 956 } 957 testSwitch()958 public void testSwitch() throws Exception { 959 CtClass cc = sloader.makeClass("test2.Switch"); 960 961 cc.addMethod(CtNewMethod.make( 962 "public int test1() {" + 963 " int i = 1;" + 964 " int j;" + 965 " switch (i) {" + 966 " case 0: j = i; break;" + 967 " case 1: j = -i; break;" + 968 " default: j = 0; break;" + 969 " }" + 970 " return j; }", cc)); 971 972 cc.addMethod(CtNewMethod.make( 973 "public int test2() {" + 974 " int i = 2;" + 975 " int j = 7;" + 976 " switch (i) {" + 977 " case 0: j = i; break;" + 978 " case 1: j = -i; break;" + 979 " }" + 980 " return j; }", cc)); 981 982 cc.addMethod(CtNewMethod.make( 983 "public int test3() {" + 984 " int i = Byte.MAX_VALUE;" + 985 " int j;" + 986 " switch (i) {" + 987 " case Byte.MAX_VALUE: j = i; break;" + 988 " case Byte.MIN_VALUE: j = -i; break;" + 989 " default: j = 0; break;" + 990 " }" + 991 " return j; }", cc)); 992 993 try { 994 cc.addMethod(CtNewMethod.make( 995 "public int test4() {" + 996 " int i = Byte.MAX_VALUE;" + 997 " int j;" + 998 " switch (i) {" + 999 " case Byte.MAX_VALUE: j = i; return j;" + 1000 " case Byte.MIN_VALUE: j = -i; return j;" + 1001 " default: j = 0;" + 1002 " }" + 1003 "}", cc)); 1004 fail("does not report an error (no return)"); 1005 } 1006 catch (CannotCompileException e) { System.out.println(e); } 1007 1008 try { 1009 cc.addMethod(CtNewMethod.make( 1010 "public int test5() {" + 1011 " int i = Byte.MAX_VALUE;" + 1012 " int j;" + 1013 " switch (i) {" + 1014 " case Byte.MAX_VALUE: j = i; return j;" + 1015 " case Byte.MIN_VALUE: j = -i; return j;" + 1016 " }" + 1017 "}", cc)); 1018 fail("does not report an error (not default)"); 1019 } 1020 catch (CannotCompileException e) { System.out.println(e); } 1021 1022 try { 1023 cc.addMethod(CtNewMethod.make( 1024 "public int test6() {" + 1025 " int i = Byte.MAX_VALUE;" + 1026 " int j;" + 1027 " switch (i) {" + 1028 " case Byte.MAX_VALUE: j = i; break;" + 1029 " default: j = -i; return j;" + 1030 " }" + 1031 " }", cc)); 1032 fail("does not report an error (break)"); 1033 } 1034 catch (CannotCompileException e) { System.out.println(e); } 1035 1036 cc.addField(CtField.make("public static int k;", cc)); 1037 1038 cc.addMethod(CtNewMethod.make( 1039 "public void foo() {" + 1040 " int i = 0;" + 1041 " k = 3;" + 1042 " switch (i) {" + 1043 " case Byte.MAX_VALUE: k = 1;" + 1044 " case Byte.MIN_VALUE: k = 2;" + 1045 " }" + 1046 "}", cc)); 1047 1048 cc.addMethod(CtNewMethod.make( 1049 "public int test7() {" + 1050 " int i = Byte.MAX_VALUE;" + 1051 " int j = 3; foo();" + 1052 " System.out.println(k);" + 1053 " switch (i) {" + 1054 " case Byte.MAX_VALUE: return k;" + 1055 " case Byte.MIN_VALUE: return j;" + 1056 " default: return 0;" + 1057 " }" + 1058 "}", cc)); 1059 1060 cc.writeFile(); 1061 Object obj = make(cc.getName()); 1062 assertEquals(-1, invoke(obj, "test1")); 1063 assertEquals(7, invoke(obj, "test2")); 1064 assertEquals(Byte.MAX_VALUE, invoke(obj, "test3")); 1065 assertEquals(3, invoke(obj, "test7")); 1066 } 1067 testGet()1068 public void testGet() throws Exception { 1069 CtClass cc = sloader.get("char[]"); 1070 CtClass cc2 = cc.getComponentType(); 1071 System.out.println(cc2); 1072 } 1073 testSynchronized()1074 public void testSynchronized() throws Exception { 1075 CtClass cc = sloader.makeClass("test2.Synch"); 1076 1077 cc.addMethod(CtNewMethod.make( 1078 "public synchronized int test1() {" + 1079 " int i = 0;" + 1080 " synchronized (this) {" + 1081 " i = 3;" + 1082 " }" + 1083 " return i; }", cc)); 1084 1085 cc.addMethod(CtNewMethod.make( 1086 "public synchronized int test2() {" + 1087 " int i = 0;" + 1088 " synchronized (this) {" + 1089 " i = 3;" + 1090 " return i;" + 1091 " }" + 1092 "}", cc)); 1093 1094 cc.addMethod(CtNewMethod.make( 1095 "public synchronized int test3() {" + 1096 " int i = 0;" + 1097 " synchronized (this) {" + 1098 " if (this instanceof String)" + 1099 " return i;" + 1100 " else" + 1101 " i = 3;" + 1102 " }" + 1103 " return i;" + 1104 "}", cc)); 1105 1106 cc.addMethod(CtNewMethod.make( 1107 "public synchronized int test4() {" + 1108 " int i = 0;" + 1109 " synchronized (this) {" + 1110 " }" + 1111 " return i; }", cc)); 1112 1113 try { 1114 cc.addMethod(CtNewMethod.make( 1115 "public synchronized int test5() {" + 1116 " while (true)" + 1117 " synchronized (this) {" + 1118 " break;" + 1119 " }" + 1120 " return i; }", cc)); 1121 fail("does not report an error"); 1122 } 1123 catch (CannotCompileException e) { System.out.println(e); } 1124 1125 cc.addMethod(CtNewMethod.make( 1126 "public synchronized int test6() {" + 1127 " int i = 0;" + 1128 " while (true) {" + 1129 " synchronized (this) {" + 1130 " i = 3;" + 1131 " }" + 1132 " break; }" + 1133 " return i; }", cc)); 1134 1135 cc.writeFile(); 1136 Object obj = make(cc.getName()); 1137 assertEquals(3, invoke(obj, "test1")); 1138 assertEquals(3, invoke(obj, "test2")); 1139 assertEquals(3, invoke(obj, "test3")); 1140 assertEquals(0, invoke(obj, "test4")); 1141 } 1142 testTryFinally()1143 public void testTryFinally() throws Exception { 1144 CtClass cc = sloader.get("test2.Finally"); 1145 1146 cc.addMethod(CtNewMethod.make( 1147 "public int test1() {" + 1148 " a = 0;" + 1149 " try {" + 1150 " update();" + 1151 " } catch (NullPointerException e) {" + 1152 " a = 1;" + 1153 " } finally {" + 1154 " a = 2;" + 1155 " }" + 1156 " return a; }", cc)); 1157 1158 cc.addMethod(CtNewMethod.make( 1159 "public int test2() {" + 1160 " a = 0;" + 1161 " try {" + 1162 " update(); return a;" + 1163 " } catch (NullPointerException e) {" + 1164 " a = 1; throw e;" + 1165 " } finally {" + 1166 " a = 2; return a;" + 1167 " }" + 1168 "}", cc)); 1169 1170 cc.addMethod(CtNewMethod.make( 1171 "public int test3() {" + 1172 " a = 0;" + 1173 " try {" + 1174 " update(); return a;" + 1175 " } catch (NullPointerException e) {" + 1176 " a = 1;" + 1177 " } finally {" + 1178 " a = 2;" + 1179 " }" + 1180 " return a;" + 1181 "}", cc)); 1182 1183 cc.addMethod(CtNewMethod.make( 1184 "public int test4() {" + 1185 " a = 0;" + 1186 " try {" + 1187 " update(); return a;" + 1188 " } catch (NullPointerException e) {" + 1189 " a = 1; return a;" + 1190 " } finally {" + 1191 " a = 2;" + 1192 " }" + 1193 "}", cc)); 1194 1195 cc.addMethod(CtNewMethod.make( 1196 "public double test5() {" + 1197 " b = 1.0;" + 1198 " try {" + 1199 " return b;" + 1200 // " } catch (NullPointerException e) {" + 1201 // " b = 2.0; return b;" + 1202 " } finally {" + 1203 " b += 3.0;" + 1204 " }" + 1205 "}", cc)); 1206 1207 cc.addMethod(CtNewMethod.make( 1208 "public int test5a() {" + 1209 " return (int)test5();" + 1210 "}", cc)); 1211 1212 cc.addMethod(CtNewMethod.make( 1213 "public int test6() {" + 1214 " a = 0;" + 1215 " try {" + 1216 " if (a > 0)" + 1217 " return a;" + 1218 " update(); a = 1;" + 1219 " }" + 1220 " catch (RuntimeException e) {" + 1221 " if (a > 0) a = 2; else a = 3;" + 1222 " }" + 1223 " catch (Throwable e) {" + 1224 " a = 4;" + 1225 " } finally {" + 1226 " try { if (a < 0) update(); return a; }" + 1227 " finally { if (a > 0) return a; a = 5; }" + 1228 " " + 1229 " }" + 1230 "}", cc)); 1231 1232 cc.writeFile(); 1233 Object obj = make(cc.getName()); 1234 assertEquals(2, invoke(obj, "test1")); 1235 assertEquals(2, invoke(obj, "test2")); 1236 assertEquals(2, invoke(obj, "test3")); 1237 assertEquals(1, invoke(obj, "test4")); 1238 assertEquals(1, invoke(obj, "test5a")); 1239 assertEquals(3, invoke(obj, "test6")); 1240 } 1241 testConstructorName()1242 public void testConstructorName() throws Exception { 1243 CtClass cc = sloader.get("test2.Construct"); 1244 CtConstructor[] cons = cc.getDeclaredConstructors(); 1245 assertEquals("Construct", cons[0].getName()); 1246 assertEquals("Construct", cons[1].getName()); 1247 assertEquals("<clinit>", cc.getClassInitializer().getName()); 1248 } 1249 testRemoveCall()1250 public void testRemoveCall() throws Exception { 1251 CtClass cc = sloader.get("test2.RemoveCall"); 1252 CtMethod m1 = cc.getDeclaredMethod("bar"); 1253 m1.instrument(new ExprEditor() { 1254 public void edit(MethodCall m) throws CannotCompileException { 1255 m.replace("{ $_ = ($r)null; }"); 1256 } 1257 }); 1258 cc.writeFile(); 1259 Object obj = make(cc.getName()); 1260 assertEquals(0, invoke(obj, "bar")); 1261 } 1262 testRemove()1263 public void testRemove() throws Exception { 1264 CtClass cc = sloader.get("test2.Remove"); 1265 testRemove2(cc, "f1"); 1266 testRemove2(cc, "f6"); 1267 testRemove2(cc, "f3"); 1268 CtField p = cc.getField("p"); 1269 try { 1270 cc.removeField(p); 1271 fail("non-existing field has been removed"); 1272 } 1273 catch (NotFoundException e) {} 1274 1275 testRemove3(cc, "bar"); 1276 testRemove3(cc, "bar2"); 1277 testRemove4(cc, "(I)V"); 1278 cc.writeFile(); 1279 Object obj = make(cc.getName()); 1280 assertEquals(7, invoke(obj, "foo")); 1281 } 1282 testRemove2(CtClass cc, String fieldName)1283 private void testRemove2(CtClass cc, String fieldName) throws Exception { 1284 CtField f = cc.getField(fieldName); 1285 cc.removeField(f); 1286 try { 1287 CtField f2 = cc.getField(fieldName); 1288 fail("the removed field still exists"); 1289 } 1290 catch (NotFoundException e) {} 1291 } 1292 testRemove3(CtClass cc, String methodName)1293 private void testRemove3(CtClass cc, String methodName) throws Exception { 1294 CtMethod m = cc.getDeclaredMethod(methodName); 1295 cc.removeMethod(m); 1296 try { 1297 CtMethod m2 = cc.getDeclaredMethod(methodName); 1298 fail("the removed method still exists"); 1299 } 1300 catch (NotFoundException e) {} 1301 } 1302 testRemove4(CtClass cc, String desc)1303 private void testRemove4(CtClass cc, String desc) throws Exception { 1304 CtConstructor c = cc.getConstructor(desc); 1305 cc.removeConstructor(c); 1306 try { 1307 CtConstructor c2 = cc.getConstructor(desc); 1308 fail("the removed method still exists"); 1309 } 1310 catch (NotFoundException e) {} 1311 } 1312 testGetAndRename()1313 public void testGetAndRename() throws Exception { 1314 try { 1315 CtClass cc = sloader.getAndRename("NotExisting", "Existing"); 1316 } 1317 catch (NotFoundException e) { 1318 System.out.println(e); 1319 } 1320 } 1321 testConstBody()1322 public void testConstBody() throws Exception { 1323 CtClass cc = sloader.get("test2.ConstBody"); 1324 CtConstructor cons = new CtConstructor(new CtClass[] { 1325 sloader.get("java.lang.String"), 1326 sloader.get("java.lang.Integer") }, cc); 1327 cons.setBody("super((String)$1, (Integer)$2);"); 1328 cc.addConstructor(cons); 1329 cc.writeFile(); 1330 Object obj = make(cc.getName()); 1331 assertEquals(1, invoke(obj, "bar")); 1332 } 1333 1334 private String methodCallData = null; 1335 testMethodCall()1336 public void testMethodCall() throws Exception { 1337 CtClass cc = sloader.get("test2.MethodCall"); 1338 1339 CtMethod m1 = cc.getDeclaredMethod("bar"); 1340 m1.instrument(new ExprEditor() { 1341 public void edit(MethodCall m) throws CannotCompileException { 1342 if ("clone".equals(m.getMethodName())) 1343 methodCallData = m.getClassName(); 1344 } 1345 }); 1346 1347 cc.writeFile(); 1348 assertEquals("java.lang.String[]", methodCallData); 1349 1350 assertEquals("java.lang.String[]", 1351 sloader.get("[Ljava/lang/String;").getName()); 1352 assertEquals("int[][]", 1353 sloader.get("[[I").getName()); 1354 } 1355 testKmatcha()1356 public void testKmatcha() throws Exception { 1357 CtClass cc = sloader.makeClass("test2.Kmatcha"); 1358 cc.addMethod(CtNewMethod.make( 1359 "public void display(String [] params){" + 1360 " if(params == null){" + 1361 " System.out.println(\"Nothing to display\");" + 1362 " }else{" + 1363 " int k = params.length - 1;" + 1364 " if(k >= 0)" + 1365 " do " + 1366 " System.out.println(params[k]);" + 1367 " while(--k >= 0);" + 1368 " }}", cc)); 1369 } 1370 testStrict()1371 public void testStrict() throws Exception { 1372 CtClass cc = sloader.makeClass("test2.StrictTest"); 1373 cc.addMethod(CtNewMethod.make( 1374 "public strictfp int foo(){ " + 1375 " int strict = 1; return strict + 1; }", cc)); 1376 } 1377 testArrayLen()1378 public void testArrayLen() throws Exception { 1379 CtClass cc = sloader.get("test2.ArrayLenTest"); 1380 cc.addMethod(CtNewMethod.make( 1381 "public int foo(){ return this.length; }", cc)); 1382 cc.writeFile(); 1383 Object obj = make(cc.getName()); 1384 assertEquals(1, invoke(obj, "foo")); 1385 } 1386 testUnicodeIdentifier()1387 public void testUnicodeIdentifier() throws Exception { 1388 CtClass cc = sloader.makeClass("test2.UnicodeIdentifier"); 1389 String src = "public int foo(){ int \u5206 = 0; return \u5206; }"; 1390 cc.addMethod(CtNewMethod.make(src, cc)); 1391 } 1392 testBrennan()1393 public void testBrennan() throws Exception { 1394 CtClass cc = sloader.get("test2.Brennan"); 1395 cc.addMethod(CtNewMethod.make( 1396 "public int foo(){" + 1397 " java.text.SimpleDateFormat df;" + 1398 " if((df = (java.text.SimpleDateFormat)format) == null)" + 1399 " df = new java.text.SimpleDateFormat(\"yyyyMMdd\");" + 1400 " return 1;}", cc)); 1401 cc.writeFile(); 1402 Object obj = make(cc.getName()); 1403 assertEquals(1, invoke(obj, "foo")); 1404 } 1405 testArrayAndNull()1406 public void testArrayAndNull() throws Exception { 1407 CtClass cc = sloader.get("test2.ArrayAndNull"); 1408 CtMethod m = cc.getDeclaredMethod("test"); 1409 m.insertAfter("if ($_ == null) $_ = new int[0];"); 1410 } 1411 testStaticArrays()1412 public void testStaticArrays() throws Exception { 1413 CtClass cc = sloader.makeClass("StaticArrays"); 1414 CtField f = new CtField(sloader.get("test2.StaticArraysMem[]"), 1415 "myStaticField", cc); 1416 1417 f.setModifiers(Modifier.STATIC); 1418 cc.addField(f); 1419 CtConstructor init = cc.makeClassInitializer(); 1420 String body = "{\n"; 1421 body += ("myStaticField = new test2.StaticArraysMem[2];\n"); 1422 body += ("\n}"); 1423 init.setBody(body); 1424 } 1425 testObjectSuper()1426 public void testObjectSuper() throws Exception { 1427 CtClass cc = sloader.get("java.lang.Object"); 1428 try { 1429 cc.addMethod(CtNewMethod.make( 1430 "public int foo(){ return super.hashCode(); }", cc)); 1431 fail("could access the super of java.lang.Object"); 1432 } 1433 catch (CannotCompileException e) {} 1434 } 1435 testStaticFinal()1436 public void testStaticFinal() throws Exception { 1437 CtClass cc = sloader.makeClass("test2.StaticFinal"); 1438 CtField f = new CtField(CtClass.intType, "sff1", cc); 1439 f.setModifiers(Modifier.STATIC | Modifier.FINAL); 1440 cc.addField(f, "5"); 1441 assertEquals(Integer.valueOf(5), f.getConstantValue()); 1442 1443 f = new CtField(CtClass.longType, "sff2", cc); 1444 f.setModifiers(Modifier.STATIC | Modifier.FINAL); 1445 cc.addField(f, "6"); 1446 assertEquals(Long.valueOf(6), f.getConstantValue()); 1447 1448 f = new CtField(CtClass.floatType, "sff3", cc); 1449 f.setModifiers(Modifier.STATIC | Modifier.FINAL); 1450 cc.addField(f, "7"); 1451 assertEquals(Float.valueOf(7.0F), f.getConstantValue()); 1452 1453 f = new CtField(CtClass.floatType, "sff4", cc); 1454 f.setModifiers(Modifier.STATIC | Modifier.FINAL); 1455 cc.addField(f, "8.0"); 1456 assertEquals(Float.valueOf(8.0F), f.getConstantValue()); 1457 1458 f = new CtField(CtClass.doubleType, "sff5", cc); 1459 f.setModifiers(Modifier.STATIC | Modifier.FINAL); 1460 cc.addField(f, "9"); 1461 assertEquals(Double.valueOf(9.0), f.getConstantValue()); 1462 1463 f = new CtField(CtClass.doubleType, "sff6", cc); 1464 f.setModifiers(Modifier.STATIC | Modifier.FINAL); 1465 cc.addField(f, "10.0"); 1466 assertEquals(Double.valueOf(10.0), f.getConstantValue()); 1467 1468 f = new CtField(sloader.get("java.lang.String"), "sff7", cc); 1469 f.setModifiers(Modifier.STATIC | Modifier.FINAL); 1470 cc.addField(f, "\"test\""); 1471 assertEquals("test", f.getConstantValue()); 1472 1473 f = new CtField(sloader.get("java.lang.String"), "sff8", cc); 1474 f.setModifiers(Modifier.STATIC); 1475 cc.addField(f, "\"static\""); 1476 assertEquals(null, f.getConstantValue()); 1477 1478 cc.addMethod(CtNewMethod.make( 1479 "public int foo(){ return sff1 + sff7.length(); }", cc)); 1480 cc.writeFile(); 1481 Object obj = make(cc.getName()); 1482 assertEquals(9, invoke(obj, "foo")); 1483 } 1484 testLocalVar()1485 public void testLocalVar() throws Exception { 1486 CtClass cc = sloader.get("test2.LocalVar"); 1487 CtMethod m = cc.getDeclaredMethod("toString"); 1488 m.addLocalVariable("var", CtClass.booleanType); 1489 m.insertBefore("{var = true; }"); 1490 m.insertAfter("{if (var) hashCode(); }", false); 1491 cc.writeFile(); 1492 Object obj = make(cc.getName()); 1493 assertEquals(3, invoke(obj, "foo")); 1494 } 1495 testImportPackage()1496 public void testImportPackage() throws Exception { 1497 CtClass cc2 = sloader.makeClass("test2.Imported"); 1498 cc2.writeFile(); 1499 CtClass cc = sloader.makeClass("test2.Importer"); 1500 sloader.importPackage("test2"); 1501 cc.addMethod(CtNewMethod.make( 1502 "public int foo(){ " + 1503 " Imported obj = new Imported();" + 1504 " return obj.getClass().getName().length(); }", cc)); 1505 sloader.clearImportedPackages(); 1506 cc.writeFile(); 1507 Object obj = make(cc.getName()); 1508 assertEquals(14, invoke(obj, "foo")); 1509 } 1510 testArrayInit()1511 public void testArrayInit() throws Exception { 1512 CtClass cc = sloader.makeClass("test2.ArrayInit"); 1513 cc.addMethod(CtNewMethod.make( 1514 "public int foo(){ " + 1515 " int[] i = new int[] { 1, 2 };" + 1516 " double[] d = new double[] { 3.0, 4.0 };" + 1517 " String[] s = new String[] { \"foo\", \"12345\" };" + 1518 " return i[0] + (int)d[0] + s[1].length(); }", cc)); 1519 cc.addMethod(CtNewMethod.make( 1520 "public int bar(){ " + 1521 " int[] i = { 1, 2.0 };" + 1522 " double[] d = { 3.0, 4 };" + 1523 " String[] s = { \"foo\", \"12345\" };" + 1524 " return i[0] + (int)d[0] + s[1].length(); }", cc)); 1525 cc.writeFile(); 1526 Object obj = make(cc.getName()); 1527 assertEquals(9, invoke(obj, "foo")); 1528 assertEquals(9, invoke(obj, "bar")); 1529 } 1530 } 1531