You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

JvstTest5.java 19KB

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