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.

JvstTest3.java 43KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  1. package javassist;
  2. import javassist.bytecode.*;
  3. import javassist.bytecode.annotation.*;
  4. import javassist.expr.*;
  5. import test3.*;
  6. @SuppressWarnings({"rawtypes","unchecked","unused"})
  7. public class JvstTest3 extends JvstTestRoot {
  8. public JvstTest3(String name) {
  9. super(name);
  10. }
  11. public void testAnnotation() throws Exception {
  12. CtClass cc = sloader.get("test3.AnnoTest");
  13. Object[] all = cc.getAnnotations();
  14. Anno a = (Anno)all[0];
  15. assertEquals('0', a.c());
  16. assertEquals(true, a.bool());
  17. assertEquals(1, a.b());
  18. assertEquals(2, a.s());
  19. assertEquals(3, a.i());
  20. assertEquals(4L, a.j());
  21. assertEquals(5.0F, a.f());
  22. assertEquals(6.0, a.d());
  23. assertEquals("7", a.str());
  24. assertEquals(AnnoTest.class, a.clazz());
  25. assertEquals(3, a.anno2().str().length);
  26. }
  27. public void testAnnotation2() throws Exception {
  28. CtClass cc = sloader.get("test3.AnnoTest2");
  29. Object[] all = cc.getAnnotations();
  30. Anno a = (Anno)all[0];
  31. assertEquals('a', a.c());
  32. assertEquals(false, a.bool());
  33. assertEquals(11, a.b());
  34. assertEquals(12, a.s());
  35. assertEquals(13, a.i());
  36. assertEquals(14L, a.j());
  37. assertEquals(15.0F, a.f());
  38. assertEquals(16.0, a.d());
  39. assertEquals("17", a.str());
  40. assertEquals(String.class, a.clazz());
  41. assertEquals(11, a.anno2().i()[0]);
  42. }
  43. public void testAnnotation3() throws Exception {
  44. CtClass cc = sloader.get("test3.AnnoTest3");
  45. Object[] all = cc.getAnnotations();
  46. assertEquals(2, all.length);
  47. int i;
  48. if (all[0] instanceof Anno2)
  49. i = 0;
  50. else
  51. i = 1;
  52. Anno2 a = (Anno2)all[i];
  53. assertEquals(1, a.i()[0]);
  54. assertEquals(test3.ColorName.RED, a.color());
  55. assertEquals(test3.ColorName.BLUE, a.color2()[0]);
  56. }
  57. public void testAnnotation4() throws Exception {
  58. CtClass cc = sloader.get("test3.AnnoTest4");
  59. Object[] all = cc.getAnnotations();
  60. Anno3 a = null;
  61. for (int i = 0; i < all.length; i++)
  62. if (all[i] instanceof Anno3)
  63. a = (Anno3)all[i];
  64. assertTrue(a != null);
  65. assertEquals('0', a.c()[0]);
  66. assertEquals(true, a.bool()[0]);
  67. assertEquals(1, a.b()[0]);
  68. assertEquals(2, a.s()[0]);
  69. assertEquals(3, a.i()[0]);
  70. assertEquals(4L, a.j()[0]);
  71. assertEquals(5.0F, a.f()[0]);
  72. assertEquals(6.0, a.d()[0]);
  73. assertEquals("7", a.str()[0]);
  74. assertEquals(AnnoTest.class, a.clazz()[0]);
  75. assertEquals(11, a.anno2()[0].i()[0]);
  76. }
  77. public void testAnnotation5() throws Exception {
  78. CtClass cc = sloader.get("test3.AnnoTest5");
  79. Object[] all = cc.getField("bar").getAnnotations();
  80. Anno2 a2 = (Anno2)all[0];
  81. assertEquals(test3.ColorName.RED, a2.color());
  82. all = cc.getDeclaredMethod("foo").getAnnotations();
  83. Anno a = (Anno)all[0];
  84. assertEquals("7", a.str());
  85. }
  86. public void testAnnotation6() throws Exception {
  87. CtClass cc = sloader.get("test3.AnnoTest6");
  88. Object[] all = cc.getAnnotations();
  89. Anno6 a = (Anno6)all[0];
  90. assertEquals(0, a.str1().length);
  91. assertEquals(0, a.str2().length);
  92. }
  93. public void testChainedException() throws Exception {
  94. try {
  95. throwChainedException();
  96. }
  97. catch (CannotCompileException e) {
  98. e.printStackTrace(System.out);
  99. }
  100. try {
  101. throwChainedException2();
  102. }
  103. catch (CannotCompileException e) {
  104. e.printStackTrace(System.out);
  105. }
  106. try {
  107. throwChainedException3();
  108. }
  109. catch (Exception e) {
  110. e.printStackTrace(System.out);
  111. }
  112. }
  113. public void throwChainedException() throws Exception {
  114. throw new CannotCompileException("test");
  115. }
  116. public void throwChainedException2() throws Exception {
  117. Throwable e = new CannotCompileException("test");
  118. throw new CannotCompileException("test2", e);
  119. }
  120. public void throwChainedException3() throws Exception {
  121. Throwable e = new CannotCompileException("testA");
  122. Throwable e2 = new CannotCompileException("testB", e);
  123. throw new Exception(e2);
  124. }
  125. // JIRA Javassist-12
  126. public void testInnerClassMethod() throws Exception {
  127. CtClass cc = sloader.get("test3.InnerMethod");
  128. CtMethod m1 = cc.getDeclaredMethod("test");
  129. m1.setBody("{inner.test();}");
  130. CtMethod m2 = CtNewMethod.make(
  131. "public int bar() {"
  132. + " if (counter-- <= 0) return 3;"
  133. + " else return bar();"
  134. + "}",
  135. cc);
  136. cc.addMethod(m2);
  137. cc.writeFile();
  138. Object obj = make(cc.getName());
  139. assertEquals(1, invoke(obj, "foo"));
  140. assertEquals(3, invoke(obj, "bar"));
  141. }
  142. public void testCheckModifyAndPruned() throws Exception {
  143. CtClass cc = sloader.get("test3.CheckModify");
  144. cc.addField(new CtField(CtClass.intType, "j", cc));
  145. cc.stopPruning(false);
  146. cc.toBytecode();
  147. try {
  148. cc.getClassFile();
  149. fail();
  150. }
  151. catch (RuntimeException e) {
  152. // System.err.println(e.getMessage());
  153. assertTrue(e.getMessage().indexOf("prune") >= 0);
  154. }
  155. }
  156. public void testReplaceNew() throws Exception {
  157. CtClass cc = sloader.get("test3.ReplaceNew");
  158. CtMethod m1 = cc.getDeclaredMethod("run");
  159. m1.instrument(new ExprEditor() {
  160. public void edit(NewExpr n) throws CannotCompileException {
  161. n.replace("{ i++; $_ = null; }");
  162. }
  163. });
  164. CtMethod m2 = cc.getDeclaredMethod("run2");
  165. m2.instrument(new ExprEditor() {
  166. public void edit(NewExpr n) throws CannotCompileException {
  167. n.replace("{ j++; $_ = null; }");
  168. }
  169. });
  170. cc.writeFile();
  171. Object obj = make(cc.getName());
  172. assertEquals(5, invoke(obj, "run"));
  173. assertEquals(2, invoke(obj, "run2"));
  174. }
  175. public void testPublicInner() throws Exception {
  176. CtClass cc0 = sloader.get("test3.PublicInner2");
  177. int mod = cc0.getClassFile2().getAccessFlags();
  178. System.out.println("testPublicInner: " + mod);
  179. CtClass cc = sloader.get("test3.PublicInner");
  180. CtClass jp = cc.makeNestedClass("Inner", true);
  181. assertEquals(Modifier.PUBLIC | Modifier.STATIC, jp.getModifiers());
  182. assertEquals(Modifier.PUBLIC | Modifier.STATIC,
  183. getPublicInner(jp, "Inner"));
  184. assertEquals(Modifier.PUBLIC | Modifier.STATIC,
  185. getPublicInner(cc, "Inner"));
  186. jp.setModifiers(Modifier.STATIC);
  187. assertEquals(Modifier.STATIC, jp.getModifiers());
  188. assertEquals(Modifier.STATIC, getPublicInner(jp, "Inner"));
  189. assertEquals(Modifier.STATIC, getPublicInner(cc, "Inner"));
  190. jp.setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT);
  191. assertEquals(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STATIC, jp.getModifiers());
  192. assertEquals(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STATIC,
  193. getPublicInner(jp, "Inner"));
  194. assertEquals(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STATIC,
  195. getPublicInner(cc, "Inner"));
  196. cc.writeFile();
  197. jp.writeFile();
  198. }
  199. private int getPublicInner(CtClass cc, String name) throws Exception {
  200. ClassFile cf = cc.getClassFile();
  201. InnerClassesAttribute ica
  202. = (InnerClassesAttribute)cf.getAttribute(
  203. InnerClassesAttribute.tag);
  204. assertEquals(name, ica.innerName(0));
  205. return ica.accessFlags(0);
  206. }
  207. public void testConstructorToMethod() throws Exception {
  208. CtClass cc = sloader.get("test3.Constructor");
  209. CtConstructor[] cons = cc.getConstructors();
  210. CtConstructor sinit = cc.getClassInitializer();
  211. for (int i = 0; i < cons.length; i++) {
  212. CtConstructor ccons = cons[i];
  213. String desc = ccons.getSignature();
  214. boolean result = false;
  215. if (desc.equals("()V"))
  216. result = false;
  217. else if (desc.equals("(I)V"))
  218. result = true;
  219. else if (desc.equals("(Ljava/lang/String;)V"))
  220. result = false;
  221. else if (desc.equals("(D)V"))
  222. result = true;
  223. else
  224. fail("unknonw constructor");
  225. assertEquals(result, ccons.callsSuper());
  226. }
  227. CtClass cc2 = sloader.get("test3.Constructor2");
  228. for (int i = 0; i < cons.length; i++)
  229. cc2.addMethod(cons[i].toMethod("m", cc2));
  230. cc2.addMethod(sinit.toMethod("sinit", cc2));
  231. cc2.addMethod(CtMethod.make(
  232. "public int run() { m(); m(5); m(\"s\"); m(0.0);" +
  233. " sinit(); return i + str.length(); }",
  234. cc2));
  235. cc2.writeFile();
  236. Object obj = make(cc2.getName());
  237. assertEquals(119, invoke(obj, "run"));
  238. }
  239. public void testUnique() throws Exception {
  240. CtClass cc = sloader.get("test3.Unique");
  241. CtClass cc2 = sloader.get("test3.Unique3");
  242. assertEquals("poi", cc.makeUniqueName("poi"));
  243. assertEquals("foo102", cc.makeUniqueName("foo"));
  244. assertEquals("bar102", cc2.makeUniqueName("bar"));
  245. assertEquals("foo100", cc2.makeUniqueName("foo"));
  246. }
  247. public void testGetMethods() throws Exception {
  248. CtClass cc = sloader.get("test3.GetMethods");
  249. assertEquals(3, cc.getConstructors().length);
  250. assertEquals(6, cc.getFields().length);
  251. assertEquals(6 + Object.class.getMethods().length + 2,
  252. cc.getMethods().length);
  253. }
  254. public void testVisiblity() throws Exception {
  255. CtClass cc = sloader.get("test3.Visible");
  256. CtClass cc2 = sloader.get("test3.Visible2");
  257. CtClass subcc = sloader.get("test3.sub.Visible");
  258. CtClass subcc2 = sloader.get("test3.sub.Visible2");
  259. CtClass top = sloader.get("VisibleTop");
  260. CtClass top2 = sloader.get("VisibleTop2");
  261. assertEquals(true, cc.getField("pub").visibleFrom(cc2));
  262. assertEquals(true, cc.getField("pub").visibleFrom(subcc));
  263. assertEquals(true, cc.getField("pri").visibleFrom(cc));
  264. assertEquals(false, cc.getField("pri").visibleFrom(cc2));
  265. assertEquals(true, cc.getField("pack").visibleFrom(cc));
  266. assertEquals(true, cc.getField("pack").visibleFrom(cc2));
  267. assertEquals(false, cc.getField("pack").visibleFrom(subcc));
  268. assertEquals(false, cc.getField("pack").visibleFrom(top));
  269. assertEquals(true, cc.getField("pro").visibleFrom(cc));
  270. assertEquals(true, cc.getField("pro").visibleFrom(cc2));
  271. assertEquals(true, cc.getField("pro").visibleFrom(subcc2));
  272. assertEquals(false, cc.getField("pro").visibleFrom(subcc));
  273. assertEquals(false, cc.getField("pro").visibleFrom(top));
  274. assertEquals(true, top.getField("pack").visibleFrom(top2));
  275. assertEquals(false, top.getField("pack").visibleFrom(cc));
  276. }
  277. public void testNewAnnotation() throws Exception {
  278. CtClass c = sloader.makeClass("test3.NewClass");
  279. ClassFile cf = c.getClassFile();
  280. ConstPool cp = cf.getConstPool();
  281. AnnotationsAttribute attr
  282. = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag);
  283. javassist.bytecode.annotation.Annotation a
  284. = new Annotation("test3.ChibaAnnotation", cp);
  285. a.addMemberValue("name", new StringMemberValue("Chiba", cp));
  286. a.addMemberValue("version", new StringMemberValue("Chiba", cp));
  287. a.addMemberValue("description", new StringMemberValue("Chiba", cp));
  288. a.addMemberValue("interfaceName", new StringMemberValue("Chiba", cp));
  289. attr.setAnnotation(a);
  290. System.out.println(attr);
  291. cf.addAttribute(attr);
  292. cf.setVersionToJava5();
  293. Object [] ans = c.getAnnotations() ;
  294. System.out.println("Num Annotation : " +ans.length);
  295. // c.debugWriteFile();
  296. Class newclass = c.toClass(DefineClassCapability.class);
  297. java.lang.annotation.Annotation[] anns = newclass.getAnnotations();
  298. System.out.println("Num NewClass Annotation : " +anns.length);
  299. assertEquals(ans.length, anns.length);
  300. }
  301. public void testRecursiveReplace() throws Exception {
  302. CtClass cc = sloader.get("test3.RecReplace");
  303. CtMethod m1 = cc.getDeclaredMethod("run");
  304. final ExprEditor e2 = new ExprEditor() {
  305. public void edit(MethodCall mc) throws CannotCompileException {
  306. if (mc.getMethodName().equals("bar")) {
  307. mc.replace("{ double k = 10.0; $_ = $proceed($1 + k); }");
  308. }
  309. }
  310. };
  311. m1.instrument(new ExprEditor() {
  312. public void edit(MethodCall mc) throws CannotCompileException {
  313. if (mc.getMethodName().equals("foo")) {
  314. mc.replace("{ int k = bar($$); $_ = k + $proceed(7.0); }",
  315. e2);
  316. }
  317. }
  318. });
  319. CtMethod m2 = cc.getDeclaredMethod("run2");
  320. m2.instrument(new ExprEditor() {
  321. public void edit(MethodCall mc) throws CannotCompileException {
  322. if (mc.getMethodName().equals("foo")) {
  323. mc.replace("{ int k = bar($$); $_ = k + $proceed(7.0); }");
  324. }
  325. }
  326. });
  327. cc.writeFile();
  328. Object obj = make(cc.getName());
  329. assertEquals(26, invoke(obj, "run"));
  330. assertEquals(16, invoke(obj, "run2"));
  331. }
  332. public void testRecursiveReplace2() throws Exception {
  333. final ExprEditor[] ref = new ExprEditor[1];
  334. ExprEditor e2 = new ExprEditor() {
  335. public void edit(FieldAccess fa) throws CannotCompileException {
  336. if (fa.getFieldName().equals("value2")
  337. && fa.isWriter()) {
  338. fa.replace("{ $_ = $proceed($1 + 2); }");
  339. }
  340. }
  341. };
  342. ExprEditor e1 = new ExprEditor() {
  343. public void edit(FieldAccess fa) throws CannotCompileException {
  344. if (fa.getFieldName().equals("value")
  345. && fa.isWriter()) {
  346. fa.replace("{ value2 = $1; value = value2; }",
  347. ref[0]);
  348. }
  349. }
  350. };
  351. CtClass cc = sloader.get("test3.RecReplace2");
  352. CtMethod m1 = cc.getDeclaredMethod("run");
  353. ref[0] = e2;
  354. m1.instrument(e1);
  355. CtMethod m2 = cc.getDeclaredMethod("run2");
  356. ref[0] = null;
  357. m2.instrument(e1);
  358. cc.writeFile();
  359. Object obj = make(cc.getName());
  360. assertEquals(28, invoke(obj, "run"));
  361. assertEquals(24, invoke(obj, "run2"));
  362. }
  363. public void testInnerModifier() throws Exception {
  364. CtClass cc = sloader.get("test3.InnerClass$Inner");
  365. assertEquals(Modifier.PUBLIC | Modifier.STATIC, cc.getModifiers());
  366. CtClass cc2 = sloader.get("test3.InnerClass$Inner2");
  367. assertEquals(Modifier.PUBLIC, cc2.getModifiers());
  368. }
  369. public void testMethodLookup() throws Exception {
  370. CtClass cc = sloader.get("test3.SubValue");
  371. CtMethod m1 = CtNewMethod.make(
  372. "public int run() {" +
  373. " test3.SuperValue sup = new test3.SuperValue();" +
  374. " test3.SubValue sub = new test3.SubValue();" +
  375. " return this.after(sup, sub, sub) == null ? 0 : 1;" +
  376. "}",
  377. cc);
  378. cc.addMethod(m1);
  379. cc.writeFile();
  380. Object obj = make(cc.getName());
  381. assertEquals(1, invoke(obj, "run"));
  382. }
  383. public void testFieldAccessType() throws Exception {
  384. CtClass cc = sloader.get("test3.FieldAccessType");
  385. CtMethod m1 = cc.getDeclaredMethod("access");
  386. final boolean[] result = new boolean[1];
  387. result[0] = true;
  388. ExprEditor e = new ExprEditor() {
  389. public void edit(FieldAccess fa) throws CannotCompileException {
  390. if (!fa.getSignature().equals("[I"))
  391. result[0] = false;
  392. }
  393. };
  394. m1.instrument(e);
  395. assertTrue(result[0]);
  396. }
  397. public void testGetNestedClasses() throws Exception {
  398. CtClass cc = sloader.get("test3.NestedClass");
  399. CtClass[] nested = cc.getNestedClasses();
  400. assertEquals(4, nested.length);
  401. testGetNestedClasses("test3.NestedClass$Inner", nested);
  402. testGetNestedClasses("test3.NestedClass$StaticNested", nested);
  403. testGetNestedClasses("test3.NestedClass$1Local", nested);
  404. testGetNestedClasses("test3.NestedClass$1", nested);
  405. }
  406. private void testGetNestedClasses(String name, CtClass[] classes) {
  407. for (int i = 0; i < classes.length; i++)
  408. if (classes[i].getName().equals(name))
  409. return;
  410. fail("no class: " + name);
  411. }
  412. public void testGetParmeterAnnotations() throws Exception {
  413. CtClass cc = sloader.get("test3.ParamAnno");
  414. Object[][] anno = cc.getDeclaredMethod("foo").getParameterAnnotations();
  415. assertEquals(4, anno.length);
  416. assertEquals(0, anno[0].length);
  417. assertEquals(0, anno[1].length);
  418. assertEquals(0, anno[2].length);
  419. assertEquals(0, anno[3].length);
  420. Object[][] anno2 = cc.getDeclaredMethod("bar").getParameterAnnotations();
  421. assertEquals(0, anno2.length);
  422. Class rc = Class.forName("test3.ParamAnno");
  423. java.lang.reflect.Method[] ms = rc.getDeclaredMethods();
  424. java.lang.reflect.Method m1, m2;
  425. if (ms[0].getName().equals("foo")) {
  426. m1 = ms[0];
  427. m2 = ms[1];
  428. }
  429. else {
  430. m1 = ms[1];
  431. m2 = ms[0];
  432. }
  433. java.lang.annotation.Annotation[][] ja;
  434. ja = m1.getParameterAnnotations();
  435. assertEquals(4, ja.length);
  436. assertEquals(0, ja[0].length);
  437. assertEquals(0, ja[1].length);
  438. assertEquals(0, ja[2].length);
  439. assertEquals(0, ja[3].length);
  440. assertEquals(0, m2.getParameterAnnotations().length);
  441. }
  442. public void testSetModifiers() throws Exception {
  443. CtClass cc = sloader.get("test3.SetModifiers");
  444. try {
  445. cc.setModifiers(Modifier.STATIC | Modifier.PUBLIC);
  446. fail("static public class SetModifiers");
  447. }
  448. catch (RuntimeException e) {
  449. assertEquals("cannot change test3.SetModifiers into a static class", e.getMessage());
  450. }
  451. cc = sloader.get("test3.SetModifiers$A");
  452. cc.setModifiers(Modifier.STATIC | Modifier.PUBLIC);
  453. assertTrue(Modifier.isStatic(cc.getModifiers()));
  454. assertTrue((cc.getClassFile2().getAccessFlags() & AccessFlag.STATIC) == 0);
  455. }
  456. public void testFieldCopy() throws Exception {
  457. CtClass cc = sloader.get("test3.FieldCopy");
  458. CtClass cc2 = sloader.get("test3.FieldCopy2");
  459. CtField f = cc.getDeclaredField("foo");
  460. cc2.addField(new CtField(f, cc2));
  461. CtField f2 = cc2.getDeclaredField("foo");
  462. Object[] anno = f2.getAnnotations();
  463. assertTrue(anno[0] instanceof test3.FieldCopy.Test);
  464. assertEquals(Modifier.PRIVATE | Modifier.STATIC,
  465. f2.getModifiers());
  466. }
  467. public void testMethodRedirect() throws Exception {
  468. CtClass cc = sloader.get("test3.MethodRedirect");
  469. CtClass cc2 = sloader.get("test3.MethodRedirectIntf");
  470. CtMethod foo = cc.getDeclaredMethod("foo");
  471. CtMethod poi = cc.getDeclaredMethod("poi");
  472. CtMethod bar = cc.getDeclaredMethod("bar");
  473. CtMethod afo = cc2.getDeclaredMethod("afo");
  474. CodeConverter conv = new CodeConverter();
  475. try {
  476. conv.redirectMethodCall(foo, bar);
  477. fail("foo");
  478. }
  479. catch (CannotCompileException e) {}
  480. try {
  481. conv.redirectMethodCall(poi, bar);
  482. fail("bar");
  483. }
  484. catch (CannotCompileException e) {}
  485. try {
  486. conv.redirectMethodCall(bar, afo);
  487. fail("afo");
  488. }
  489. catch (CannotCompileException e) {}
  490. bar.setName("bar2");
  491. conv.redirectMethodCall("bar", bar);
  492. cc.instrument(conv);
  493. // cc.writeFile();
  494. Object obj = make(cc.getName());
  495. assertEquals(2, invoke(obj, "test"));
  496. }
  497. public void testMethodRedirect2() throws Exception {
  498. CtClass cc = sloader.get("test3.MethodRedirect2");
  499. CtClass sup = sloader.get("test3.MethodRedirect2Sup");
  500. CtClass supsup = sloader.get("test3.MethodRedirect2SupSup");
  501. CtClass intf = sloader.get("test3.MethodRedirect2SupIntf");
  502. CtMethod bfo2 = supsup.getDeclaredMethod("bfo2");
  503. CtMethod afo2 = sup.getDeclaredMethod("afo2");
  504. CtMethod foo = intf.getDeclaredMethod("foo");
  505. CodeConverter conv = new CodeConverter();
  506. conv.redirectMethodCall("bfo", bfo2);
  507. conv.redirectMethodCall("afo", afo2);
  508. conv.redirectMethodCall("bar", foo);
  509. conv.redirectMethodCall("bar2", foo);
  510. cc.instrument(conv);
  511. cc.writeFile();
  512. Object obj = make(cc.getName());
  513. assertEquals(524, invoke(obj, "test"));
  514. }
  515. public void testMethodRedirectToStatic() throws Exception {
  516. CtClass targetClass = sloader.get("test3.MethodRedirectToStatic");
  517. CtClass staticClass = sloader.get("test3.MethodRedirectToStatic2");
  518. CtMethod targetMethod = targetClass.getDeclaredMethod("add");
  519. CtMethod staticMethod = staticClass.getDeclaredMethod("add2");
  520. CodeConverter conv = new CodeConverter();
  521. conv.redirectMethodCallToStatic(targetMethod, staticMethod);
  522. targetClass.instrument(conv);
  523. targetClass.writeFile();
  524. Object obj = make(targetClass.getName());
  525. assertEquals(30, invoke(obj, "test"));
  526. }
  527. public void testClassMap() throws Exception {
  528. ClassMap map = new ClassMap();
  529. map.put("aa", "AA");
  530. map.put("xx", "XX");
  531. assertEquals("AA", map.get("aa"));
  532. assertEquals(null, map.get("bb"));
  533. ClassMap map2 = new ClassMap(map);
  534. map2.put("aa", "A1");
  535. map2.put("cc", "CC");
  536. assertEquals("A1", map2.get("aa"));
  537. assertEquals("CC", map2.get("cc"));
  538. assertEquals("XX", map2.get("xx"));
  539. assertEquals(null, map2.get("bb"));
  540. }
  541. public void testEmptyConstructor() throws Exception {
  542. CtClass cc = sloader.get("test3.EmptyConstructor");
  543. CtConstructor[] cons = cc.getDeclaredConstructors();
  544. for (int i = 0; i < cons.length; i++)
  545. assertTrue("index: " + i, cons[i].isEmpty());
  546. cc = sloader.get("test3.EmptyConstructor2");
  547. cons = cc.getDeclaredConstructors();
  548. for (int i = 0; i < cons.length; i++)
  549. assertTrue("index: " + i, cons[i].isEmpty());
  550. cc = sloader.get("test3.EmptyConstructor3");
  551. cons = cc.getDeclaredConstructors();
  552. for (int i = 0; i < cons.length; i++)
  553. assertTrue("index: " + i, cons[i].isEmpty());
  554. cc = sloader.get("test3.EmptyConstructor4");
  555. cons = cc.getDeclaredConstructors();
  556. for (int i = 0; i < cons.length; i++)
  557. assertFalse("index: " + i, cons[i].isEmpty());
  558. }
  559. public void testTransformRead() throws Exception {
  560. CtClass cc = sloader.get("test3.TransformRead");
  561. CtClass parent = cc.getSuperclass();
  562. CtMethod m = cc.getDeclaredMethod("foo");
  563. CodeConverter conv = new CodeConverter();
  564. conv.replaceFieldRead(parent.getField("value"), cc, "getValue");
  565. conv.replaceFieldRead(parent.getField("value2"), cc, "getValue2");
  566. m.instrument(conv);
  567. cc.writeFile();
  568. Object obj = make(cc.getName());
  569. assertEquals(11100, invoke(obj, "foo"));
  570. }
  571. public void testDescriptor() throws Exception {
  572. assertEquals("int", Descriptor.toString("I"));
  573. assertEquals("long[][]", Descriptor.toString("[[J"));
  574. assertEquals("java.lang.Object", Descriptor.toString("Ljava/lang/Object;"));
  575. assertEquals("()", Descriptor.toString("()V"));
  576. assertEquals("(int)", Descriptor.toString("(I)V"));
  577. assertEquals("(int,int[])", Descriptor.toString("(I[I)V"));
  578. assertEquals("(java.lang.String,Foo[][])", Descriptor.toString("(Ljava/lang/String;[[LFoo;)V"));
  579. }
  580. public void testLongName() throws Exception {
  581. CtClass cc = sloader.get("test3.Name");
  582. assertEquals("test3.Name.<clinit>()", cc.getClassInitializer().getLongName());
  583. assertEquals("test3.Name()", cc.getConstructor("()V").getLongName());
  584. assertEquals("test3.Name(int)", cc.getConstructor("(I)V").getLongName());
  585. assertEquals("test3.Name(test3.Name)", cc.getConstructor("(Ltest3/Name;)V").getLongName());
  586. assertEquals("test3.Name(test3.Name,java.lang.String)",
  587. cc.getConstructor("(Ltest3/Name;Ljava/lang/String;)V").getLongName());
  588. assertEquals("test3.Name.foo()", cc.getDeclaredMethod("foo").getLongName());
  589. assertEquals("test3.Name.foo2(int)", cc.getDeclaredMethod("foo2").getLongName());
  590. assertEquals("test3.Name.foo3(java.lang.String)", cc.getDeclaredMethod("foo3").getLongName());
  591. assertEquals("test3.Name.foo4(java.lang.String[])", cc.getDeclaredMethod("foo4").getLongName());
  592. assertEquals("test3.Name.foo5(int,java.lang.String)", cc.getDeclaredMethod("foo5").getLongName());
  593. }
  594. public void testPackageName() throws Exception {
  595. CtClass cc = sloader.get("test3.PackName");
  596. CtMethod m1 = CtNewMethod.make(
  597. "public int run() {" +
  598. " return test3.PackName.get() + test3.sub.SubPackName.get(); }",
  599. cc);
  600. cc.addMethod(m1);
  601. cc.writeFile();
  602. Object obj = make(cc.getName());
  603. assertEquals(8, invoke(obj, "run"));
  604. }
  605. public void testErasure() throws Exception {
  606. CtClass cc = sloader.get("test3.Erasure");
  607. cc.addInterface(sloader.get("test3.ErasureGet"));
  608. CtMethod m1 = CtNewMethod.make(
  609. "public Object get() { return value; }",
  610. cc);
  611. cc.addMethod(m1);
  612. cc.writeFile();
  613. Object obj = make(cc.getName());
  614. assertEquals(4, invoke(obj, "run"));
  615. }
  616. /* Check the result of JvstTest#testFieldInit()
  617. * This tests CtClassType#saveClassFile().
  618. */
  619. public void testFieldInitAgain() throws Exception {
  620. System.gc();
  621. CtClass cc = sloader.get("test1.FieldInit");
  622. CtField f = cc.getDeclaredField("f1");
  623. assertEquals(CtClass.intType, f.getType());
  624. assertTrue("f.hashCode() doesn't change!", f.hashCode() != JvstTest.testFieldInitHash);
  625. }
  626. /* This tests CtClassType#saveClassFile().
  627. * A CtMethod is not garbage collected, its CtClass is never
  628. * compressed.
  629. */
  630. public void testCalleeBeforeAgain() throws Exception {
  631. CtClass cc = sloader.get("test1.CalleeBefore");
  632. assertEquals(JvstTest.testCalleeBeforeMethod,
  633. cc.getDeclaredMethod("m1"));
  634. assertEquals(JvstTest.testCalleeBeforeMethod2,
  635. cc.getDeclaredMethod("m2").getMethodInfo2().hashCode());
  636. }
  637. public void testSetSuper() throws Exception {
  638. CtClass cc = sloader.get("test3.Superclass");
  639. CtClass cc3 = sloader.get("test3.Superclass3");
  640. cc3.setModifiers(Modifier.setPublic(cc3.getModifiers()));
  641. cc.setSuperclass(sloader.get("test3.Superclass3"));
  642. cc.writeFile();
  643. cc3.writeFile();
  644. Object obj = make(cc.getName());
  645. assertEquals(21, invoke(obj, "test"));
  646. }
  647. public void testFrozen2() throws Exception {
  648. CtClass cc = sloader.get("test3.Frozen");
  649. cc.addField(new CtField(CtClass.intType, "k", cc));
  650. cc.toBytecode();
  651. cc.toBytecode();
  652. cc = sloader.makeClass("test3.Frozen2");
  653. cc.toBytecode();
  654. cc.toBytecode();
  655. }
  656. public void testCopyAnnotation() throws Exception {
  657. CtClass cc1 = sloader.get("test3.CopyAnnoBase");
  658. CtMethod m1 = cc1.getDeclaredMethod("getX");
  659. CtClass cc2 = sloader.get("test3.CopyAnno");
  660. CtMethod m2 = cc2.getDeclaredMethod("getX");
  661. copyAnnotations(m1, m2);
  662. cc2.getClassFile();
  663. Class clazz = cc2.toClass(DefineClassCapability.class);
  664. java.lang.reflect.Method m = clazz.getDeclaredMethod("getX", new Class[0]);
  665. assertEquals(1, m.getAnnotations().length);
  666. test3.VisibleAnno a = m.getAnnotation(test3.VisibleAnno.class);
  667. assertNotNull(a);
  668. }
  669. private void copyAnnotations(CtMethod src, CtMethod dest)
  670. throws NotFoundException
  671. {
  672. MethodInfo srcInfo = src.getMethodInfo2();
  673. MethodInfo destInfo = dest.getMethodInfo2();
  674. copyAnnotations(srcInfo, destInfo, AnnotationsAttribute.invisibleTag);
  675. copyAnnotations(srcInfo, destInfo, AnnotationsAttribute.visibleTag);
  676. }
  677. private void copyAnnotations(MethodInfo src, MethodInfo dest, String annotationTag) {
  678. AnnotationsAttribute attribute = (AnnotationsAttribute)src.getAttribute(annotationTag);
  679. if (attribute != null)
  680. dest.addAttribute(attribute.copy(dest.getConstPool(), new java.util.HashMap()));
  681. }
  682. public void testStaticFinalField() throws Exception {
  683. CtClass cc = sloader.makeClass("test3.StaticFinalField");
  684. CtField fj = new CtField(CtClass.longType, "j", cc);
  685. fj.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
  686. cc.addField(fj, CtField.Initializer.constant(2L));
  687. CtField fi = new CtField(CtClass.intType, "i", cc);
  688. fi.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
  689. cc.addField(fi, CtField.Initializer.constant(3));
  690. CtField fs = new CtField(CtClass.shortType, "s", cc);
  691. fs.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
  692. cc.addField(fs, CtField.Initializer.constant(4));
  693. CtField fc = new CtField(CtClass.charType, "c", cc);
  694. fc.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
  695. cc.addField(fc, CtField.Initializer.constant('5'));
  696. CtField fby = new CtField(CtClass.byteType, "by", cc);
  697. fby.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
  698. cc.addField(fby, CtField.Initializer.constant(6));
  699. CtField fb = new CtField(CtClass.booleanType, "b", cc);
  700. fb.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
  701. cc.addField(fb, CtField.Initializer.constant(true));
  702. CtField ff = new CtField(CtClass.floatType, "f", cc);
  703. ff.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
  704. cc.addField(ff, CtField.Initializer.constant(7.0F));
  705. CtField fstr = new CtField(sloader.get("java.lang.String"), "str", cc);
  706. fstr.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
  707. cc.addField(fstr, CtField.Initializer.constant("foo"));
  708. CtField fobj = new CtField(sloader.get("java.lang.Object"), "obj", cc);
  709. fobj.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
  710. cc.addField(fobj, CtField.Initializer.constant("bar"));
  711. cc.writeFile();
  712. Class clazz = cc.toClass(DefineClassCapability.class);
  713. assertEquals(2L, clazz.getField("j").getLong(null));
  714. assertEquals(3, clazz.getField("i").getInt(null));
  715. assertEquals(4, clazz.getField("s").getShort(null));
  716. assertEquals('5', clazz.getField("c").getChar(null));
  717. assertEquals(6, clazz.getField("by").getByte(null));
  718. assertEquals(true, clazz.getField("b").getBoolean(null));
  719. assertEquals(7.0F, clazz.getField("f").getFloat(null));
  720. assertEquals("foo", clazz.getField("str").get(null));
  721. assertEquals("bar", clazz.getField("obj").get(null));
  722. }
  723. /*
  724. public void testClassPath() throws Exception {
  725. ClassPool cp = new ClassPool(null);
  726. cp.appendClassPath("./test-classpath.JaR");
  727. assertNotNull(cp.get("test.Point"));
  728. cp = new ClassPool(null);
  729. cp.appendClassPath("./*");
  730. assertNotNull(cp.get("javassist.bytecode.Gap0Example"));
  731. }*/
  732. public void testVoidReturn() throws Exception {
  733. CtClass cc = sloader.get("test3.VoidReturn");
  734. CtMethod m1 = cc.getDeclaredMethod("foo");
  735. m1.insertAfter("System.out.println(\"return value: \" + $_);", true);
  736. cc.writeFile();
  737. make(cc.getName());
  738. }
  739. public void testInsertParam0() throws Exception {
  740. assertEquals("(I)V", Descriptor.insertParameter(CtClass.intType, "()V"));
  741. assertEquals("(ILjava/lang/Object;)V", Descriptor.insertParameter(CtClass.intType, "(Ljava/lang/Object;)V"));
  742. assertEquals("(IJ)V", Descriptor.appendParameter(CtClass.longType, "(I)V"));
  743. assertEquals("(Ljava/lang/String;I)V", Descriptor.insertParameter(sloader.get("java.lang.String"), "(I)V"));
  744. }
  745. public void testInsertParam() throws Exception {
  746. CtClass cc = sloader.get("test3.InsParam");
  747. CtMethod m1 = cc.getDeclaredMethod("foo");
  748. m1.insertParameter(CtClass.longType);
  749. m1.insertBefore("$2 += (int)$1;");
  750. CtMethod m2 = cc.getDeclaredMethod("bar");
  751. m2.addParameter(CtClass.doubleType);
  752. m2.insertBefore("$1 += (int)$2;");
  753. CtMethod m3 = cc.getDeclaredMethod("poi");
  754. m3.addParameter(sloader.get("java.lang.Object"));
  755. m3.insertBefore("$2 = (String)$3;");
  756. cc.writeFile();
  757. Object obj = make(cc.getName());
  758. assertEquals(11, invoke(obj, "foo", 10L, 1));
  759. assertEquals(11, invoke(obj, "bar", 1, 10.0));
  760. assertEquals(3, invoke(obj, "poi", 1, "x", "xx"));
  761. }
  762. private int invoke(Object target, String method, long arg1, int arg2)
  763. throws Exception
  764. {
  765. java.lang.reflect.Method m =
  766. target.getClass().getMethod(method, new Class[] { long.class, int.class });
  767. Object res = m.invoke(target, new Object[] { Long.valueOf(arg1), Integer.valueOf(arg2)});
  768. return ((Integer)res).intValue();
  769. }
  770. private int invoke(Object target, String method, int arg1, double arg2)
  771. throws Exception
  772. {
  773. java.lang.reflect.Method m =
  774. target.getClass().getMethod(method, new Class[] { int.class, double.class });
  775. Object res = m.invoke(target, new Object[] { Integer.valueOf(arg1), Double.valueOf(arg2)});
  776. return ((Integer)res).intValue();
  777. }
  778. private int invoke(Object target, String method, int arg1, String arg2, Object arg3)
  779. throws Exception
  780. {
  781. java.lang.reflect.Method m =
  782. target.getClass().getMethod(method, new Class[] { int.class, String.class, Object.class });
  783. Object res = m.invoke(target, new Object[] { Integer.valueOf(arg1), arg2, arg3});
  784. return ((Integer)res).intValue();
  785. }
  786. public void testInvokeinterface() throws Exception {
  787. // JIRA JASSIST-60
  788. CtClass cc = sloader.get("test3.InvokeIntf");
  789. CtMethod mth = cc.getDeclaredMethod("doit");
  790. ExprEditor e = new ExprEditor() {
  791. public void edit(MethodCall m) throws CannotCompileException {
  792. String block = "{$_=$proceed($$);}";
  793. m.replace(block);
  794. }
  795. };
  796. mth.instrument(e);
  797. cc.writeFile();
  798. Object obj = make(cc.getName());
  799. assertEquals(7, invoke(obj, "test"));
  800. }
  801. public void testInvokeArrayObj() throws Exception {
  802. // JIRA JASSIST-61
  803. CtClass cc = sloader.get("test3.InvokeArray");
  804. CtMethod mth = cc.getDeclaredMethod("doit");
  805. ExprEditor e = new ExprEditor() {
  806. public void edit(MethodCall m) throws CannotCompileException {
  807. String block = "{$_=$proceed($$);}";
  808. m.replace(block);
  809. }
  810. };
  811. mth.instrument(e);
  812. cc.writeFile();
  813. Object obj = make(cc.getName());
  814. assertEquals(3, invoke(obj, "test"));
  815. }
  816. public void testNewExprTry() throws Exception {
  817. CtClass cc = sloader.get("test3.NewExprTryCatch");
  818. CtMethod mth = cc.getDeclaredMethod("instrumentMe");
  819. ExprEditor e = new ExprEditor() {
  820. public void edit(NewExpr m) throws CannotCompileException {
  821. String block = "{$_=$proceed($$);}";
  822. m.replace(block);
  823. }
  824. };
  825. mth.instrument(e);
  826. // JIRA JASSIST-52
  827. CtMethod mth2 = cc.getDeclaredMethod("me2");
  828. ExprEditor e2 = new ExprEditor() {
  829. public void edit(MethodCall m) throws CannotCompileException {
  830. String block = "{try{$_=$proceed($$);} catch(Throwable t) {}}";
  831. m.replace(block);
  832. }
  833. };
  834. //mth2.instrument(e2);
  835. /*
  836. // JIRA JASSIST-53
  837. CtClass cc2 = sloader.get("test3.NewExprTryCatch2");
  838. CtBehavior mth3 = cc2.getDeclaredConstructors()[0];
  839. ExprEditor e3 = new ExprEditor() {
  840. public void edit(ConstructorCall m) throws CannotCompileException {
  841. String block = "{try {$_=$proceed($$);} catch (Throwable t) {}}";
  842. m.replace(block);
  843. }
  844. };
  845. mth3.instrument(e3);
  846. */
  847. cc.writeFile();
  848. // cc2.writeFile();
  849. Object obj = make(cc.getName());
  850. assertEquals(0, invoke(obj, "test"));
  851. // Object obj2 = make(cc2.getName());
  852. }
  853. public void testJIRA63() throws Exception {
  854. frameTypeTest(2);
  855. frameTypeTest(7);
  856. }
  857. private void frameTypeTest(final int initializerRepeatCount) throws Exception {
  858. // Get a class
  859. final CtClass cTst = sloader.get("test3.JIRA63");
  860. cTst.getClassFile().setMajorVersion(ClassFile.JAVA_6);
  861. try {
  862. // Create an initializer for the fields
  863. String initializer = "test3.JIRA63Helper";
  864. for(int i=0; i < initializerRepeatCount; i++)
  865. initializer += ".getAnObject(new Integer(1))";
  866. initializer += ";";
  867. // Add some fields
  868. final CtClass cObj = sloader.get("java.lang.Object");
  869. for(int i = 0; i < 7; i++)
  870. cTst.addField(new CtField(cObj, "a" + i, cTst), initializer);
  871. // Modify the constructors
  872. for(final CtConstructor m : cTst.getConstructors()) {
  873. m.insertAfter(initializer, true);
  874. m.insertBefore(initializer);
  875. }
  876. // Get the byte code.
  877. // cTst.toBytecode();
  878. cTst.writeFile();
  879. //make(cTst.getName());
  880. }
  881. finally {
  882. cTst.detach();
  883. }
  884. }
  885. public void testInsertBeforeType() throws Exception {
  886. CtClass cc = sloader.get("test3.InsertBeforeType");
  887. CtMethod m1 = cc.getDeclaredMethod("foo");
  888. m1.insertBefore("value = $type.getName();");
  889. cc.writeFile();
  890. Object obj = make(cc.getName());
  891. assertEquals(5, invoke(obj, "test"));
  892. }
  893. public void testTransformNewClass() throws Exception {
  894. CodeConverter conv = new CodeConverter();
  895. conv.replaceNew(sloader.get("test3.TransNewClassOld"),
  896. sloader.get("test3.TransNewClassNew"));
  897. CtClass cc = sloader.get("test3.TransNewClass");
  898. cc.instrument(conv);
  899. cc.writeFile();
  900. CtClass cc2 = sloader.get("test3.TransNewClass$TransNewClass2");
  901. cc2.instrument(conv);
  902. cc2.writeFile();
  903. Object obj = make(cc.getName());
  904. assertEquals(170, invoke(obj, "test"));
  905. Object obj2 = make(cc2.getName());
  906. assertEquals(50, invoke(obj2, "test"));
  907. }
  908. public void testInsertAfter() throws Exception {
  909. CtClass cc = sloader.get("test3.InsertAfter");
  910. CtMethod m1 = cc.getDeclaredMethod("foo");
  911. m1.insertAfter("k++;", true);
  912. CtConstructor cons = cc.getConstructor("()V");
  913. cons.insertAfter("k++;", true);
  914. cc.writeFile();
  915. Object obj = make(cc.getName());
  916. assertEquals(6, invoke(obj, "test"));
  917. }
  918. public void testInsertSwitch() throws Exception {
  919. CtClass cc = sloader.get("test3.Switch");
  920. CtMethod m1 = cc.getDeclaredMethod("foo");
  921. String sourceCode = "{"
  922. + "System.out.println(\"Bla!\");"
  923. + "}";
  924. String toInsert =
  925. " try " +
  926. " { " +
  927. sourceCode +
  928. " } " +
  929. " catch(Throwable e) " +
  930. " { " +
  931. " e.printStackTrace(); " +
  932. " } ";
  933. m1.insertBefore(toInsert);
  934. cc.writeFile();
  935. Object obj = make(cc.getName());
  936. assertEquals(0, invoke(obj, "test"));
  937. }
  938. public void testStringBuilder() throws Exception {
  939. CtClass cc = sloader.get("test3.StrBuild");
  940. CtMethod mth = cc.getDeclaredMethod("test");
  941. ExprEditor ed = new ExprEditor() {
  942. public void edit(MethodCall m) throws CannotCompileException {
  943. String block = "$_=$proceed($$);";
  944. m.replace(block);
  945. }
  946. };
  947. mth.instrument(ed);
  948. cc.writeFile();
  949. Object obj = make(cc.getName());
  950. assertEquals('t', invoke(obj, "test"));
  951. }
  952. public void testInheritCons() throws Exception {
  953. CtClass s = sloader.get("test3.InheritCons");
  954. CtClass cc = sloader.makeClass("test3.InheritCons2", s);
  955. cc.writeFile();
  956. Object obj = make(cc.getName());
  957. assertEquals("test3.InheritCons2", obj.getClass().getName());
  958. assertEquals(3, obj.getClass().getDeclaredConstructors().length);
  959. cc = sloader.makeClass("InheritCons3", s);
  960. cc.writeFile();
  961. obj = make(cc.getName());
  962. assertEquals("InheritCons3", obj.getClass().getName());
  963. assertEquals(2, obj.getClass().getDeclaredConstructors().length);
  964. }
  965. public void testAddInterfaceMethod() throws Exception {
  966. CtClass cc = sloader.makeInterface("test3.AddIntfMth");
  967. CtMethod m = CtMethod.make("void foo();", cc);
  968. cc.addMethod(m);
  969. assertTrue(Modifier.isPublic(m.getModifiers()));
  970. CtMethod m2 = CtMethod.make("public void foo2();", cc);
  971. cc.addMethod(m2);
  972. assertTrue(Modifier.isPublic(m2.getModifiers()));
  973. CtMethod m3 = CtMethod.make("public void foo3() {}", cc);
  974. try {
  975. cc.addMethod(m3);
  976. if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_8)
  977. fail();
  978. }
  979. catch (CannotCompileException e) {
  980. // System.out.println(e);
  981. }
  982. }
  983. // JIRA-67
  984. public void test67() throws Exception {
  985. ClassPool pool = new ClassPool(true);
  986. CtClass ctc = pool.makeClass("test3.Clazz67");
  987. StringBuilder sb = new StringBuilder("public void test() {");
  988. for (int i = 0; i < 1000; i++) {
  989. sb.append("for(int i=0; i<10; i++) {}"); // line 1
  990. // sb.append("for(int i=0; i<10; i++) {int j=i;}"); // line 2
  991. }
  992. sb.append("}");
  993. ctc.addMethod(CtNewMethod.make(sb.toString(), ctc));
  994. ctc.debugWriteFile();
  995. ctc.toClass(DefineClassCapability.class).getConstructor().newInstance();
  996. }
  997. // JIRA-83
  998. public void testEmptyCatch() throws Exception {
  999. CtClass cc = sloader.get("test3.EmptyCatch");
  1000. CtMethod mth = cc.getDeclaredMethod("test");
  1001. mth.instrument(new ExprEditor() {
  1002. public void edit(Handler h) throws CannotCompileException {
  1003. try {
  1004. assertEquals(null, h.getType());
  1005. assertTrue(h.isFinally());
  1006. } catch (NotFoundException e) {}
  1007. }
  1008. });
  1009. }
  1010. }