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 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. package javassist;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.lang.annotation.Annotation;
  6. import java.lang.reflect.Method;
  7. import java.lang.reflect.TypeVariable;
  8. import javassist.bytecode.AccessFlag;
  9. import javassist.bytecode.AnnotationsAttribute;
  10. import javassist.bytecode.AttributeInfo;
  11. import javassist.bytecode.ClassFile;
  12. import javassist.bytecode.ConstPool;
  13. import javassist.bytecode.InnerClassesAttribute;
  14. import javassist.bytecode.MethodInfo;
  15. import javassist.bytecode.MethodParametersAttribute;
  16. import javassist.bytecode.NestHostAttribute;
  17. import javassist.bytecode.NestMembersAttribute;
  18. import javassist.expr.ExprEditor;
  19. import javassist.expr.Handler;
  20. import javassist.expr.MethodCall;
  21. import javassist.expr.NewExpr;
  22. import junit.framework.Assert;
  23. @SuppressWarnings({"rawtypes","unchecked","unused"})
  24. public class JvstTest5 extends JvstTestRoot {
  25. public JvstTest5(String name) {
  26. super(name);
  27. }
  28. public void testDollarClassInStaticMethod() throws Exception {
  29. CtClass cc = sloader.makeClass("test5.DollarClass");
  30. CtMethod m = CtNewMethod.make("public static int run(){ return $class.getName().length(); }", cc);
  31. cc.addMethod(m);
  32. m = CtNewMethod.make("public int run2(){ return $class.getName().length(); }", cc);
  33. cc.addMethod(m);
  34. cc.writeFile();
  35. Object obj = make(cc.getName());
  36. assertEquals(cc.getName().length(), invoke(obj, "run"));
  37. assertEquals(cc.getName().length(), invoke(obj, "run2"));
  38. }
  39. public void testSuperDefaultMethodCall() throws Exception {
  40. CtClass cc = sloader.get("test5.DefaultMethod");
  41. CtMethod m = CtNewMethod.make("public int run(){ return test5.DefaultMethodIntf.super.foo(); }", cc);
  42. cc.addMethod(m);
  43. m = CtNewMethod.make("public int run2(){ return test5.DefaultMethodIntf.baz(); }", cc);
  44. cc.addMethod(m);
  45. m = CtNewMethod.make("public int run3(){ return test5.DefaultMethodIntf.super.baz(); }", cc);
  46. cc.addMethod(m);
  47. cc.writeFile();
  48. Object obj = make(cc.getName());
  49. assertEquals(1, invoke(obj, "run"));
  50. assertEquals(10, invoke(obj, "run2"));
  51. assertEquals(10, invoke(obj, "run3"));
  52. }
  53. public void testTypeAnno() throws Exception {
  54. CtClass cc = sloader.get("test5.TypeAnno");
  55. cc.getClassFile().compact();
  56. cc.writeFile();
  57. Object obj = make(cc.getName());
  58. TypeVariable<?> t = obj.getClass().getTypeParameters()[0];
  59. Annotation[] annos = t.getAnnotations();
  60. assertEquals("@test5.TypeAnnoA()", annos[0].toString());
  61. }
  62. public void testJIRA241() throws Exception {
  63. CtClass cc = sloader.get("test5.JIRA241");
  64. CtMethod testMethod = cc.getDeclaredMethod("test");
  65. testMethod.insertAfter("System.out.println(\"inserted!\");");
  66. cc.writeFile();
  67. Object obj = make(cc.getName());
  68. assertEquals(10, invoke(obj, "run"));
  69. }
  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. public void testJIRA246b() throws Exception {
  78. CtClass ctClass = sloader.get(test5.JIRA246.A.class.getName());
  79. String src = "public void id() { get(); }";
  80. CtMethod make = CtNewMethod.make(src, ctClass);
  81. }
  82. public void testJIRA242() throws Exception {
  83. Boolean ss = Boolean.valueOf(2 > 3);
  84. ClassPool cp = ClassPool.getDefault();
  85. CtClass cc = cp.get("test5.JIRA242$Hello");
  86. CtMethod m = cc.getDeclaredMethod("say");
  87. m.insertBefore("{ System.out.println(\"Say Hello...\"); }");
  88. StringBuilder sb = new StringBuilder();
  89. sb.append("BOOL_SERIES = createBooleanSeriesStep();");
  90. //Below code cause the issue
  91. sb.append("BOOL_SERIES.setValue(3>=3);"); //lets comment this and run it will work
  92. // Below code snippets will work
  93. // this cast into exact class and call the same function
  94. sb.append("((test5.JIRA242$BooleanDataSeries)BOOL_SERIES).setValue(3>=3);");
  95. // this code snippet will set exact boolean variable to the function.
  96. sb.append("boolean var = 3>=3;");
  97. sb.append("BOOL_SERIES.setValue(var);");
  98. m.insertBefore(sb.toString());
  99. cc.writeFile();
  100. Object obj = make(cc.getName());
  101. assertEquals(0, invoke(obj, "say"));
  102. }
  103. public void testJIRA249() throws Exception {
  104. CtClass cc = sloader.get("test5.BoolTest");
  105. CtMethod testMethod = cc.getDeclaredMethod("test");
  106. testMethod.insertBefore("i = foo(true & true);");
  107. cc.writeFile();
  108. Object obj = make(cc.getName());
  109. assertEquals(1, invoke(obj, "run"));
  110. }
  111. public void testInnerClassAttributeRemove() throws Exception {
  112. CtClass cc = sloader.get("test5.InnerClassRemove");
  113. ClassFile cf = cc.getClassFile();
  114. InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute(InnerClassesAttribute.tag);
  115. String second = ica.innerClass(1);
  116. String secondName = ica.innerName(1);
  117. String third = ica.innerClass(2);
  118. String thirdName = ica.innerName(2);
  119. assertEquals(3, ica.remove(3));
  120. assertEquals(2, ica.remove(0));
  121. assertEquals(second, ica.innerClass(0));
  122. assertEquals(secondName, ica.innerName(0));
  123. assertEquals(third, ica.innerClass(1));
  124. assertEquals(thirdName, ica.innerName(1));
  125. assertEquals(1, ica.remove(1));
  126. assertEquals(second, ica.innerClass(0));
  127. assertEquals(secondName, ica.innerName(0));
  128. cc.writeFile();
  129. Object obj = make(cc.getName());
  130. assertEquals(1, invoke(obj, "run"));
  131. }
  132. public void testJIRA248() throws Exception {
  133. CtClass cc = sloader.get("test5.JIRA248");
  134. String methodBody = "public int run() { return foo() + super.foo() + super.bar() + test5.JIRA248Intf2.super.baz(); }";
  135. CtMethod ctMethod = CtMethod.make(methodBody, cc);
  136. cc.addMethod(ctMethod);
  137. cc.writeFile();
  138. Object obj = make(cc.getName());
  139. assertEquals(40271, invoke(obj, "run"));
  140. }
  141. public void testInvalidCastWithDollar() throws Exception {
  142. String code = "{ new test5.JavassistInvalidCastTest().inspectReturn((Object) ($w) $_); } ";
  143. CtClass c = sloader.get("test5.InvalidCastDollar");
  144. for (CtMethod method : c.getDeclaredMethods())
  145. method.insertAfter(code);
  146. }
  147. public void testJIRA256() throws Exception {
  148. // CtClass ec = sloader.get("test5.Entity");
  149. CtClass cc = sloader.makeClass("test5.JIRA256");
  150. ClassFile ccFile = cc.getClassFile();
  151. ConstPool constpool = ccFile.getConstPool();
  152. AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
  153. javassist.bytecode.annotation.Annotation entityAnno
  154. = new javassist.bytecode.annotation.Annotation("test5.Entity", constpool);
  155. // = new javassist.bytecode.annotation.Annotation(constpool, ec);
  156. entityAnno.addMemberValue("value", new javassist.bytecode.annotation.ArrayMemberValue(constpool));
  157. attr.addAnnotation(entityAnno);
  158. ccFile.addAttribute(attr);
  159. cc.writeFile();
  160. Object o = make(cc.getName());
  161. assertTrue(o.getClass().getName().equals("test5.JIRA256"));
  162. java.lang.annotation.Annotation[] annotations = o.getClass().getDeclaredAnnotations();
  163. assertEquals(1, annotations.length);
  164. }
  165. public void testJIRA250() throws Exception {
  166. CtClass cc = sloader.makeClass("test5.JIRA250", sloader.get("test5.JIRA250Super"));
  167. cc.addMethod(CtNewMethod.make(
  168. " public test5.JIRA250Bar getBar() {" +
  169. " return super.getBar();\n" +
  170. " }\n", cc));
  171. cc.addMethod(CtNewMethod.make("public int run() { getBar(); return 1; }", cc));
  172. cc.writeFile();
  173. Object obj = make(cc.getName());
  174. assertEquals(1, invoke(obj, "run"));
  175. }
  176. public void testProceedToDefaultMethod() throws Exception {
  177. CtClass cc = ClassPool.getDefault().get("test5.ProceedDefault");
  178. CtMethod mth = cc.getDeclaredMethod("bar");
  179. mth.instrument(new ExprEditor() {
  180. public void edit(MethodCall c) throws CannotCompileException {
  181. c.replace("$_ = $proceed($$) + 10000;");
  182. }
  183. });
  184. cc.writeFile();
  185. Object obj = make(cc.getName());
  186. assertEquals(21713, invoke(obj, "run"));
  187. }
  188. public void testBadClass() throws Exception {
  189. CtClass badClass = ClassPool.getDefault().makeClass("badClass");
  190. String src = String.join(System.getProperty("line.separator"),
  191. "public void eval () {",
  192. " if (true) {",
  193. " double t=0;",
  194. " } else {",
  195. " double t=0;",
  196. " }",
  197. " for (int i=0; i < 2; i++) {",
  198. " int a=0;",
  199. " int b=0;",
  200. " int c=0;",
  201. " int d=0;",
  202. " if (true) {",
  203. " int e = 0;",
  204. " }",
  205. " }",
  206. "}");
  207. System.out.println(src);
  208. badClass.addMethod(CtMethod.make(src, badClass));
  209. Class clazzz = badClass.toClass(Class.forName("DefineClassCapability"));
  210. Object obj = clazzz.getConstructor().newInstance(); // <-- falls here
  211. }
  212. public void test83StackmapWithArrayType() throws Exception {
  213. final CtClass ctClass = sloader.get("test5.StackmapWithArray83");
  214. final CtMethod method = ctClass.getDeclaredMethod("bytecodeVerifyError");
  215. method.addLocalVariable("test_localVariable", CtClass.intType);
  216. method.insertBefore("{ test_localVariable = 1; }");
  217. final CtMethod method2 = ctClass.getDeclaredMethod("bytecodeVerifyError2");
  218. method2.addLocalVariable("test_localVariable", CtClass.intType);
  219. method2.insertBefore("{ test_localVariable = 1; }");
  220. ctClass.writeFile();
  221. Object obj = make(ctClass.getName());
  222. assertEquals(1, invoke(obj, "run"));
  223. }
  224. public void testLoaderClassPath() throws Exception {
  225. ClassPool cp = new ClassPool();
  226. cp.appendClassPath(new LoaderClassPath(new Loader()));
  227. assertNotNull(cp.get(Object.class.getName()));
  228. assertNotNull(cp.get(this.getClass().getName()));
  229. }
  230. public void testAddDefaultMethod() throws Exception {
  231. CtClass cc = sloader.makeInterface("test5.AddDefaultMethod");
  232. cc.addMethod(CtNewMethod.make("static int foo() { return 1; }", cc));
  233. cc.addMethod(CtNewMethod.make("public static int foo1() { return 1; }", cc));
  234. cc.addMethod(CtNewMethod.make("public int foo2() { return 1; }", cc));
  235. cc.addMethod(CtNewMethod.make("int foo3() { return 1; }", cc));
  236. try {
  237. cc.addMethod(CtNewMethod.make("private int foo4() { return 1; }", cc));
  238. fail();
  239. } catch (CannotCompileException e) {}
  240. try {
  241. cc.addMethod(CtNewMethod.make("private static int foo5() { return 1; }", cc));
  242. fail();
  243. } catch (CannotCompileException e) {}
  244. }
  245. public void testRemoveAnnotatino() throws Exception {
  246. CtClass cc = sloader.get("test5.RemoveAnnotation");
  247. AnnotationsAttribute aa
  248. = (AnnotationsAttribute)cc.getClassFile().getAttribute(AnnotationsAttribute.invisibleTag);
  249. assertTrue(aa.removeAnnotation("test5.RemoveAnno1"));
  250. AttributeInfo ai = cc.getClassFile().removeAttribute(AnnotationsAttribute.invisibleTag);
  251. assertEquals(ai.getName(), AnnotationsAttribute.invisibleTag);
  252. CtMethod foo = cc.getDeclaredMethod("foo");
  253. AnnotationsAttribute aa2 = (AnnotationsAttribute)foo.getMethodInfo().getAttribute(AnnotationsAttribute.invisibleTag);
  254. assertTrue(aa2.removeAnnotation("test5.RemoveAnno1"));
  255. CtMethod bar = cc.getDeclaredMethod("bar");
  256. AnnotationsAttribute aa3 = (AnnotationsAttribute)bar.getMethodInfo().getAttribute(AnnotationsAttribute.invisibleTag);
  257. assertFalse(aa3.removeAnnotation("test5.RemoveAnno1"));
  258. assertTrue(aa3.removeAnnotation("test5.RemoveAnno2"));
  259. AttributeInfo ai2 = bar.getMethodInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
  260. assertEquals(ai2.getName(), AnnotationsAttribute.invisibleTag);
  261. CtMethod run = cc.getDeclaredMethod("run");
  262. AttributeInfo ai3 = run.getMethodInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
  263. assertNull(ai3);
  264. CtField baz = cc.getDeclaredField("baz");
  265. AttributeInfo ai4 = baz.getFieldInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
  266. assertEquals(ai4.getName(), AnnotationsAttribute.invisibleTag);
  267. cc.writeFile();
  268. Object obj = make(cc.getName());
  269. assertEquals(3, invoke(obj, "run"));
  270. }
  271. public void testInnerClassModifiers() throws Exception {
  272. CtClass cc = sloader.get("test5.InnerModifier$NonStatic");
  273. try {
  274. cc.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
  275. fail();
  276. }
  277. catch (RuntimeException e) {
  278. if (!e.getMessage().startsWith("cannot change "))
  279. fail();
  280. }
  281. cc.setModifiers(Modifier.PUBLIC);
  282. cc.writeFile();
  283. assertEquals(Modifier.PUBLIC, cc.getModifiers());
  284. InnerClassesAttribute ica = getInnerClassAttr(cc);
  285. int i = ica.find("test5.InnerModifier$NonStatic");
  286. assertTrue(i >= 0);
  287. assertEquals(Modifier.PUBLIC, ica.accessFlags(i));
  288. CtClass cc2 = sloader.get("test5.InnerModifier$Static");
  289. InnerClassesAttribute ica3 = getInnerClassAttr(cc2);
  290. int i3 = ica3.find("test5.InnerModifier$Static");
  291. assertTrue(i3 >= 0);
  292. assertEquals(AccessFlag.STATIC, ica3.accessFlags(i3));
  293. cc2.setModifiers(Modifier.PROTECTED | Modifier.STATIC);
  294. cc2.setModifiers(Modifier.PUBLIC);
  295. cc2.writeFile();
  296. assertEquals(Modifier.PUBLIC | Modifier.STATIC, cc2.getModifiers());
  297. InnerClassesAttribute ica2 = getInnerClassAttr(cc2);
  298. int i2 = ica2.find("test5.InnerModifier$Static");
  299. assertTrue(i2 >= 0);
  300. assertEquals(AccessFlag.PUBLIC | AccessFlag.STATIC, ica2.accessFlags(i2));
  301. CtClass cc3 = cc.getDeclaringClass();
  302. assertTrue(cc3.isModified());
  303. cc3.writeFile();
  304. InnerClassesAttribute ica4 = getInnerClassAttr(cc3);
  305. int i4 = ica4.find("test5.InnerModifier$Static");
  306. assertTrue(i4 >= 0);
  307. assertEquals(AccessFlag.PUBLIC | AccessFlag.STATIC, ica4.accessFlags(i4));
  308. int i5 = ica4.find("test5.InnerModifier$NonStatic");
  309. assertTrue(i5 >= 0);
  310. assertEquals(Modifier.PUBLIC, ica4.accessFlags(i5));
  311. }
  312. public void testInnerClassModifiers2() throws Exception {
  313. CtClass cc = sloader.get("test5.InnerModifier2$Protected");
  314. Class<?> ccc = Class.forName("test5.InnerModifier2$Protected");
  315. assertEquals(cc.getModifiers(), ccc.getModifiers());
  316. assertTrue(Modifier.isProtected(cc.getModifiers()));
  317. cc = sloader.get("test5.InnerModifier2$Public");
  318. ccc = Class.forName("test5.InnerModifier2$Public");
  319. assertEquals(cc.getModifiers(), ccc.getModifiers());
  320. assertTrue(Modifier.isPublic(cc.getModifiers()));
  321. cc = sloader.get("test5.InnerModifier2$Private");
  322. ccc = Class.forName("test5.InnerModifier2$Private");
  323. assertEquals(cc.getModifiers(), ccc.getModifiers());
  324. assertTrue(Modifier.isPrivate(cc.getModifiers()));
  325. cc = sloader.get("test5.InnerModifier2$Package");
  326. ccc = Class.forName("test5.InnerModifier2$Package");
  327. assertEquals(cc.getModifiers(), ccc.getModifiers());
  328. assertTrue(Modifier.isPackage(cc.getModifiers()));
  329. cc = sloader.get("test5.InnerModifier2$ProtectedStatic");
  330. ccc = Class.forName("test5.InnerModifier2$ProtectedStatic");
  331. assertEquals(cc.getModifiers(), ccc.getModifiers());
  332. assertTrue(Modifier.isProtected(cc.getModifiers()));
  333. assertTrue(Modifier.isStatic(cc.getModifiers()));
  334. cc = sloader.get("test5.InnerModifier2$PublicStatic");
  335. ccc = Class.forName("test5.InnerModifier2$PublicStatic");
  336. assertEquals(cc.getModifiers(), ccc.getModifiers());
  337. assertTrue(Modifier.isPublic(cc.getModifiers()));
  338. assertTrue(Modifier.isStatic(cc.getModifiers()));
  339. cc = sloader.get("test5.InnerModifier2$PrivateStatic");
  340. ccc = Class.forName("test5.InnerModifier2$PrivateStatic");
  341. assertEquals(cc.getModifiers(), ccc.getModifiers());
  342. assertTrue(Modifier.isPrivate(cc.getModifiers()));
  343. assertTrue(Modifier.isStatic(cc.getModifiers()));
  344. cc = sloader.get("test5.InnerModifier2$PackageStatic");
  345. ccc = Class.forName("test5.InnerModifier2$PackageStatic");
  346. assertEquals(cc.getModifiers(), ccc.getModifiers());
  347. assertTrue(Modifier.isPackage(cc.getModifiers()));
  348. assertTrue(Modifier.isStatic(cc.getModifiers()));
  349. }
  350. private InnerClassesAttribute getInnerClassAttr(CtClass cc) {
  351. return (InnerClassesAttribute)cc.getClassFile2().getAttribute(InnerClassesAttribute.tag);
  352. }
  353. public void testVarArgsModifier() throws Exception {
  354. CtClass cc = sloader.get("test5.VarArgsMethod");
  355. assertTrue(Modifier.isVarArgs(cc.getDeclaredMethod("foo").getModifiers()));
  356. assertFalse(Modifier.isVarArgs(cc.getDeclaredMethod("bar").getModifiers()));
  357. }
  358. public void testIssue155() throws Exception {
  359. CtClass cc = sloader.get("test5.Issue155");
  360. CtMethod testMethod = cc.getDeclaredMethod("foo");
  361. testMethod.instrument(
  362. new ExprEditor() {
  363. public void edit(Handler m)
  364. throws CannotCompileException {
  365. m.insertBefore("throw $1;");
  366. }
  367. });
  368. cc.writeFile();
  369. Object obj = make(cc.getName());
  370. assertEquals(1, invoke(obj, "test"));
  371. }
  372. public void testNestHostAttribute() throws Exception {
  373. CtClass cc = sloader.get("test5.NestHost$Foo");
  374. ClassFile cf = cc.getClassFile();
  375. NestHostAttribute attr = (NestHostAttribute)cf.getAttribute(NestHostAttribute.tag);
  376. assertEquals(test5.NestHost.class.getName(),
  377. cf.getConstPool().getClassInfo(attr.hostClassIndex()));
  378. }
  379. public void testNestMembersAttribute() throws Exception {
  380. CtClass cc = sloader.get("test5.NestHost");
  381. ClassFile cf = cc.getClassFile();
  382. NestMembersAttribute attr = (NestMembersAttribute)cf.getAttribute(NestMembersAttribute.tag);
  383. assertEquals(2, attr.numberOfClasses());
  384. String[] names = new String[2];
  385. for (int i = 0; i < 2; i++)
  386. names[i] = cf.getConstPool().getClassInfo(attr.memberClass(i));
  387. assertFalse(names[0].equals(names[1]));
  388. assertTrue(names[0].equals("test5.NestHost$Foo") || names[0].equals("test5.NestHost$Bar"));
  389. assertTrue(names[1].equals("test5.NestHost$Foo") || names[1].equals("test5.NestHost$Bar"));
  390. }
  391. public void testNestMembersAttributeCopy() throws Exception {
  392. CtClass cc = sloader.get("test5.NestHost2");
  393. cc.getClassFile().compact();
  394. cc.writeFile();
  395. make(cc.getName());
  396. }
  397. public void testNestHostAttributeCopy() throws Exception {
  398. CtClass cc = sloader.get("test5.NestHost2$Foo");
  399. cc.getClassFile().compact();
  400. cc.toClass(test5.DefineClassCapability.class);
  401. }
  402. public void testSwitchCaseWithStringConstant() throws Exception {
  403. CtClass cc = sloader.get("test5.SwitchCase");
  404. cc.addMethod(CtNewMethod.make(
  405. "public int run() {" +
  406. " String s = \"foobar\";\n" +
  407. " switch (s) {\n" +
  408. " case STR1: return 1;\n" +
  409. " case \"foobar\": return 2;\n" +
  410. " default: return 3; }\n" +
  411. "}\n", cc));
  412. cc.writeFile();
  413. Object obj = make(cc.getName());
  414. assertEquals(2, invoke(obj, "run"));
  415. }
  416. public void testNestPrivateConstructor() throws Exception {
  417. CtClass cc = sloader.get("test5.NestHost3$Builder");
  418. cc.instrument(new ExprEditor() {
  419. public void edit(NewExpr e) throws CannotCompileException {
  420. String code = "$_ = $proceed($$);";
  421. e.replace(code);
  422. }
  423. });
  424. cc.writeFile();
  425. try {
  426. Class<?> nestHost3Class = cloader.loadClass("test5.NestHost3");
  427. Object builder = nestHost3Class.getDeclaredMethod("builder").invoke(nestHost3Class);
  428. Class<?> nestHost3BuilderClass = cloader.loadClass("test5.NestHost3$Builder");
  429. nestHost3BuilderClass.getDeclaredMethod("build").invoke(builder);
  430. } catch (Exception ex) {
  431. ex.printStackTrace();
  432. fail("it should be able to access the private constructor of the nest host");
  433. }
  434. }
  435. public void testNestPrivateConstructor2() throws Exception {
  436. CtClass cc = sloader.get("test5.NestHost4$InnerClass1");
  437. cc.instrument(new ExprEditor() {
  438. public void edit(NewExpr e) throws CannotCompileException {
  439. String code = "$_ = $proceed($$);";
  440. e.replace(code);
  441. }
  442. });
  443. cc.writeFile();
  444. cc = sloader.get("test5.NestHost4$InnerClass1$InnerClass5");
  445. cc.instrument(new ExprEditor() {
  446. public void edit(NewExpr e) throws CannotCompileException {
  447. String code = "$_ = $proceed($$);";
  448. e.replace(code);
  449. }
  450. });
  451. cc.writeFile();
  452. try {
  453. Class<?> nestHost4Class = cloader.loadClass("test5.NestHost4");
  454. nestHost4Class.getDeclaredConstructor().newInstance();
  455. } catch (Exception ex) {
  456. ex.printStackTrace();
  457. fail("it should be able to access the private constructor of the nest host");
  458. }
  459. }
  460. public void testSwitchCaseWithStringConstant2() throws Exception {
  461. CtClass cc = sloader.makeClass("test5.SwitchCase2");
  462. cc.addMethod(CtNewMethod.make(
  463. "public int run() {" +
  464. " String s = \"foo\";\n" +
  465. " switch (s) {\n" +
  466. " case test5.SwitchCase.STR1: return 1;\n" +
  467. " case \"foobar\": return 2;\n" +
  468. " }\n" +
  469. " return 3;\n" +
  470. "}\n", cc));
  471. cc.writeFile();
  472. Object obj = make(cc.getName());
  473. assertEquals(1, invoke(obj, "run"));
  474. }
  475. // Issue #241
  476. public void testInsertBeforeAndDollarR() throws Exception {
  477. CtClass cc = sloader.get(test5.InsertBeforeDollarR.class.getName());
  478. CtMethod m = cc.getDeclaredMethod("foo");
  479. m.insertBefore("{ if ($1 == 1) return ($r)$2; }");
  480. try {
  481. m.insertBefore("{ $_ = \"bar\"; }");
  482. assertTrue(false);
  483. } catch (CannotCompileException e) {}
  484. cc.writeFile();
  485. Object obj = make(cc.getName());
  486. assertEquals(1, invoke(obj, "run"));
  487. }
  488. // Issue #275
  489. public void testRedundantInsertAfter() throws Exception {
  490. CtClass cc = sloader.get(test5.InsertAfter.class.getName());
  491. CtMethod m = cc.getDeclaredMethod("foo");
  492. m.insertAfter("{ $_ += 1; }", false, true);
  493. CtMethod m2 = cc.getDeclaredMethod("bar");
  494. m2.insertAfter("{ $_ += 1; }", true, true);
  495. cc.writeFile();
  496. Object obj = make(cc.getName());
  497. assertEquals(71 + 22, invoke(obj, "run"));
  498. }
  499. // PR #294
  500. public void testEmptyArrayInit() throws Exception {
  501. CtClass cc = sloader.makeClass("test5.EmptyArrayInit");
  502. CtMethod m = CtNewMethod.make("public int[] foo(){ int[] a = {}; return a; }", cc);
  503. cc.addMethod(m);
  504. CtMethod m2 = CtNewMethod.make("public int[] bar(){ int[] a = new int[]{}; return a; }", cc);
  505. cc.addMethod(m2);
  506. CtMethod m3 = CtNewMethod.make("public String[] baz(){ String[] a = { null }; return a; }", cc);
  507. cc.addMethod(m3);
  508. CtMethod m0 = CtNewMethod.make("public int run() { return foo().length + bar().length + baz().length; }", cc);
  509. cc.addMethod(m0);
  510. cc.writeFile();
  511. Object obj = make(cc.getName());
  512. assertEquals(1, invoke(obj, "run"));
  513. }
  514. public void testTooManyConstPoolItems() throws Exception {
  515. CtClass cc = sloader.makeClass("TooManyConstPoolItems");
  516. ClassFile cf = cc.getClassFile();
  517. ConstPool cPool = cf.getConstPool();
  518. int size = cPool.getSize();
  519. while (cPool.getSize() < 65536 - 6)
  520. cPool.addIntegerInfo(cPool.getSize());
  521. cc.writeFile();
  522. cc.defrost();
  523. cPool.addIntegerInfo(-1);
  524. try {
  525. cc.writeFile();
  526. fail("too many items were accepted");
  527. }
  528. catch (CannotCompileException e) {}
  529. }
  530. public void testGithubIssue462Java21WithoutParameters() throws IOException {
  531. //This is a class file compiled by Java-21
  532. //javac Java21InnerClassWithoutParameters.java
  533. //public class Java21InnerClassWithoutParameters {
  534. // class InnerClass implements Runnable {
  535. // public void run() {
  536. // }
  537. // }
  538. //}
  539. String classFileName = "./Java21InnerClassWithoutParameters$InnerClass.class";
  540. ClassLoader classLoader = getClass().getClassLoader();
  541. File classFile = new File(classLoader.getResource(classFileName).getFile());
  542. CtClass cc = sloader.makeClass(new FileInputStream(classFile));
  543. cc.getClassFile().compact();
  544. ClassFile cf = cc.getClassFile2();
  545. ConstPool cp = cf.getConstPool();
  546. MethodInfo minfo = cf.getMethod("<init>");
  547. MethodParametersAttribute attr
  548. = (MethodParametersAttribute)minfo.getAttribute(MethodParametersAttribute.tag);
  549. assertEquals(1, attr.size());
  550. assertNull(attr.parameterName(0));
  551. }
  552. public void testSuperCall() throws Exception {
  553. String javacResult = new BearKeeper().javacResult();
  554. assertEquals("Man feed(Bear)", javacResult);
  555. CtClass cc = sloader.get("javassist.BearKeeper");
  556. CtMethod cm = CtMethod.make(
  557. "public String javassistResult() {return super.feed(new javassist.Bear());}",
  558. cc);
  559. cc.addMethod(cm);
  560. cc.setModifiers(Modifier.PUBLIC);
  561. cc.writeFile();
  562. Object obj = make(cc.getName());
  563. Method m = obj.getClass().getMethod("javassistResult");
  564. Object javassistResult = m.invoke(obj);
  565. //before this fix
  566. //expected:<Man feed(Bear)> but was:<Keeper feed(Animal)>
  567. assertEquals(javacResult, javassistResult);
  568. }
  569. }