1 package javassist; 2 3 import java.lang.annotation.Annotation; 4 import java.lang.reflect.TypeVariable; 5 6 import javassist.bytecode.AccessFlag; 7 import javassist.bytecode.AnnotationsAttribute; 8 import javassist.bytecode.AttributeInfo; 9 import javassist.bytecode.ClassFile; 10 import javassist.bytecode.ConstPool; 11 import javassist.bytecode.InnerClassesAttribute; 12 import javassist.bytecode.NestHostAttribute; 13 import javassist.bytecode.NestMembersAttribute; 14 import javassist.expr.ExprEditor; 15 import javassist.expr.Handler; 16 import javassist.expr.MethodCall; 17 18 @SuppressWarnings({"rawtypes","unchecked","unused"}) 19 public class JvstTest5 extends JvstTestRoot { JvstTest5(String name)20 public JvstTest5(String name) { 21 super(name); 22 } 23 testDollarClassInStaticMethod()24 public void testDollarClassInStaticMethod() throws Exception { 25 CtClass cc = sloader.makeClass("test5.DollarClass"); 26 CtMethod m = CtNewMethod.make("public static int run(){ return $class.getName().length(); }", cc); 27 cc.addMethod(m); 28 m = CtNewMethod.make("public int run2(){ return $class.getName().length(); }", cc); 29 cc.addMethod(m); 30 cc.writeFile(); 31 Object obj = make(cc.getName()); 32 assertEquals(cc.getName().length(), invoke(obj, "run")); 33 assertEquals(cc.getName().length(), invoke(obj, "run2")); 34 } 35 testSuperDefaultMethodCall()36 public void testSuperDefaultMethodCall() throws Exception { 37 CtClass cc = sloader.get("test5.DefaultMethod"); 38 CtMethod m = CtNewMethod.make("public int run(){ return test5.DefaultMethodIntf.super.foo(); }", cc); 39 cc.addMethod(m); 40 m = CtNewMethod.make("public int run2(){ return test5.DefaultMethodIntf.baz(); }", cc); 41 cc.addMethod(m); 42 m = CtNewMethod.make("public int run3(){ return test5.DefaultMethodIntf.super.baz(); }", cc); 43 cc.addMethod(m); 44 cc.writeFile(); 45 Object obj = make(cc.getName()); 46 assertEquals(1, invoke(obj, "run")); 47 assertEquals(10, invoke(obj, "run2")); 48 assertEquals(10, invoke(obj, "run3")); 49 } 50 testTypeAnno()51 public void testTypeAnno() throws Exception { 52 CtClass cc = sloader.get("test5.TypeAnno"); 53 cc.getClassFile().compact(); 54 cc.writeFile(); 55 Object obj = make(cc.getName()); 56 TypeVariable<?> t = obj.getClass().getTypeParameters()[0]; 57 Annotation[] annos = t.getAnnotations(); 58 assertEquals("@test5.TypeAnnoA()", annos[0].toString()); 59 } 60 testJIRA241()61 public void testJIRA241() throws Exception { 62 CtClass cc = sloader.get("test5.JIRA241"); 63 CtMethod testMethod = cc.getDeclaredMethod("test"); 64 testMethod.insertAfter("System.out.println(\"inserted!\");"); 65 cc.writeFile(); 66 Object obj = make(cc.getName()); 67 assertEquals(10, invoke(obj, "run")); 68 } 69 testJIRA246()70 public void testJIRA246() throws Exception { 71 CtClass ctClass = sloader.makeClass("test5.JIRA246Test"); 72 ctClass.addInterface(sloader.get(test5.JIRA246.Test.class.getName())); 73 String methodBody = "public void test() { defaultMethod(); }"; 74 CtMethod ctMethod = CtMethod.make(methodBody, ctClass); 75 ctClass.addMethod(ctMethod); 76 } 77 testJIRA246b()78 public void testJIRA246b() throws Exception { 79 CtClass ctClass = sloader.get(test5.JIRA246.A.class.getName()); 80 String src = "public void id() { get(); }"; 81 CtMethod make = CtNewMethod.make(src, ctClass); 82 } 83 testJIRA242()84 public void testJIRA242() throws Exception { 85 Boolean ss = Boolean.valueOf(2 > 3); 86 ClassPool cp = ClassPool.getDefault(); 87 CtClass cc = cp.get("test5.JIRA242$Hello"); 88 CtMethod m = cc.getDeclaredMethod("say"); 89 m.insertBefore("{ System.out.println(\"Say Hello...\"); }"); 90 91 StringBuilder sb = new StringBuilder(); 92 sb.append("BOOL_SERIES = createBooleanSeriesStep();"); 93 //Below code cause the issue 94 sb.append("BOOL_SERIES.setValue(3>=3);"); //lets comment this and run it will work 95 // Below code snippets will work 96 // this cast into exact class and call the same function 97 sb.append("((test5.JIRA242$BooleanDataSeries)BOOL_SERIES).setValue(3>=3);"); 98 // this code snippet will set exact boolean variable to the function. 99 sb.append("boolean var = 3>=3;"); 100 sb.append("BOOL_SERIES.setValue(var);"); 101 102 m.insertBefore(sb.toString()); 103 cc.writeFile(); 104 Object obj = make(cc.getName()); 105 assertEquals(0, invoke(obj, "say")); 106 } 107 testJIRA249()108 public void testJIRA249() throws Exception { 109 CtClass cc = sloader.get("test5.BoolTest"); 110 CtMethod testMethod = cc.getDeclaredMethod("test"); 111 testMethod.insertBefore("i = foo(true & true);"); 112 cc.writeFile(); 113 Object obj = make(cc.getName()); 114 assertEquals(1, invoke(obj, "run")); 115 } 116 testInnerClassAttributeRemove()117 public void testInnerClassAttributeRemove() throws Exception { 118 CtClass cc = sloader.get("test5.InnerClassRemove"); 119 ClassFile cf = cc.getClassFile(); 120 InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute(InnerClassesAttribute.tag); 121 String second = ica.innerClass(1); 122 String secondName = ica.innerName(1); 123 String third = ica.innerClass(2); 124 String thirdName = ica.innerName(2); 125 assertEquals(3, ica.remove(3)); 126 assertEquals(2, ica.remove(0)); 127 assertEquals(second, ica.innerClass(0)); 128 assertEquals(secondName, ica.innerName(0)); 129 assertEquals(third, ica.innerClass(1)); 130 assertEquals(thirdName, ica.innerName(1)); 131 assertEquals(1, ica.remove(1)); 132 assertEquals(second, ica.innerClass(0)); 133 assertEquals(secondName, ica.innerName(0)); 134 cc.writeFile(); 135 Object obj = make(cc.getName()); 136 assertEquals(1, invoke(obj, "run")); 137 } 138 testJIRA248()139 public void testJIRA248() throws Exception { 140 CtClass cc = sloader.get("test5.JIRA248"); 141 String methodBody = "public int run() { return foo() + super.foo() + super.bar() + test5.JIRA248Intf2.super.baz(); }"; 142 CtMethod ctMethod = CtMethod.make(methodBody, cc); 143 cc.addMethod(ctMethod); 144 cc.writeFile(); 145 Object obj = make(cc.getName()); 146 assertEquals(40271, invoke(obj, "run")); 147 } 148 testInvalidCastWithDollar()149 public void testInvalidCastWithDollar() throws Exception { 150 String code = "{ new test5.JavassistInvalidCastTest().inspectReturn((Object) ($w) $_); } "; 151 CtClass c = sloader.get("test5.InvalidCastDollar"); 152 for (CtMethod method : c.getDeclaredMethods()) 153 method.insertAfter(code); 154 } 155 testJIRA256()156 public void testJIRA256() throws Exception { 157 // CtClass ec = sloader.get("test5.Entity"); 158 159 CtClass cc = sloader.makeClass("test5.JIRA256"); 160 ClassFile ccFile = cc.getClassFile(); 161 ConstPool constpool = ccFile.getConstPool(); 162 163 AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag); 164 javassist.bytecode.annotation.Annotation entityAnno 165 = new javassist.bytecode.annotation.Annotation("test5.Entity", constpool); 166 // = new javassist.bytecode.annotation.Annotation(constpool, ec); 167 168 entityAnno.addMemberValue("value", new javassist.bytecode.annotation.ArrayMemberValue(constpool)); 169 attr.addAnnotation(entityAnno); 170 ccFile.addAttribute(attr); 171 172 cc.writeFile(); 173 Object o = make(cc.getName()); 174 assertTrue(o.getClass().getName().equals("test5.JIRA256")); 175 176 java.lang.annotation.Annotation[] annotations = o.getClass().getDeclaredAnnotations(); 177 assertEquals(1, annotations.length); 178 } 179 testJIRA250()180 public void testJIRA250() throws Exception { 181 CtClass cc = sloader.makeClass("test5.JIRA250", sloader.get("test5.JIRA250Super")); 182 cc.addMethod(CtNewMethod.make( 183 " public test5.JIRA250Bar getBar() {" + 184 " return super.getBar();\n" + 185 " }\n", cc)); 186 cc.addMethod(CtNewMethod.make("public int run() { getBar(); return 1; }", cc)); 187 cc.writeFile(); 188 Object obj = make(cc.getName()); 189 assertEquals(1, invoke(obj, "run")); 190 } 191 testProceedToDefaultMethod()192 public void testProceedToDefaultMethod() throws Exception { 193 CtClass cc = ClassPool.getDefault().get("test5.ProceedDefault"); 194 CtMethod mth = cc.getDeclaredMethod("bar"); 195 mth.instrument(new ExprEditor() { 196 public void edit(MethodCall c) throws CannotCompileException { 197 c.replace("$_ = $proceed($$) + 10000;"); 198 } 199 }); 200 cc.writeFile(); 201 Object obj = make(cc.getName()); 202 assertEquals(21713, invoke(obj, "run")); 203 } 204 testBadClass()205 public void testBadClass() throws Exception { 206 CtClass badClass = ClassPool.getDefault().makeClass("badClass"); 207 String src = String.join(System.getProperty("line.separator"), 208 "public void eval () {", 209 " if (true) {", 210 " double t=0;", 211 " } else {", 212 " double t=0;", 213 " }", 214 " for (int i=0; i < 2; i++) {", 215 " int a=0;", 216 " int b=0;", 217 " int c=0;", 218 " int d=0;", 219 " if (true) {", 220 " int e = 0;", 221 " }", 222 " }", 223 "}"); 224 System.out.println(src); 225 badClass.addMethod(CtMethod.make(src, badClass)); 226 Class clazzz = badClass.toClass(Class.forName("DefineClassCapability")); 227 Object obj = clazzz.getConstructor().newInstance(); // <-- falls here 228 } 229 test83StackmapWithArrayType()230 public void test83StackmapWithArrayType() throws Exception { 231 final CtClass ctClass = sloader.get("test5.StackmapWithArray83"); 232 final CtMethod method = ctClass.getDeclaredMethod("bytecodeVerifyError"); 233 method.addLocalVariable("test_localVariable", CtClass.intType); 234 method.insertBefore("{ test_localVariable = 1; }"); 235 236 final CtMethod method2 = ctClass.getDeclaredMethod("bytecodeVerifyError2"); 237 method2.addLocalVariable("test_localVariable", CtClass.intType); 238 method2.insertBefore("{ test_localVariable = 1; }"); 239 240 ctClass.writeFile(); 241 Object obj = make(ctClass.getName()); 242 assertEquals(1, invoke(obj, "run")); 243 } 244 testLoaderClassPath()245 public void testLoaderClassPath() throws Exception { 246 ClassPool cp = new ClassPool(); 247 cp.appendClassPath(new LoaderClassPath(new Loader())); 248 assertNotNull(cp.get(Object.class.getName())); 249 assertNotNull(cp.get(this.getClass().getName())); 250 } 251 testAddDefaultMethod()252 public void testAddDefaultMethod() throws Exception { 253 CtClass cc = sloader.makeInterface("test5.AddDefaultMethod"); 254 cc.addMethod(CtNewMethod.make("static int foo() { return 1; }", cc)); 255 cc.addMethod(CtNewMethod.make("public static int foo1() { return 1; }", cc)); 256 cc.addMethod(CtNewMethod.make("public int foo2() { return 1; }", cc)); 257 cc.addMethod(CtNewMethod.make("int foo3() { return 1; }", cc)); 258 try { 259 cc.addMethod(CtNewMethod.make("private int foo4() { return 1; }", cc)); 260 fail(); 261 } catch (CannotCompileException e) {} 262 try { 263 cc.addMethod(CtNewMethod.make("private static int foo5() { return 1; }", cc)); 264 fail(); 265 } catch (CannotCompileException e) {} 266 } 267 testRemoveAnnotatino()268 public void testRemoveAnnotatino() throws Exception { 269 CtClass cc = sloader.get("test5.RemoveAnnotation"); 270 AnnotationsAttribute aa 271 = (AnnotationsAttribute)cc.getClassFile().getAttribute(AnnotationsAttribute.invisibleTag); 272 assertTrue(aa.removeAnnotation("test5.RemoveAnno1")); 273 AttributeInfo ai = cc.getClassFile().removeAttribute(AnnotationsAttribute.invisibleTag); 274 assertEquals(ai.getName(), AnnotationsAttribute.invisibleTag); 275 276 CtMethod foo = cc.getDeclaredMethod("foo"); 277 AnnotationsAttribute aa2 = (AnnotationsAttribute)foo.getMethodInfo().getAttribute(AnnotationsAttribute.invisibleTag); 278 assertTrue(aa2.removeAnnotation("test5.RemoveAnno1")); 279 280 CtMethod bar = cc.getDeclaredMethod("bar"); 281 AnnotationsAttribute aa3 = (AnnotationsAttribute)bar.getMethodInfo().getAttribute(AnnotationsAttribute.invisibleTag); 282 assertFalse(aa3.removeAnnotation("test5.RemoveAnno1")); 283 assertTrue(aa3.removeAnnotation("test5.RemoveAnno2")); 284 AttributeInfo ai2 = bar.getMethodInfo().removeAttribute(AnnotationsAttribute.invisibleTag); 285 assertEquals(ai2.getName(), AnnotationsAttribute.invisibleTag); 286 287 CtMethod run = cc.getDeclaredMethod("run"); 288 AttributeInfo ai3 = run.getMethodInfo().removeAttribute(AnnotationsAttribute.invisibleTag); 289 assertNull(ai3); 290 291 CtField baz = cc.getDeclaredField("baz"); 292 AttributeInfo ai4 = baz.getFieldInfo().removeAttribute(AnnotationsAttribute.invisibleTag); 293 assertEquals(ai4.getName(), AnnotationsAttribute.invisibleTag); 294 295 cc.writeFile(); 296 Object obj = make(cc.getName()); 297 assertEquals(3, invoke(obj, "run")); 298 } 299 testInnerClassModifiers()300 public void testInnerClassModifiers() throws Exception { 301 CtClass cc = sloader.get("test5.InnerModifier$NonStatic"); 302 try { 303 cc.setModifiers(Modifier.PUBLIC | Modifier.STATIC); 304 fail(); 305 } 306 catch (RuntimeException e) { 307 if (!e.getMessage().startsWith("cannot change ")) 308 fail(); 309 } 310 311 cc.setModifiers(Modifier.PUBLIC); 312 cc.writeFile(); 313 314 assertEquals(Modifier.PUBLIC, cc.getModifiers()); 315 InnerClassesAttribute ica = getInnerClassAttr(cc); 316 int i = ica.find("test5.InnerModifier$NonStatic"); 317 assertTrue(i >= 0); 318 assertEquals(Modifier.PUBLIC, ica.accessFlags(i)); 319 320 CtClass cc2 = sloader.get("test5.InnerModifier$Static"); 321 322 InnerClassesAttribute ica3 = getInnerClassAttr(cc2); 323 int i3 = ica3.find("test5.InnerModifier$Static"); 324 assertTrue(i3 >= 0); 325 assertEquals(AccessFlag.STATIC, ica3.accessFlags(i3)); 326 327 cc2.setModifiers(Modifier.PROTECTED | Modifier.STATIC); 328 cc2.setModifiers(Modifier.PUBLIC); 329 cc2.writeFile(); 330 331 assertEquals(Modifier.PUBLIC | Modifier.STATIC, cc2.getModifiers()); 332 InnerClassesAttribute ica2 = getInnerClassAttr(cc2); 333 int i2 = ica2.find("test5.InnerModifier$Static"); 334 assertTrue(i2 >= 0); 335 assertEquals(AccessFlag.PUBLIC | AccessFlag.STATIC, ica2.accessFlags(i2)); 336 337 CtClass cc3 = cc.getDeclaringClass(); 338 assertTrue(cc3.isModified()); 339 cc3.writeFile(); 340 341 InnerClassesAttribute ica4 = getInnerClassAttr(cc3); 342 int i4 = ica4.find("test5.InnerModifier$Static"); 343 assertTrue(i4 >= 0); 344 assertEquals(AccessFlag.PUBLIC | AccessFlag.STATIC, ica4.accessFlags(i4)); 345 int i5 = ica4.find("test5.InnerModifier$NonStatic"); 346 assertTrue(i5 >= 0); 347 assertEquals(Modifier.PUBLIC, ica4.accessFlags(i5)); 348 } 349 testInnerClassModifiers2()350 public void testInnerClassModifiers2() throws Exception { 351 CtClass cc = sloader.get("test5.InnerModifier2$Protected"); 352 Class<?> ccc = Class.forName("test5.InnerModifier2$Protected"); 353 assertEquals(cc.getModifiers(), ccc.getModifiers()); 354 assertTrue(Modifier.isProtected(cc.getModifiers())); 355 356 cc = sloader.get("test5.InnerModifier2$Public"); 357 ccc = Class.forName("test5.InnerModifier2$Public"); 358 assertEquals(cc.getModifiers(), ccc.getModifiers()); 359 assertTrue(Modifier.isPublic(cc.getModifiers())); 360 361 cc = sloader.get("test5.InnerModifier2$Private"); 362 ccc = Class.forName("test5.InnerModifier2$Private"); 363 assertEquals(cc.getModifiers(), ccc.getModifiers()); 364 assertTrue(Modifier.isPrivate(cc.getModifiers())); 365 366 cc = sloader.get("test5.InnerModifier2$Package"); 367 ccc = Class.forName("test5.InnerModifier2$Package"); 368 assertEquals(cc.getModifiers(), ccc.getModifiers()); 369 assertTrue(Modifier.isPackage(cc.getModifiers())); 370 371 cc = sloader.get("test5.InnerModifier2$ProtectedStatic"); 372 ccc = Class.forName("test5.InnerModifier2$ProtectedStatic"); 373 assertEquals(cc.getModifiers(), ccc.getModifiers()); 374 assertTrue(Modifier.isProtected(cc.getModifiers())); 375 assertTrue(Modifier.isStatic(cc.getModifiers())); 376 377 cc = sloader.get("test5.InnerModifier2$PublicStatic"); 378 ccc = Class.forName("test5.InnerModifier2$PublicStatic"); 379 assertEquals(cc.getModifiers(), ccc.getModifiers()); 380 assertTrue(Modifier.isPublic(cc.getModifiers())); 381 assertTrue(Modifier.isStatic(cc.getModifiers())); 382 383 cc = sloader.get("test5.InnerModifier2$PrivateStatic"); 384 ccc = Class.forName("test5.InnerModifier2$PrivateStatic"); 385 assertEquals(cc.getModifiers(), ccc.getModifiers()); 386 assertTrue(Modifier.isPrivate(cc.getModifiers())); 387 assertTrue(Modifier.isStatic(cc.getModifiers())); 388 389 cc = sloader.get("test5.InnerModifier2$PackageStatic"); 390 ccc = Class.forName("test5.InnerModifier2$PackageStatic"); 391 assertEquals(cc.getModifiers(), ccc.getModifiers()); 392 assertTrue(Modifier.isPackage(cc.getModifiers())); 393 assertTrue(Modifier.isStatic(cc.getModifiers())); 394 } 395 getInnerClassAttr(CtClass cc)396 private InnerClassesAttribute getInnerClassAttr(CtClass cc) { 397 return (InnerClassesAttribute)cc.getClassFile2().getAttribute(InnerClassesAttribute.tag); 398 } 399 testVarArgsModifier()400 public void testVarArgsModifier() throws Exception { 401 CtClass cc = sloader.get("test5.VarArgsMethod"); 402 assertTrue(Modifier.isVarArgs(cc.getDeclaredMethod("foo").getModifiers())); 403 assertFalse(Modifier.isVarArgs(cc.getDeclaredMethod("bar").getModifiers())); 404 } 405 testIssue155()406 public void testIssue155() throws Exception { 407 CtClass cc = sloader.get("test5.Issue155"); 408 CtMethod testMethod = cc.getDeclaredMethod("foo"); 409 testMethod.instrument( 410 new ExprEditor() { 411 public void edit(Handler m) 412 throws CannotCompileException { 413 m.insertBefore("throw $1;"); 414 } 415 }); 416 417 cc.writeFile(); 418 Object obj = make(cc.getName()); 419 assertEquals(1, invoke(obj, "test")); 420 } 421 testNestHostAttribute()422 public void testNestHostAttribute() throws Exception { 423 CtClass cc = sloader.get("test5.NestHost$Foo"); 424 ClassFile cf = cc.getClassFile(); 425 NestHostAttribute attr = (NestHostAttribute)cf.getAttribute(NestHostAttribute.tag); 426 assertEquals(test5.NestHost.class.getName(), 427 cf.getConstPool().getClassInfo(attr.hostClassIndex())); 428 } 429 testNestMembersAttribute()430 public void testNestMembersAttribute() throws Exception { 431 CtClass cc = sloader.get("test5.NestHost"); 432 ClassFile cf = cc.getClassFile(); 433 NestMembersAttribute attr = (NestMembersAttribute)cf.getAttribute(NestMembersAttribute.tag); 434 assertEquals(2, attr.numberOfClasses()); 435 String[] names = new String[2]; 436 for (int i = 0; i < 2; i++) 437 names[i] = cf.getConstPool().getClassInfo(attr.memberClass(i)); 438 439 assertFalse(names[0].equals(names[1])); 440 assertTrue(names[0].equals("test5.NestHost$Foo") || names[0].equals("test5.NestHost$Bar")); 441 assertTrue(names[1].equals("test5.NestHost$Foo") || names[1].equals("test5.NestHost$Bar")); 442 } 443 testNestMembersAttributeCopy()444 public void testNestMembersAttributeCopy() throws Exception { 445 CtClass cc = sloader.get("test5.NestHost2"); 446 cc.getClassFile().compact(); 447 cc.writeFile(); 448 make(cc.getName()); 449 } 450 testNestHostAttributeCopy()451 public void testNestHostAttributeCopy() throws Exception { 452 CtClass cc = sloader.get("test5.NestHost2$Foo"); 453 cc.getClassFile().compact(); 454 cc.toClass(test5.DefineClassCapability.class); 455 } 456 } 457