1 package javassist; 2 3 import java.io.DataOutputStream; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.FileOutputStream; 7 import java.util.HashSet; 8 9 import org.junit.FixMethodOrder; 10 import org.junit.runners.MethodSorters; 11 12 import javassist.bytecode.*; 13 import javassist.bytecode.annotation.Annotation; 14 import javassist.expr.*; 15 16 @SuppressWarnings({"rawtypes","unchecked","unused"}) 17 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 18 public class JvstTest4 extends JvstTestRoot { JvstTest4(String name)19 public JvstTest4(String name) { 20 super(name); 21 } 22 testInsertLocalVars()23 public void testInsertLocalVars() throws Exception { 24 CtClass cc = sloader.get("test4.LocalVars"); 25 26 CtMethod m1 = cc.getDeclaredMethod("run"); 27 m1.getMethodInfo().getCodeAttribute().insertLocalVar(2, 20); 28 m1.getMethodInfo().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile()); 29 CtMethod m2 = cc.getDeclaredMethod("run2"); 30 m2.getMethodInfo().getCodeAttribute().insertLocalVar(2, 0x101); 31 m2.getMethodInfo().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile()); 32 33 cc.writeFile(); 34 Object obj = make(cc.getName()); 35 assertEquals(10, invoke(obj, "run")); 36 assertEquals(10, invoke(obj, "run2")); 37 } 38 testCodeConv()39 public void testCodeConv() throws Exception { 40 CtClass cc = sloader.get("test4.CodeConv"); 41 CtMethod m1 = cc.getDeclaredMethod("m1"); 42 CtMethod m2 = cc.getDeclaredMethod("m2"); 43 CtMethod m3 = cc.getDeclaredMethod("m3"); 44 CodeConverter conv = new CodeConverter(); 45 conv.insertAfterMethod(m1, m3); 46 conv.insertBeforeMethod(m2, m3); 47 cc.instrument(conv); 48 cc.writeFile(); 49 Object obj = make(cc.getName()); 50 assertEquals(111033, invoke(obj, "run")); 51 } 52 testCodeConv2()53 public void testCodeConv2() throws Exception { 54 CtClass cc = sloader.get("test4.CodeConv2"); 55 CtField f = cc.getDeclaredField("field"); 56 CtField f2 = cc.getDeclaredField("sf"); 57 CtMethod run = cc.getDeclaredMethod("run"); 58 CodeConverter conv = new CodeConverter(); 59 conv.replaceFieldRead(f, cc, "read"); 60 conv.replaceFieldWrite(f, cc, "write"); 61 conv.replaceFieldRead(f2, cc, "read"); 62 conv.replaceFieldWrite(f2, cc, "write"); 63 run.instrument(conv); 64 cc.writeFile(); 65 Object obj = make(cc.getName()); 66 assertEquals(14001600, invoke(obj, "run")); 67 } 68 testInsGap()69 public void testInsGap() throws Exception { 70 CtClass cc = sloader.get("test4.GapSwitch"); 71 ExprEditor ed = new ExprEditor() { 72 public void edit(MethodCall c) throws CannotCompileException { 73 c.replace("{ value++; $_ = $proceed($$); }"); 74 } 75 }; 76 77 CtMethod m1 = cc.getDeclaredMethod("run"); 78 m1.instrument(ed); 79 CtMethod m2 = cc.getDeclaredMethod("run2"); 80 m2.instrument(ed); 81 82 final CtMethod m3 = cc.getDeclaredMethod("run3"); 83 m3.instrument(new ExprEditor() { 84 public void edit(MethodCall c) throws CannotCompileException { 85 CodeIterator it = m3.getMethodInfo().getCodeAttribute().iterator(); 86 try { 87 it.insertGap(c.indexOfBytecode(), 5000); 88 } catch (BadBytecode e) { 89 throw new CannotCompileException(e); 90 } 91 } 92 }); 93 m3.getMethodInfo().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile()); 94 95 cc.writeFile(); 96 Object obj = make(cc.getName()); 97 assertEquals(1010, invoke(obj, "run")); 98 assertEquals(1100, invoke(obj, "run2")); 99 assertEquals(12222, invoke(obj, "run3")); 100 } 101 testAnnotationCheck()102 public void testAnnotationCheck() throws Exception { 103 CtClass cc = sloader.get("test4.Anno"); 104 CtMethod m1 = cc.getDeclaredMethod("foo"); 105 CtField f = cc.getDeclaredField("value"); 106 107 assertTrue(cc.hasAnnotation(test4.Anno1.class)); 108 assertFalse(cc.hasAnnotation(java.lang.annotation.Documented.class)); 109 110 assertTrue(cc.hasAnnotation(test4.Anno1.class.getName())); 111 assertFalse(cc.hasAnnotation(java.lang.annotation.Documented.class.getName())); 112 113 assertEquals("empty", ((test4.Anno1)cc.getAnnotation(test4.Anno1.class)).value()); 114 assertNull(cc.getAnnotation(Deprecated.class)); 115 116 assertTrue(m1.hasAnnotation(test4.Anno1.class)); 117 assertFalse(m1.hasAnnotation(java.lang.annotation.Documented.class)); 118 assertTrue(m1.getAnnotation(test4.Anno1.class) != null); 119 assertNull(m1.getAnnotation(Deprecated.class)); 120 121 assertTrue(f.hasAnnotation(test4.Anno1.class)); 122 assertFalse(f.hasAnnotation(java.lang.annotation.Documented.class)); 123 assertTrue(f.getAnnotation(test4.Anno1.class) != null); 124 assertNull(f.getAnnotation(Deprecated.class)); 125 } 126 testRename()127 public void testRename() throws Exception { 128 CtClass cc = sloader.get("test4.Rename"); 129 cc.setName("test4.Rename2"); 130 cc.rebuildClassFile(); 131 cc.writeFile(); 132 CtClass cc2 = sloader.get("test4.IRename"); 133 cc2.replaceClassName("test4.Rename", "test4.Rename2"); 134 cc2.rebuildClassFile(); 135 cc2.writeFile(); 136 Object obj = make(cc.getName()); 137 assertEquals("test4.Rename2", obj.getClass().getName()); 138 assertEquals(14, invoke(obj, "run")); 139 } 140 testRename2()141 public void testRename2() throws Exception { 142 CtClass cc = sloader.get("test4.Signature"); 143 cc.setName("test4.Sig"); 144 cc.rebuildClassFile(); 145 cc.writeFile(); 146 Object obj = make(cc.getName()); 147 assertEquals(3, invoke(obj, "run")); 148 } 149 testJIRA93()150 public void testJIRA93() throws Exception { 151 ClassPool cp = ClassPool.getDefault(); 152 CtClass cc = sloader.getCtClass("test4.JIRA93"); 153 CtMethod m = cc.getDeclaredMethod("foo"); 154 155 m.addLocalVariable("bar", CtClass.longType); 156 // The original bug report includes the next line. 157 // But this is not a bug. 158 //m.insertAfter("bar;", true); 159 // Instead, the following code is OK. 160 m.insertBefore("bar = 0;"); 161 m.insertAfter("bar;", false); 162 163 cc.writeFile(); 164 Object obj = make(cc.getName()); 165 } 166 testNewRemover()167 public void testNewRemover() throws Exception { 168 CtClass cc = sloader.get("test4.NewRemover"); 169 CtMethod mth = cc.getDeclaredMethod("make"); 170 mth.getMethodInfo().rebuildStackMap(cc.getClassPool()); 171 mth.getMethodInfo().rebuildStackMapForME(cc.getClassPool()); 172 //cc.debugWriteFile("debug"); 173 CodeConverter conv = new CodeConverter(); 174 conv.replaceNew(cc, cc, "make2"); 175 mth.instrument(conv); 176 cc.writeFile(); 177 Object obj = make(cc.getName()); 178 assertEquals(10, invoke(obj, "run")); 179 } 180 testClassFileWriter()181 public void testClassFileWriter() throws Exception { 182 ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0); 183 ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool(); 184 185 ClassFileWriter.FieldWriter fw = cfw.getFieldWriter(); 186 fw.add(AccessFlag.PUBLIC, "value", "J", null); 187 fw.add(AccessFlag.PROTECTED | AccessFlag.STATIC, "value2", "Ljava/lang/String;", null); 188 189 ClassFileWriter.MethodWriter mw = cfw.getMethodWriter(); 190 191 mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, null); 192 assertEquals(0, mw.size()); 193 mw.add(Opcode.ALOAD_0); 194 assertEquals(1, mw.size()); 195 mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V"); 196 mw.add(Opcode.RETURN); 197 mw.codeEnd(1, 1); 198 mw.end(null, null); 199 200 mw.begin(AccessFlag.PUBLIC, "move", "(II)V", null, null); 201 assertEquals(0, mw.size()); 202 mw.add(Opcode.ALOAD_0); 203 mw.addInvoke(Opcode.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;"); 204 assertEquals(4, mw.size()); 205 mw.add(Opcode.POP); 206 mw.add(Opcode.RETURN); 207 mw.add(Opcode.POP); 208 mw.add(Opcode.RETURN); 209 mw.codeEnd(1, 3); 210 mw.addCatch(0, 4, 6, cpw.addClassInfo("java/lang/Exception")); 211 mw.addCatch(0, 4, 6, cpw.addClassInfo("java/lang/Throwable")); 212 mw.end(null, null); 213 214 String[] exceptions = { "java/lang/Exception", "java/lang/NullPointerException" }; 215 mw.begin(AccessFlag.PUBLIC, "move2", "()V", exceptions, null); 216 mw.add(Opcode.RETURN); 217 mw.codeEnd(0, 1); 218 StackMapTable.Writer stack = new StackMapTable.Writer(32); 219 stack.sameFrame(1); 220 mw.end(stack, null); 221 222 mw.begin(AccessFlag.PUBLIC, "foo", "()I", null, null); 223 mw.add(Opcode.ICONST_2); 224 mw.add(Opcode.IRETURN); 225 mw.codeEnd(1, 1); 226 mw.end(null, null); 227 228 byte[] out = cfw.end(AccessFlag.PUBLIC, cpw.addClassInfo("test4/WrittenFile"), 229 cpw.addClassInfo("java/lang/Object"), 230 null, null); 231 FileOutputStream fos = new FileOutputStream("test4/WrittenFile.class"); 232 fos.write(out); 233 fos.close(); 234 Object obj = make("test4.WrittenFile"); 235 assertNotNull(obj); 236 assertEquals(2, invoke(obj, "foo")); 237 } 238 testClassFileWriter2()239 public void testClassFileWriter2() throws Exception { 240 ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0); 241 ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool(); 242 243 ClassFileWriter.FieldWriter fw = cfw.getFieldWriter(); 244 fw.add(AccessFlag.PUBLIC | AccessFlag.STATIC, "value", "I", null); 245 246 ClassFileWriter.MethodWriter mw = cfw.getMethodWriter(); 247 248 mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, null); 249 mw.add(Opcode.ALOAD_0); 250 mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V"); 251 mw.add(Opcode.RETURN); 252 mw.codeEnd(1, 1); 253 mw.end(null, null); 254 255 String[] exceptions = { "java/lang/Exception" }; 256 mw.begin(AccessFlag.PUBLIC | AccessFlag.ABSTRACT, "move", "(II)V", exceptions, null); 257 mw.end(null, null); 258 259 int thisClass = cpw.addClassInfo("test4/WrittenFile2"); 260 int superClass = cpw.addClassInfo("java/lang/Object"); 261 262 cfw.end(new DataOutputStream(new FileOutputStream("test4/WrittenFile2.class")), 263 AccessFlag.PUBLIC | AccessFlag.ABSTRACT, thisClass, superClass, 264 null, null); 265 266 File f = new File("test4/WrittenFile2.class"); 267 byte[] file = new byte[(int)f.length()]; 268 FileInputStream fis = new FileInputStream(f); 269 fis.read(file); 270 fis.close(); 271 272 byte[] out = cfw.end(AccessFlag.PUBLIC | AccessFlag.ABSTRACT, thisClass, 273 superClass, null, null); 274 275 assertEquals(out.length, file.length); 276 for (int i = 0; i < out.length; i++) 277 assertEquals(out[i], file[i]); 278 279 CtClass sub = dloader.makeClass("test4.WrittenFile2sub", dloader.get("test4.WrittenFile2")); 280 sub.addMethod(CtMethod.make("public void move(int i, int j) {}", sub)); 281 sub.addMethod(CtMethod.make("public int foo() { move(0, 1); return 1; }", sub)); 282 sub.writeFile(); 283 Object obj = make("test4.WrittenFile2sub"); 284 assertEquals(1, invoke(obj, "foo")); 285 } 286 testClassFileWriter3()287 public void testClassFileWriter3() throws Exception { 288 ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0); 289 ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool(); 290 int superClass = cpw.addClassInfo("java/lang/Object"); 291 292 final int syntheticTag = cpw.addUtf8Info("Synthetic"); 293 ClassFileWriter.AttributeWriter attribute = new ClassFileWriter.AttributeWriter() { 294 public void write(DataOutputStream out) throws java.io.IOException { 295 out.writeShort(syntheticTag); 296 out.writeInt(0); 297 } 298 299 public int size() { 300 return 1; 301 } 302 }; 303 304 ClassFileWriter.FieldWriter fw = cfw.getFieldWriter(); 305 fw.add(AccessFlag.PUBLIC, "value", "J", null); 306 fw.add(AccessFlag.PROTECTED | AccessFlag.STATIC, "value2", "Ljava/lang/String;", attribute); 307 308 ClassFileWriter.MethodWriter mw = cfw.getMethodWriter(); 309 310 mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, attribute); 311 mw.add(Opcode.ALOAD_0); 312 mw.add(Opcode.INVOKESPECIAL); 313 mw.add16(cpw.addMethodrefInfo(superClass, cpw.addNameAndTypeInfo(MethodInfo.nameInit, "()V"))); 314 // mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V"); 315 mw.add(Opcode.RETURN); 316 mw.codeEnd(1, 1); 317 mw.end(null, null); 318 319 mw.begin(AccessFlag.PUBLIC, "foo", "()I", null, attribute); 320 mw.add(Opcode.ICONST_2); 321 mw.add(Opcode.IRETURN); 322 mw.codeEnd(1, 1); 323 mw.end(null, null); 324 325 int thisClass = cpw.addClassInfo("test4/WrittenFile3"); 326 cfw.end(new DataOutputStream(new FileOutputStream("test4/WrittenFile3.class")), 327 AccessFlag.PUBLIC, thisClass, superClass, 328 null, attribute); 329 330 File f = new File("test4/WrittenFile3.class"); 331 byte[] file = new byte[(int)f.length()]; 332 FileInputStream fis = new FileInputStream(f); 333 fis.read(file); 334 fis.close(); 335 336 byte[] out = cfw.end(AccessFlag.PUBLIC, thisClass, superClass, 337 null, attribute); 338 339 assertEquals(out.length, file.length); 340 for (int i = 0; i < out.length; i++) 341 assertEquals(out[i], file[i]); 342 343 Object obj = make("test4.WrittenFile3"); 344 assertNotNull(obj); 345 assertEquals(2, invoke(obj, "foo")); 346 } 347 testCtArray()348 public void testCtArray() throws Exception { 349 CtClass cc = sloader.get("int"); 350 assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers()); 351 cc = sloader.get("int[]"); 352 assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers()); 353 cc = sloader.get("java.lang.String[]"); 354 assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers()); 355 CtClass[] intfs = cc.getInterfaces(); 356 assertEquals(Cloneable.class.getName(), intfs[0].getName()); 357 assertEquals(java.io.Serializable.class.getName(), intfs[1].getName()); 358 cc = sloader.get("test4.CtArrayTest[]"); 359 assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers()); 360 } 361 testAnalysisType()362 public void testAnalysisType() throws Exception { 363 testAnalysisType2(sloader.get("int[]"), 1); 364 testAnalysisType2(sloader.get("java.lang.String[][]"), 2); 365 sloader.makeClass("A"); 366 testAnalysisType2(sloader.getCtClass("A"), 0); 367 testAnalysisType2(sloader.getCtClass("A[]"), 1); 368 testAnalysisType2(sloader.getCtClass("A[][]"), 2); 369 } 370 testAnalysisType2(CtClass cc, int size)371 private void testAnalysisType2(CtClass cc, int size) throws Exception { 372 javassist.bytecode.analysis.Type t = javassist.bytecode.analysis.Type.get(cc); 373 assertEquals(cc.getName(), size, t.getDimensions()); 374 } 375 testArrayType()376 public void testArrayType() throws Exception { 377 CtClass at = sloader.get("java.lang.Object[]"); 378 CtClass[] intfs = at.getInterfaces(); 379 assertEquals(intfs.length, 2); 380 assertEquals(intfs[0].getName(), java.lang.Cloneable.class.getName()); 381 assertEquals(intfs[1].getName(), java.io.Serializable.class.getName()); 382 383 assertTrue(at.subtypeOf(sloader.get(java.lang.Object.class.getName()))); 384 assertTrue(at.subtypeOf(intfs[0])); 385 assertTrue(at.subtypeOf(intfs[1])); 386 assertTrue(at.subtypeOf(intfs[1])); 387 CtClass subt = sloader.get(java.text.CharacterIterator.class.getName()); 388 assertFalse(at.subtypeOf(subt)); 389 } 390 testGetFieldDesc()391 public void testGetFieldDesc() throws Exception { 392 CtClass cc = sloader.get("test4.GetFieldDesc"); 393 cc.getDeclaredField("f", "I"); 394 cc.getField("s", "Ljava/lang/String;"); 395 CtClass cc2 = sloader.get("test4.GetFieldDescSub"); 396 assertEquals(cc2.getField("s", "Ljava/lang/String;").getDeclaringClass().getName(), 397 "test4.GetFieldDesc"); 398 assertEquals(cc2.getField("s", "I").getDeclaringClass().getName(), 399 "test4.GetFieldDescSub"); 400 } 401 testMakeMethod()402 public void testMakeMethod() throws CannotCompileException { 403 CtClass ctClass = sloader.makeClass("test4.MakeMethod2"); 404 CtNewMethod.make("public String foox(){return test4.MakeMethod.foo();}", ctClass); 405 CtNewMethod.make("public String foo(){return test4.MakeMethod.foo();}", ctClass); 406 } 407 testVarArgs()408 public void testVarArgs() throws Exception { 409 CtClass cc = sloader.get("test4.VarArgs"); 410 CtMethod m = CtMethod.make("public int foo(int i, String[] args) { return args.length; }", cc); 411 m.setModifiers(m.getModifiers() | Modifier.VARARGS); 412 cc.addMethod(m); 413 m = CtMethod.make("public int run() { return goo(7, new int[] { 1, 2, 3 }); }", cc); 414 cc.addMethod(m); 415 cc.writeFile(); 416 Object obj = make(cc.getName()); 417 assertEquals(3, invoke(obj, "run")); 418 } 419 testGetAllRef()420 public void testGetAllRef() throws Exception { 421 CtClass cc = sloader.get("test4.GetAllRef"); 422 ClassFile cf = cc.getClassFile(); 423 AttributeInfo ainfo 424 = cf.getAttribute(AnnotationsAttribute.visibleTag); 425 ClassMap map = new ClassMap(); 426 map.put("test4.GetAllRefAnno", "test4.GetAllRefAnno2"); 427 map.put("test4.GetAllRefEnum", "test4.GetAllRefEnum2"); 428 map.put("java.lang.String", "java.lang.StringBuilder"); 429 cf.addAttribute(ainfo.copy(cf.getConstPool(), map)); 430 cc.writeFile(); 431 cc.detach(); 432 433 cc = dloader.get(cc.getName()); 434 test4.GetAllRefAnno2 anno 435 = (test4.GetAllRefAnno2)cc.getAnnotation(test4.GetAllRefAnno2.class); 436 assertEquals(test4.GetAllRefEnum2.A, anno.getA()); 437 assertEquals(StringBuilder.class, anno.getC()); 438 } 439 testGetAllRefB()440 public void testGetAllRefB() throws Exception { 441 CtClass cc = sloader.get("test4.GetAllRefB"); 442 ClassMap map = new ClassMap(); 443 map.put("test4.GetAllRefAnno", "test4.GetAllRefAnno2"); 444 map.put("test4.GetAllRefEnum", "test4.GetAllRefEnum2"); 445 map.put("java.lang.String", "java.lang.StringBuilder"); 446 cc.replaceClassName(map); 447 //cc.replaceClassName("test4.GetAllRefAnno", "test4.GetAllRefAnno2"); 448 cc.writeFile(); 449 450 cc = dloader.get(cc.getName()); 451 test4.GetAllRefAnno2 anno 452 = (test4.GetAllRefAnno2)cc.getAnnotation(test4.GetAllRefAnno2.class); 453 assertEquals(test4.GetAllRefEnum2.A, anno.getA()); 454 assertEquals(StringBuilder.class, anno.getC()); 455 /* 456 AnnotationsAttribute aainfo = (AnnotationsAttribute) 457 cc.getClassFile().getAttribute(AnnotationsAttribute.visibleTag); 458 Annotation[] a = aainfo.getAnnotations(); 459 System.err.println(a[0].getTypeName()); 460 System.err.println(a[0]); 461 */ 462 } 463 testGetAllRefC()464 public void testGetAllRefC() throws Exception { 465 CtClass cc = sloader.get("test4.GetAllRefC"); 466 HashSet set = new HashSet(); 467 set.add("java.lang.Object"); 468 set.add("java.lang.String"); 469 set.add("test4.GetAllRefC"); 470 set.add("test4.GetAllRefAnno"); 471 set.add("test4.GetAllRefEnum"); 472 set.add("test4.GetAllRefAnnoC"); 473 set.add("test4.GetAllRefAnnoC2"); 474 set.add("test4.GetAllRefAnnoC3"); 475 set.add("test4.GetAllRefAnnoC4"); 476 java.util.Collection<String> refs 477 = (java.util.Collection<String>)cc.getRefClasses(); 478 assertEquals(set.size(), refs.size()); 479 for (String s: refs) { 480 assertTrue(set.contains(s)); 481 } 482 } 483 testGetAllRefInner()484 public void testGetAllRefInner() throws Exception { 485 HashSet set = new HashSet(); 486 set.add("java.lang.Object"); 487 set.add("test4.GetAllRefInnerTest"); 488 set.add("test4.GetAllRefInnerTest$1"); 489 set.add("test4.GetAllRefInnerTest$2"); 490 CtClass cc = sloader.get("test4.GetAllRefInnerTest"); 491 int size = 0; 492 for (Object s: cc.getRefClasses()) { 493 assertTrue((String)s, set.contains(s)); 494 ++size; 495 } 496 497 assertEquals(set.size(), size); 498 } 499 testNestedClass()500 public void testNestedClass() throws Exception { 501 CtClass cc = sloader.get("test4.NestedClass$1"); 502 CtClass[] tab = cc.getNestedClasses(); 503 assertEquals(1, tab.length); 504 assertEquals("test4.NestedClass$1$1", tab[0].getName()); 505 506 cc = sloader.get("test4.NestedClass$1$1"); 507 tab = cc.getNestedClasses(); 508 assertEquals(0, tab.length); 509 510 cc = sloader.get("test4.NestedClass"); 511 tab = cc.getNestedClasses(); 512 for (CtClass c: tab) { 513 System.err.println(c.getName()); 514 } 515 516 // Eclipse compiler sets tab.length to 4 but javac sets to 3. 517 assertTrue(tab.length == 4 || tab.length == 3); 518 for (CtClass c: tab) { 519 String name = c.getName(); 520 assertTrue(name.equals("test4.NestedClass$N") 521 || name.equals("test4.NestedClass$S") 522 || name.equals("test4.NestedClass$1") 523 || name.equals("test4.NestedClass$1In")); 524 } 525 526 cc = sloader.get("test4.NestedClass$1In"); 527 tab = cc.getNestedClasses(); 528 assertEquals(0, tab.length); 529 } 530 testGetClasses()531 public void testGetClasses() throws Exception { 532 CtClass cc = sloader.get("test4.NestedClass"); 533 CtClass[] tab = cc.getDeclaredClasses(); 534 535 // Eclipse compiler sets tab.length to 4 but javac sets to 3. 536 assertTrue(tab.length == 4 || tab.length == 3); 537 for (CtClass c: tab) { 538 String name = c.getName(); 539 assertTrue(name.equals("test4.NestedClass$N") 540 || name.equals("test4.NestedClass$S") 541 || name.equals("test4.NestedClass$1") 542 || name.equals("test4.NestedClass$1In")); 543 } 544 545 cc = sloader.get("test4.NestedClass$1In"); 546 tab = cc.getDeclaredClasses(); 547 assertEquals(0, tab.length); 548 } 549 testImportPac()550 public void testImportPac() throws Exception { 551 CtClass cc = sloader.makeClass("test4.TestImpP"); 552 sloader.importPackage("test4.NewImportPac"); 553 try { 554 cc.addMethod(CtNewMethod.make( 555 "public int foo(){ " + 556 " ImportPac obj = new ImportPac();" + 557 " return obj.getClass().getName().length(); }", cc)); 558 fail("ImportPac was found"); 559 } 560 catch (CannotCompileException e) {} 561 562 cc.addMethod(CtNewMethod.make( 563 "public int bar(){ " + 564 " NewImportPac obj = new NewImportPac();" + 565 " return obj.getClass().getName().length(); }", cc)); 566 sloader.clearImportedPackages(); 567 } 568 testLength()569 public void testLength() throws Exception { 570 CtClass cc = sloader.makeClass("test4.LengthTest"); 571 cc.addMethod(CtNewMethod.make( 572 "public int len(String s){ " + 573 " return s.length(); }", cc)); 574 cc.addField(CtField.make("int length = 100;", cc)); 575 cc.addConstructor(CtNewConstructor.defaultConstructor(cc)); 576 cc.addMethod(CtNewMethod.make( 577 "public int run(){ " + 578 " test4.LengthTest t = new test4.LengthTest();" + 579 " return len(\"foo\") + t.length + test4.length.m(); }", cc)); 580 try { 581 cc.addMethod(CtNewMethod.make( 582 "public int run(){ " + 583 " return test4no.length.m(); }", cc)); 584 fail("test4no was found!"); 585 } 586 catch (CannotCompileException e) { 587 System.out.println(e); 588 } 589 cc.writeFile(); 590 Object obj = make(cc.getName()); 591 assertEquals(110, invoke(obj, "run")); 592 } 593 testAaload()594 public void testAaload() throws Exception { 595 CtClass clazz = sloader.get("test4.Aaload"); 596 CtMethod method = clazz.getMethod("narf", "()V"); 597 method.instrument(new ExprEditor() { 598 @Override 599 public void edit(MethodCall call) throws CannotCompileException { 600 String name = call.getMethodName(); 601 if (name.equals("addActionListener")) 602 call.replace("$0." + name + "($$);"); 603 } 604 }); 605 } 606 607 @SuppressWarnings("deprecation") testMakePackage()608 public void testMakePackage() throws Exception { 609 if (ClassFile.MAJOR_VERSION >= ClassFile.JAVA_9) { 610 ClassPool pool = ClassPool.getDefault(); 611 try { 612 pool.makePackage(pool.getClassLoader(), "test4.pack2"); 613 fail("makePackage() ran"); 614 } 615 catch (CannotCompileException e) {} 616 } 617 } 618 619 @SuppressWarnings("deprecation") testPackage()620 public void testPackage() throws Throwable { // JASSIST-147 621 String packageName = "test4.pack"; 622 ClassPool pool = ClassPool.getDefault(); 623 try { 624 pool.makePackage(pool.getClassLoader(), packageName); 625 pool.makePackage(pool.getClassLoader(), packageName); 626 } 627 catch (CannotCompileException e) { 628 if (ClassFile.MAJOR_VERSION >= ClassFile.JAVA_9) 629 return; // makePackage() does not work in Java 9. 630 } 631 632 CtClass ctcl = pool.makeClass("test4.pack.Clazz"); 633 Class cl = ctcl.toClass(); 634 Object obj = cl.getConstructor().newInstance(); 635 assertEquals(packageName, obj.getClass().getPackage().getName()); 636 } 637 638 public static final String BASE_PATH = "../../"; 639 public static final String JAVASSIST_JAR = BASE_PATH + "javassist.jar"; 640 public static final String CLASSES_FOLDER = BASE_PATH + "build/classes"; 641 public static final String TEST_CLASSES_FOLDER = BASE_PATH + "build/test-classes"; 642 643 public static class Inner1 { get()644 public static int get() { 645 return 0; 646 } 647 } 648 testJIRA150()649 public void testJIRA150() throws Exception { 650 ClassPool pool = new ClassPool(true); 651 for(int paths=0; paths<50; paths++) { 652 pool.appendClassPath(JAVASSIST_JAR); 653 pool.appendClassPath(CLASSES_FOLDER); 654 pool.appendClassPath(TEST_CLASSES_FOLDER); 655 } 656 CtClass cc = pool.get("Jassist150$Inner1"); 657 CtMethod ccGet = cc.getDeclaredMethod("get"); 658 long startTime = System.currentTimeMillis(); 659 for(int replace=0; replace<1000; replace++) { 660 ccGet.setBody( 661 "{ int n1 = java.lang.Integer#valueOf(1); " + 662 " int n2 = java.lang.Integer#valueOf(2); " + 663 " int n3 = java.lang.Integer#valueOf(3); " + 664 " int n4 = java.lang.Integer#valueOf(4); " + 665 " int n5 = java.lang.Integer#valueOf(5); " + 666 " return n1+n2+n3+n4+n5; }"); 667 } 668 long endTime = System.currentTimeMillis(); 669 for(int replace=0; replace<1000; replace++) { 670 ccGet.setBody( 671 "{ int n1 = java.lang.Integer.valueOf(1); " + 672 " int n2 = java.lang.Integer.valueOf(2); " + 673 " int n3 = java.lang.Integer.valueOf(3); " + 674 " int n4 = java.lang.Integer.valueOf(4); " + 675 " int n5 = java.lang.Integer.valueOf(5); " + 676 " return n1+n2+n3+n4+n5; }"); 677 } 678 long endTime2 = System.currentTimeMillis(); 679 for(int replace=0; replace<1000; replace++) { 680 ccGet.setBody( 681 "{ int n1 = Integer.valueOf(1); " + 682 " int n2 = Integer.valueOf(2); " + 683 " int n3 = Integer.valueOf(3); " + 684 " int n4 = Integer.valueOf(4); " + 685 " int n5 = Integer.valueOf(5); " + 686 " return n1+n2+n3+n4+n5; }"); 687 } 688 long endTime3 = System.currentTimeMillis(); 689 long t1 = endTime - startTime; 690 long t2 = endTime2 - endTime; 691 long t3 = endTime3 - endTime2; 692 System.out.println("JIRA150: " + t1 + ", " + t2 + ", " + t3); 693 assertTrue("performance test (the next try may succeed): " + t2 + " < 6 * " + t1, 694 t2 < t1 * 6); 695 assertTrue(t3 + " < 3 * " + t1, t3 < t1 * 3); 696 } 697 testJIRA150b()698 public void testJIRA150b() throws Exception { 699 int origSize = javassist.compiler.MemberResolver.getInvalidMapSize(); 700 int N = 100; 701 for (int k = 0; k < N; k++) { 702 ClassPool pool = new ClassPool(true); 703 for(int paths=0; paths<50; paths++) { 704 pool.appendClassPath(JAVASSIST_JAR); 705 pool.appendClassPath(CLASSES_FOLDER); 706 pool.appendClassPath(TEST_CLASSES_FOLDER); 707 } 708 CtClass cc = pool.get("Jassist150$Inner1"); 709 CtMethod ccGet = cc.getDeclaredMethod("get"); 710 for(int replace=0; replace < 5; replace++) { 711 ccGet.setBody( 712 "{ int n1 = java.lang.Integer#valueOf(1); " + 713 " int n2 = java.lang.Integer#valueOf(2); " + 714 " int n3 = java.lang.Integer#valueOf(3); " + 715 " int n4 = java.lang.Integer#valueOf(4); " + 716 " int n5 = java.lang.Integer#valueOf(5); " + 717 " return n1+n2+n3+n4+n5; }"); 718 } 719 pool = null; 720 } 721 722 // try to run garbage collection. 723 int[][] mem = new int[100][]; 724 int[] large; 725 for (int i = 0; i < 100; i++) { 726 large = new int[1000000]; 727 large[large.length - 2] = 9 + i; 728 mem[i] = large; 729 } 730 System.gc(); 731 System.gc(); 732 int size = javassist.compiler.MemberResolver.getInvalidMapSize(); 733 System.out.println("JIRA150b " + size + " " + mem[mem.length - 1][mem[0].length - 2]); 734 // Now this seems obsolete. 735 // assertTrue("JIRA150b size: " + origSize + " " + size, size < origSize + N); 736 } 737 testJIRA152()738 public void testJIRA152() throws Exception { 739 CtClass cc = sloader.get("test4.JIRA152"); 740 CtMethod mth = cc.getDeclaredMethod("buildColumnOverride"); 741 //CtMethod mth = cc.getDeclaredMethod("tested"); 742 mth.instrument(new ExprEditor() { 743 public void edit(MethodCall c) throws CannotCompileException { 744 c.replace("try{ $_ = $proceed($$); } catch (Throwable t) { throw t; }"); 745 } 746 }); 747 cc.writeFile(); 748 Object obj = make(cc.getName()); 749 assertEquals(1, invoke(obj, "test")); 750 } 751 testJIRA151()752 public void testJIRA151() { 753 // try it using classloader of TestDescForName Desc.useContextClassLoader = false; 754 assertTrue(javassist.runtime.Desc.getClazz("[Ljava.lang.String;") != null); 755 //Thread.currentThread().setContextClassLoader(TestDescForName.class.getClassLoader()); 756 boolean old = javassist.runtime.Desc.useContextClassLoader; 757 javassist.runtime.Desc.useContextClassLoader = true; 758 assertTrue(javassist.runtime.Desc.getClazz("[Ljava.lang.String;") != null); 759 javassist.runtime.Desc.useContextClassLoader = old; 760 } 761 testJIRA166()762 public void testJIRA166() throws Exception { 763 CtClass cc = sloader.get("test4.JIRA166"); 764 cc.instrument(new ExprEditor() { 765 public void edit(FieldAccess fa) throws CannotCompileException { 766 if (fa.isReader() && fa.getFieldName().equals("length")) 767 fa.replace("length = self().length + \"!\"; $_ = ($r) this.length.substring(1);"); 768 } 769 }); 770 cc.writeFile(); 771 Object obj = make(cc.getName()); 772 assertEquals(1, invoke(obj, "run")); 773 } 774 testGenericSignature()775 public void testGenericSignature() throws Exception { 776 CtClass cc = sloader.makeClass("test4.GenSig"); 777 CtClass objClass = sloader.get(CtClass.javaLangObject); 778 SignatureAttribute.ClassSignature cs 779 = new SignatureAttribute.ClassSignature( 780 new SignatureAttribute.TypeParameter[] { 781 new SignatureAttribute.TypeParameter("T") }); 782 cc.setGenericSignature(cs.encode()); // <T:Ljava/lang/Object;>Ljava/lang/Object; 783 784 CtField f = new CtField(objClass, "value", cc); 785 SignatureAttribute.TypeVariable tvar = new SignatureAttribute.TypeVariable("T"); 786 f.setGenericSignature(tvar.encode()); // TT; 787 cc.addField(f); 788 789 CtMethod m = CtNewMethod.make("public Object get(){return value;}", cc); 790 SignatureAttribute.MethodSignature ms 791 = new SignatureAttribute.MethodSignature(null, null, tvar, null); 792 m.setGenericSignature(ms.encode()); // ()TT; 793 cc.addMethod(m); 794 795 CtMethod m2 = CtNewMethod.make("public void set(Object v){value = v;}", cc); 796 SignatureAttribute.MethodSignature ms2 797 = new SignatureAttribute.MethodSignature(null, new SignatureAttribute.Type[] { tvar }, 798 new SignatureAttribute.BaseType("void"), null); 799 m2.setGenericSignature(ms2.encode()); // (TT;)V; 800 cc.addMethod(m2); 801 802 cc.writeFile(); 803 Object obj = make(cc.getName()); 804 Class clazz = obj.getClass(); 805 assertEquals("T", clazz.getTypeParameters()[0].getName()); 806 assertEquals("T", ((java.lang.reflect.TypeVariable)clazz.getDeclaredField("value").getGenericType()).getName()); 807 java.lang.reflect.Method rm = clazz.getDeclaredMethod("get", new Class[0]); 808 assertEquals("T", ((java.lang.reflect.TypeVariable)rm.getGenericReturnType()).getName()); 809 java.lang.reflect.Method rm2 = clazz.getDeclaredMethod("set", new Class[] { Object.class }); 810 assertEquals("T", ((java.lang.reflect.TypeVariable)rm2.getGenericParameterTypes()[0]).getName()); 811 } 812 testJIRA171()813 public void testJIRA171() throws Exception { 814 SignatureAttribute.MethodSignature ms 815 = SignatureAttribute.toMethodSignature("(Ljava/lang/Object;Lorg/apache/hadoop/io/Text;" 816 + "Lorg/apache/hadoop/mapreduce/Mapper<Ljava/lang/Object;Lorg/apache/hadoop/io/Text;" 817 + "Lorg/apache/hadoop/io/Text;Lorg/apache/hadoop/io/IntWritable;>.Context;)V"); 818 String s = ms.toString(); 819 System.out.println(s); 820 assertEquals("<> (java.lang.Object, org.apache.hadoop.io.Text, " 821 + "org.apache.hadoop.mapreduce.Mapper<java.lang.Object, org.apache.hadoop.io.Text, " 822 + "org.apache.hadoop.io.Text, org.apache.hadoop.io.IntWritable>.Context) void", s); 823 } 824 testAfter()825 public void testAfter() throws Exception { 826 CtClass cc = sloader.get("test4.AfterTest"); 827 CtMethod m1 = cc.getDeclaredMethod("m1"); 828 m1.insertAfter("print();"); 829 CtMethod m2 = cc.getDeclaredMethod("m2"); 830 m2.insertAfter("print();"); 831 CtMethod m3 = cc.getDeclaredMethod("m3"); 832 m3.insertAfter("print();"); 833 CtMethod m4 = cc.getDeclaredMethod("m4"); 834 m4.insertAfter("print();"); 835 836 CtMethod mm1 = cc.getDeclaredMethod("mm1"); 837 mm1.insertAfter("print();", true); 838 CtMethod mm2 = cc.getDeclaredMethod("mm2"); 839 mm2.insertAfter("print();", true); 840 CtMethod mm3 = cc.getDeclaredMethod("mm3"); 841 mm3.insertAfter("print();", true); 842 CtMethod mm4 = cc.getDeclaredMethod("mm4"); 843 mm4.insertAfter("print();", true); 844 845 cc.writeFile(); 846 Object obj = make(cc.getName()); 847 assertEquals(131, invoke(obj, "test1")); 848 assertEquals(112, invoke(obj, "test2")); 849 assertEquals(10, invoke(obj, "test3")); 850 assertEquals(100, invoke(obj, "test4")); 851 852 assertEquals(131, invoke(obj, "test11")); 853 assertEquals(112, invoke(obj, "test22")); 854 assertEquals(10, invoke(obj, "test33")); 855 assertEquals(100, invoke(obj, "test44")); 856 } 857 testJIRA186()858 public void testJIRA186() throws Exception { 859 CtClass cc = sloader.get("test4.JIRA186"); 860 cc.getDeclaredMethod("test").insertBefore("{" + 861 " java.util.List l = new java.util.ArrayList();" + 862 " l.add(this.toString());" + 863 "}"); 864 cc.writeFile(); 865 Object obj = make(cc.getName()); 866 assertEquals(1, invoke(obj, "test")); 867 } 868 869 // JASSIST-190 testMultipleCatch()870 public void testMultipleCatch() throws Exception { 871 CtClass cc = sloader.get("test4.MultiCatch"); 872 CtMethod m1 = cc.getDeclaredMethod("m1"); 873 m1.insertAfter("print();"); 874 cc.writeFile(); 875 Object obj = make(cc.getName()); 876 assertEquals(12, invoke(obj, "test1")); 877 } 878 879 // JASSIST-185 testLocalVariableTypeTable()880 public void testLocalVariableTypeTable() throws Exception { 881 CtClass cc = sloader.get("test4.Lvtt"); 882 CtMethod m = cc.getDeclaredMethod("run"); 883 m.addParameter(CtClass.intType); 884 cc.writeFile(); 885 Object obj = make(cc.getName()); 886 } 887 888 // JASSISt-181 testAnnotationWithGenerics()889 public void testAnnotationWithGenerics() throws Exception { 890 CtClass cc0 = sloader.get("test4.JIRA181b"); 891 CtField field0 = cc0.getField("aField"); 892 String s0 = field0.getAnnotation(test4.JIRA181b.Condition.class).toString(); 893 assertEquals("@test4.JIRA181b$Condition(condition=java.lang.String.class)", s0); 894 CtField field01 = cc0.getField("aField2"); 895 String s01 = field01.getAnnotation(test4.JIRA181b.Condition.class).toString(); 896 assertEquals("@test4.JIRA181b$Condition(condition=void.class)", s01); 897 898 CtClass cc = sloader.get("test4.JIRA181"); 899 CtField field = cc.getField("aField"); 900 String s = field.getAnnotation(test4.JIRA181.Condition.class).toString(); 901 if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_9) 902 assertEquals("@test4.JIRA181$Condition(condition=test4.JIRA181<T>.B.class)", s); 903 else 904 assertEquals("@test4.JIRA181$Condition(condition=test4.JIRA181.B.class)", s); 905 906 CtField field2 = cc.getField("aField2"); 907 String s2 = field2.getAnnotation(test4.JIRA181.Condition2.class).toString(); 908 if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_9) 909 assertEquals("@test4.JIRA181$Condition2(condition=test4.JIRA181<T>.B[].class)", s2); 910 else 911 assertEquals("@test4.JIRA181$Condition2(condition=test4.JIRA181.B[].class)", s2); 912 } 913 testJIRA195()914 public void testJIRA195() throws Exception { 915 CtClass cc = sloader.get("test4.JIRA195"); 916 CtMethod mth = cc.getDeclaredMethod("test"); 917 mth.getMethodInfo().rebuildStackMap(cc.getClassPool()); 918 cc.writeFile(); 919 Object obj = make(cc.getName()); 920 assertEquals(4, invoke(obj, "run")); 921 } 922 testJIRA188()923 public void testJIRA188() throws Exception { 924 CtClass cc = sloader.makeClass("test4.JIRA188"); 925 CtField f = new CtField(CtClass.intType, "f", cc); 926 f.setModifiers(Modifier.PRIVATE); 927 cc.addField(f); 928 cc.addMethod(CtNewMethod.make( 929 "public int getf(test4.JIRA188 p){ return p.f; }", cc)); 930 cc.detach(); 931 // System.gc(); 932 try { 933 cc = sloader.get("test4.JIRA188"); 934 fail("test4.JIRA188 found"); 935 } 936 catch (NotFoundException e) {} 937 cc = sloader.makeClass("test4.JIRA188"); 938 cc.addField(new CtField(CtClass.intType, "g", cc)); 939 cc.addMethod(CtNewMethod.make( 940 "public int getf(test4.JIRA188 p){ return p.g; }", cc)); 941 } 942 testJIRA158()943 public void testJIRA158() throws Exception { 944 CtClass cc = sloader.get("test4.JIRA158"); 945 cc.addMethod(CtMethod.make("public int run() { return obj.foo(jj, dd) + obj.bar(j, d); }", cc)); 946 cc.writeFile(); 947 Object obj = make(cc.getName()); 948 assertEquals(15, invoke(obj, "run")); 949 } 950 testJIRA207()951 public void testJIRA207() throws Exception { 952 CtClass cc = sloader.get("test4.JIRA207"); 953 CtMethod cm = cc.getDeclaredMethod("foo"); 954 cm.insertBefore("throw new Exception();"); 955 956 CtMethod cm2 = cc.getDeclaredMethod("run2"); 957 cm2.insertBefore("throw new Exception();"); 958 cc.writeFile(); 959 Object obj = make(cc.getName()); 960 try { 961 invoke(obj, "run2"); 962 fail("run2"); 963 } 964 catch (Exception e) {} 965 } 966 testJIRA212()967 public void testJIRA212() throws Exception { 968 CtClass cc = sloader.get("test4.JIRA212"); 969 for (final CtBehavior behavior : cc.getDeclaredBehaviors()) { 970 behavior.instrument(new ExprEditor() { 971 public void edit(FieldAccess fieldAccess) throws CannotCompileException { 972 String fieldName = fieldAccess.getFieldName().substring(0,1).toUpperCase() + fieldAccess.getFieldName().substring(1); 973 if (fieldAccess.isReader()) { 974 // Rewrite read access 975 fieldAccess.replace("$_ = $0.get" + fieldName + "();"); 976 } else if (fieldAccess.isWriter()) { 977 // Rewrite write access 978 fieldAccess.replace("$0.set" + fieldName + "($1);"); 979 } 980 }}); 981 } 982 cc.writeFile(); 983 Object obj = make(cc.getName()); 984 } 985 testWhileTrueKO()986 public void testWhileTrueKO() throws Exception { 987 final ClassPool pool = ClassPool.getDefault(); 988 final CtClass cc = pool.makeClass("test4.TestWhileTrueKO"); 989 String source = "public void testWhile() { while(true) { break; } }"; 990 cc.addMethod(CtMethod.make(source, cc)); 991 cc.writeFile(); 992 make(cc.getName()); 993 } 994 testWhileTrueOK()995 public void testWhileTrueOK() throws Exception { 996 final ClassPool pool = ClassPool.getDefault(); 997 final CtClass cc = pool.makeClass("test4.TestWhileTrueOK"); 998 String source = "public void testWhile() { while(0==0) { break; }}"; 999 cc.addMethod(CtMethod.make(source, cc)); 1000 cc.writeFile(); 1001 make(cc.getName()); 1002 } 1003 1004 // JIRA JASSIST-224 testMethodParameters()1005 public void testMethodParameters() throws Exception { 1006 Class rc = test4.MethodParamTest.class; 1007 java.lang.reflect.Method m = rc.getDeclaredMethods()[0]; 1008 java.lang.reflect.Parameter[] params = m.getParameters(); 1009 assertEquals("i", params[0].getName()); 1010 assertEquals("s", params[1].getName()); 1011 1012 CtClass cc = sloader.get("test4.MethodParamTest"); 1013 ClassFile cf = cc.getClassFile2(); 1014 ConstPool cp = cf.getConstPool(); 1015 MethodInfo minfo = cf.getMethod("test"); 1016 MethodParametersAttribute attr 1017 = (MethodParametersAttribute)minfo.getAttribute(MethodParametersAttribute.tag); 1018 assertEquals(2, attr.size()); 1019 assertEquals("i", cp.getUtf8Info(attr.name(0))); 1020 assertEquals("s", cp.getUtf8Info(attr.name(1))); 1021 1022 attr = (MethodParametersAttribute)attr.copy(cp, null); 1023 assertEquals(2, attr.size()); 1024 assertEquals("i", cp.getUtf8Info(attr.name(0))); 1025 assertEquals("s", cp.getUtf8Info(attr.name(1))); 1026 } 1027 1028 // JIRA JASSIST-220 testStaticInterfaceMethods()1029 public void testStaticInterfaceMethods() throws Exception { 1030 CtClass cc = sloader.get("test4.JIRA220"); 1031 1032 cc.getMethod("foo", "()V").instrument(new ExprEditor() { 1033 @Override 1034 public void edit(MethodCall m) throws CannotCompileException { 1035 try { 1036 m.getClassName(); 1037 } catch (Exception e) { 1038 fail(e.getMessage()); 1039 } 1040 } 1041 }); 1042 } 1043 1044 // JIRA-230 testDeadcode()1045 public void testDeadcode() throws Exception { 1046 CtClass newClass = sloader.makeClass("test4.TestDeadcode"); 1047 addDeadCode(newClass, "public void evaluate(){if (false) {int i = 0;}}"); 1048 addDeadCode(newClass, "public void evaluate2(){if (false == true) {int i = 0;}}"); 1049 addDeadCode(newClass, "public void evaluate3(){if (true) {} else {} int i = 0; if (false) {} else {} i++; }"); 1050 addDeadCode(newClass, "public void evaluate4(){ for (;false;); int i = false ? 1 : 0; while (true) { return; }}"); 1051 addDeadCode(newClass, "public void evaluate5(){ boolean b = !false; b = false && b; b = true && true;" 1052 + " b = true || b; b = b || false; }"); 1053 addDeadCode(newClass, "public boolean evaluate6(){ return !false; }"); 1054 addDeadCode(newClass, "public boolean evaluate7(){ return !true; }"); 1055 1056 newClass.debugWriteFile(); 1057 Class<?> cClass = newClass.toClass(test4.DefineClassCapability.class); 1058 Object o = cClass.getConstructor().newInstance(); 1059 java.lang.reflect.Method m = cClass.getMethod("evaluate"); 1060 m.invoke(o); 1061 m = cClass.getMethod("evaluate2"); 1062 m.invoke(o); 1063 m = cClass.getMethod("evaluate3"); 1064 m.invoke(o); 1065 m = cClass.getMethod("evaluate4"); 1066 m.invoke(o); 1067 m = cClass.getMethod("evaluate6"); 1068 assertTrue((boolean)m.invoke(o)); 1069 m = cClass.getMethod("evaluate7"); 1070 assertFalse((boolean)m.invoke(o)); 1071 m = cClass.getMethod("evaluate5"); 1072 m.invoke(o); 1073 } 1074 addDeadCode(CtClass cc, String meth)1075 private void addDeadCode(CtClass cc, String meth) throws Exception { 1076 CtMethod m = CtNewMethod.make(meth, cc); 1077 cc.addMethod(m); 1078 } 1079 testAnnArg()1080 public void testAnnArg() throws Exception { 1081 CtClass cc = sloader.get("test4.AnnoArg"); 1082 CtMethod m = cc.getDeclaredMethod("foo"); 1083 test4.AnnoArg.AnnoArgAt a = (test4.AnnoArg.AnnoArgAt)m.getAnnotations()[0]; 1084 assertEquals("test4.AnnoArg$B", a.value().getName()); 1085 System.out.println(a.value().getName()); 1086 } 1087 testDeclaredMethods()1088 public void testDeclaredMethods() throws Exception { 1089 CtClass cc = sloader.get("test4.DeclMethodsList"); 1090 CtMethod[] meth = cc.getDeclaredMethods("foo"); 1091 assertEquals(2, meth.length); 1092 assertEquals("()V", meth[0].getSignature()); 1093 assertEquals("(I)I", meth[1].getSignature()); 1094 meth = cc.getDeclaredMethods("bar"); 1095 assertEquals(1, meth.length); 1096 assertEquals("()V", meth[0].getSignature()); 1097 meth = cc.getDeclaredMethods("baz"); 1098 assertEquals(0, meth.length); 1099 } 1100 testAnnotationLoader()1101 public void testAnnotationLoader() throws Exception { 1102 CtClass anno = sloader.makeAnnotation("test4.AnnoLoadAnno"); 1103 anno.debugWriteFile(); 1104 CtClass cc = sloader.get("test4.AnnoLoad"); 1105 CtMethod m = cc.getDeclaredMethod("foo"); 1106 ClassFile cf = cc.getClassFile(); 1107 ConstPool cp = cf.getConstPool(); 1108 AnnotationsAttribute attr 1109 = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag); 1110 Annotation a = new Annotation(anno.getName(), cp); 1111 a.addMemberValue("value", new javassist.bytecode.annotation.StringMemberValue("file/path", cp)); 1112 attr.setAnnotation(a); 1113 m.getMethodInfo().addAttribute(attr); 1114 cc.writeFile(); 1115 anno.toClass(test4.DefineClassCapability.class); 1116 Class<?> rc = ((java.lang.annotation.Annotation)m.getAnnotations()[0]).annotationType(); 1117 assertEquals(anno.getName(), rc.getName()); 1118 } 1119 } 1120