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.

JvstTest2.java 52KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525
  1. package javassist;
  2. import java.io.*;
  3. import java.net.URL;
  4. import org.junit.FixMethodOrder;
  5. import org.junit.runners.MethodSorters;
  6. import java.lang.reflect.Method;
  7. import javassist.expr.*;
  8. import test2.DefineClassCapability;
  9. @SuppressWarnings({"rawtypes","unused"})
  10. @FixMethodOrder(MethodSorters.NAME_ASCENDING)
  11. public class JvstTest2 extends JvstTestRoot {
  12. public void testInsertAt() throws Exception {
  13. CtClass cc = sloader.get("test2.InsertAt");
  14. CtMethod m1 = cc.getDeclaredMethod("foo");
  15. int line = 6;
  16. int ln = m1.insertAt(line, false, null);
  17. int ln2 = m1.insertAt(line, "counter++;");
  18. assertEquals(ln, ln2);
  19. assertEquals(7, ln2);
  20. line = 8;
  21. ln = m1.insertAt(line, false, null);
  22. ln2 = m1.insertAt(line, "counter++;");
  23. assertEquals(ln, ln2);
  24. assertEquals(8, ln2);
  25. CtMethod m2 = cc.getDeclaredMethod("bar2");
  26. int ln3 = m2.insertAt(20, "{ int m = 13; j += m; }");
  27. assertEquals(20, ln3);
  28. cc.writeFile();
  29. Object obj = make(cc.getName());
  30. assertEquals(7, invoke(obj, "foo"));
  31. assertEquals(25, invoke(obj, "bar"));
  32. }
  33. public void testInsertLocal() throws Exception {
  34. CtClass cc = sloader.get("test2.InsertLocal");
  35. CtMethod m1 = cc.getDeclaredMethod("foo");
  36. m1.insertBefore("{ i = s.length(); d = 0.14; }");
  37. m1.insertAfter("{ field = i; }");
  38. CtMethod m2 = cc.getDeclaredMethod("run2");
  39. m2.insertAt(22, "{ s = \"12\"; k = 5; }");
  40. CtMethod m3 = cc.getDeclaredMethod("run3");
  41. m3.instrument(new ExprEditor() {
  42. public void edit(NewExpr n) throws CannotCompileException {
  43. n.replace("{ i++; $_ = $proceed($$); }");
  44. }
  45. public void edit(FieldAccess f) throws CannotCompileException {
  46. f.replace("{ i++; $_ = $proceed($$); }");
  47. }
  48. public void edit(MethodCall m) throws CannotCompileException {
  49. m.replace("{ i++; $_ = $proceed($$); }");
  50. }
  51. });
  52. cc.writeFile();
  53. Object obj = make(cc.getName());
  54. assertEquals(317, invoke(obj, "run"));
  55. assertEquals(7, invoke(obj, "run2"));
  56. assertEquals(3, invoke(obj, "run3"));
  57. }
  58. public void testStaticMember() throws Exception {
  59. CtClass cc = sloader.get("test2.StaticMember");
  60. CtMethod m = CtNewMethod.make(
  61. "public int run() {" +
  62. "return test2.StaticMember#k + test2.StaticMember#foo(); }", cc);
  63. cc.addMethod(m);
  64. m = CtNewMethod.make(
  65. "public int run2() {" +
  66. "return k + foo(); }", cc);
  67. cc.addMethod(m);
  68. m = CtNewMethod.make(
  69. "public int run3() {" +
  70. " test2.StaticMember sm = this;" +
  71. " return sm.k + sm.foo(); }", cc);
  72. cc.addMethod(m);
  73. m = CtNewMethod.make(
  74. "public int run4() {" +
  75. " return this.k + this.foo(); }", cc);
  76. cc.addMethod(m);
  77. m = CtNewMethod.make(
  78. "public static int run5() {" +
  79. " return k + foo(); }", cc);
  80. cc.addMethod(m);
  81. m = CtNewMethod.make(
  82. "public int run6() {" +
  83. " test2.IStaticMember i = this; return i.bar(); }", cc);
  84. cc.addMethod(m);
  85. cc.writeFile();
  86. Object obj = make(cc.getName());
  87. assertEquals(10, invoke(obj, "run"));
  88. assertEquals(10, invoke(obj, "run2"));
  89. assertEquals(10, invoke(obj, "run3"));
  90. assertEquals(10, invoke(obj, "run4"));
  91. assertEquals(10, invoke(obj, "run5"));
  92. assertEquals(3, invoke(obj, "run6"));
  93. }
  94. public void testStaticMember2() throws Exception {
  95. CtClass cc = sloader.get("test2.StaticMember2");
  96. cc.addMethod(CtNewMethod.make(
  97. "public int run() {"
  98. + " return test2.StaticMember2.k + test2.StaticMember2.seven()"
  99. + " + (test2.StaticMember2.f + f)"
  100. + " + test2.StaticMember2.f + f; }",
  101. cc));
  102. cc.addMethod(CtNewMethod.make(
  103. "public int run1() {"
  104. + " long j = 1L;"
  105. + " return (int)(j + (test2.StaticMember2.fj + fj)"
  106. + " + test2.StaticMember2.fj + fj); }",
  107. cc));
  108. cc.addMethod(CtNewMethod.make(
  109. "public int run2() {"
  110. + " double x = 1.0;"
  111. + " double d = x + test2.StaticMember2.fd + fd"
  112. + " + (test2.StaticMember2.fd + fd);"
  113. + " return (int)(d * 10); }",
  114. cc));
  115. cc.addMethod(CtNewMethod.make(
  116. "public int run3() {"
  117. + " return (test2.StaticMember2.fb & fb) ? 1 : 0; }",
  118. cc));
  119. cc.writeFile();
  120. Object obj = make(cc.getName());
  121. assertEquals(54, invoke(obj, "run"));
  122. assertEquals(53, invoke(obj, "run1"));
  123. assertEquals(958, invoke(obj, "run2"));
  124. assertEquals(0, invoke(obj, "run3"));
  125. }
  126. public void testSuperCall() throws Exception {
  127. CtClass cc = sloader.get("test2.SuperCall");
  128. CtMethod m1 = cc.getDeclaredMethod("foo");
  129. m1.instrument(new ExprEditor() {
  130. public void edit(MethodCall m) throws CannotCompileException {
  131. m.replace("{ $_ = $proceed($$); }");
  132. }
  133. });
  134. cc.writeFile();
  135. Object obj = make(cc.getName());
  136. invoke(obj, "bar");
  137. }
  138. public void testSetSuper() throws Exception {
  139. CtClass cc = sloader.makeClass("test2.SetSuper");
  140. CtClass cc2 = sloader.makeClass("test2.SetSuperParent");
  141. CtClass intf = sloader.makeInterface("test2.SetSuperIntf");
  142. CtClass remote = sloader.get("java.rmi.Remote");
  143. cc.setSuperclass(cc2);
  144. cc.setInterfaces(new CtClass[] { intf });
  145. intf.setSuperclass(remote);
  146. intf.writeFile();
  147. cc2.writeFile();
  148. cc.writeFile();
  149. assertEquals(cc2, cc.getSuperclass());
  150. assertEquals(intf, cc.getInterfaces()[0]);
  151. assertEquals(sloader.get("java.lang.Object"), intf.getSuperclass());
  152. assertEquals(remote, intf.getInterfaces()[0]);
  153. make(cc.getName());
  154. }
  155. public void testReplaceClassName() throws Exception {
  156. String oldName = "test2.ReplaceClassName2";
  157. String newName = "test2.ReplaceClassName3";
  158. CtClass cc = sloader.get("test2.ReplaceClassName");
  159. cc.replaceClassName(oldName, newName);
  160. cc.writeFile();
  161. CtClass cc2 = dloader.get(cc.getName());
  162. CtMethod m = cc2.getDeclaredMethod("foo");
  163. assertEquals(newName, m.getParameterTypes()[0].getName());
  164. }
  165. public void testCodeGen() throws Exception {
  166. CtClass cc = sloader.get("test2.CodeGen");
  167. CtMethod m1 = cc.getDeclaredMethod("run");
  168. m1.insertBefore(
  169. "{ double d = true ? 1 : 0.1; "
  170. + " d = d > 0.5 ? 0.0 : - 1.0; "
  171. + " System.out.println(d); "
  172. + " String s = \"foo\"; "
  173. + " s = 1 + 2 + s + \"bar\"; "
  174. + " s += \"poi\" + 3 + seven() + seven(\":\" + ' '); "
  175. + " s += .14; "
  176. + " msg = s; "
  177. + " System.out.println(s); }");
  178. // recursive type check is done if $proceed is used.
  179. CtMethod m2 = CtNewMethod.make(
  180. "public int test() {"
  181. + " String s = $proceed(\"int\" + (3 + 0.14)) + '.'; "
  182. + " System.out.println(s); return s.length(); }",
  183. cc, "this", "seven");
  184. cc.addMethod(m2);
  185. cc.writeFile();
  186. Object obj = make(cc.getName());
  187. assertEquals(19, invoke(obj, "run"));
  188. assertEquals(9, invoke(obj, "test"));
  189. }
  190. public void testCodeGen2() throws Exception {
  191. CtClass cc = sloader.makeClass("test2.CodeGen2");
  192. CtMethod m1 = CtNewMethod.make(
  193. "public int test() {"
  194. + " int len;"
  195. + " String s = \"foo\" + \"bar\" + 3;"
  196. + " System.out.println(s); len = s.length();"
  197. + " len = -3 + len; len = len - (7 - 2 + -1);"
  198. + " int k = 3; len += ~k - ~3;"
  199. + " return len; }",
  200. cc);
  201. cc.addMethod(m1);
  202. CtMethod m2 = CtNewMethod.make(
  203. "public int test2() {"
  204. + " double d = 0.2 - -0.1;"
  205. + " d += (0.2 + 0.3) * 1.0;"
  206. + " return (int)(d * 10); }",
  207. cc);
  208. cc.addMethod(m2);
  209. cc.writeFile();
  210. Object obj = make(cc.getName());
  211. assertEquals(0, invoke(obj, "test"));
  212. assertEquals(8, invoke(obj, "test2"));
  213. }
  214. // not used anymore.
  215. private void notTestGetInner() throws Exception {
  216. ClassPool pool = ClassPool.getDefault();
  217. CtClass c = pool.get("javassist.CtMethod.ConstParameter");
  218. CtClass d = pool.get("javassist.CtMethod.ConstParameter");
  219. CtClass e = pool.get("javassist.CtMethod$ConstParameter");
  220. assertSame(c, d);
  221. assertSame(c, e);
  222. try {
  223. c = pool.get("test2.Inner.Fake");
  224. fail("found not-existing class");
  225. }
  226. catch (NotFoundException ex) {}
  227. }
  228. public void testInner() throws Exception {
  229. ClassPool pool = ClassPool.getDefault();
  230. String classname = "test2.Inner";
  231. CtClass target = pool.get(classname);
  232. String src =
  233. "public void sampleMethod() throws Exception {"
  234. + "java.util.Properties props = new java.util.Properties();"
  235. + "test2.Inner2.Child ace = null;"
  236. + "test2.Inner2 agd = new test2.Inner2(props, ace);}";
  237. CtMethod newmethod = CtNewMethod.make(src, target);
  238. target.addMethod(newmethod);
  239. String src2 =
  240. "public java.lang.Character.Subset sampleMethod2() {"
  241. + " java.lang.Character.Subset s "
  242. + " = Character.UnicodeBlock.HIRAGANA; "
  243. + " return s; }";
  244. CtMethod newmethod2 = CtNewMethod.make(src2, target);
  245. target.addMethod(newmethod2);
  246. target.writeFile();
  247. }
  248. public void testURL() throws Exception {
  249. String url;
  250. ClassPool cp = new ClassPool(null);
  251. cp.appendSystemPath();
  252. url = cp.find("java.lang.Object").toString();
  253. System.out.println(url);
  254. if (JvstTest.java9)
  255. assertEquals("jrt:/java.base/java/lang/Object.class", url);
  256. else {
  257. assertTrue(url.startsWith("jar:file:"));
  258. assertTrue(url.endsWith(".jar!/java/lang/Object.class"));
  259. }
  260. assertNull(cp.find("class.not.Exist"));
  261. cp = new ClassPool(null);
  262. cp.insertClassPath(".");
  263. url = cp.find("test2.Inner").toString();
  264. System.out.println("testURL: " + url);
  265. assertTrue(url.startsWith("file:/"));
  266. assertTrue(url.endsWith("/test2/Inner.class"));
  267. assertNull(cp.find("test2.TestURL"));
  268. cp = new ClassPool(null);
  269. cp.insertClassPath(JAR_PATH + "javassist.jar");
  270. url = cp.find("javassist.CtClass").toString();
  271. System.out.println("testURL: " + url);
  272. assertTrue(url.startsWith("jar:file:"));
  273. assertTrue(url.endsWith("javassist.jar!/javassist/CtClass.class"));
  274. assertNull(cp.find("javassist.TestURL"));
  275. cp = new ClassPool(null);
  276. cp.insertClassPath(new LoaderClassPath(cloader));
  277. url = cp.find("javassist.CtMethod").toString();
  278. System.out.println("testURL: " + url);
  279. assertTrue(url.startsWith("file:"));
  280. assertTrue(url.endsWith("/javassist/CtMethod.class"));
  281. assertNull(cp.find("javassist.TestURL"));
  282. cp = new ClassPool(null);
  283. cp.insertClassPath(new ByteArrayClassPath("test2.ByteArray", null));
  284. url = cp.find("test2.ByteArray").toString();
  285. System.out.println("testURL: " + url);
  286. assertTrue(
  287. url.equals("file:/ByteArrayClassPath/test2/ByteArray.class"));
  288. assertNull(cp.find("test2.TestURL"));
  289. }
  290. public void not_testURLClassPath() throws Exception {
  291. String host = "www.csg.is.titech.ac.jp";
  292. String path = "/~chiba/tmp/";
  293. String url;
  294. ClassPool cp = new ClassPool(null);
  295. cp.insertClassPath(new URLClassPath(host, 80, path, "test"));
  296. url = cp.find("test.TestClassPath").toString();
  297. System.out.println(url);
  298. assertEquals("http://" + host + ":80" + path
  299. + "test/TestClassPath.class", url);
  300. assertNull(cp.find("test.No"));
  301. }
  302. public void testGetURL() throws Exception {
  303. CtClass cc = sloader.get("java.lang.String");
  304. String url = cc.getURL().toString();
  305. System.out.println(url);
  306. if (JvstTest.java9) {
  307. assertEquals("jrt:/java.base/java/lang/String.class", url);
  308. }
  309. else {
  310. assertTrue(url.startsWith("jar:file:"));
  311. assertTrue(url.endsWith(".jar!/java/lang/String.class"));
  312. }
  313. cc = sloader.get("int");
  314. try {
  315. URL u = cc.getURL();
  316. fail();
  317. }
  318. catch (NotFoundException e) {
  319. assertEquals("int", e.getMessage());
  320. }
  321. }
  322. public void testInheritance() throws Exception {
  323. ClassPool pool = ClassPool.getDefault();
  324. String classname = "test2.Inherit";
  325. CtClass target = pool.get(classname);
  326. String src =
  327. "public void sampleMethod() {" +
  328. " test2.Inherit i = new test2.Inherit();" +
  329. " test2.Inherit2 i2 = i;" +
  330. " test2.Inherit3 i3 = i;" +
  331. " i3.foo2(); i3.foo2(); i2.foo1(); }";
  332. CtMethod newmethod = CtNewMethod.make(src, target);
  333. target.addMethod(newmethod);
  334. target.writeFile();
  335. }
  336. public void testIncOp() throws Exception {
  337. CtClass target = sloader.makeClass("test2.IncOp");
  338. String src =
  339. "public int sample() {"
  340. + " int ia[] = new int[50];"
  341. + " ia[0] = 1;"
  342. + " int v = ++(ia[0]);"
  343. + " return v; }";
  344. CtMethod newmethod = CtNewMethod.make(src, target);
  345. target.addMethod(newmethod);
  346. target.writeFile();
  347. Object obj = make(target.getName());
  348. assertEquals(2, invoke(obj, "sample"));
  349. }
  350. public void testSetExceptions() throws Exception {
  351. CtClass cc = sloader.get("test2.SetExceptions");
  352. CtMethod m = cc.getDeclaredMethod("f");
  353. CtClass ex = m.getExceptionTypes()[0];
  354. assertEquals("java.lang.Exception", ex.getName());
  355. m.setExceptionTypes(null);
  356. assertEquals(0, m.getExceptionTypes().length);
  357. m.setExceptionTypes(new CtClass[0]);
  358. assertEquals(0, m.getExceptionTypes().length);
  359. m.setExceptionTypes(new CtClass[] { ex });
  360. assertEquals(ex, m.getExceptionTypes()[0]);
  361. }
  362. public void testNullArg() throws Exception {
  363. CtClass cc = sloader.makeClass("test2.NullArgTest");
  364. CtMethod m1 = CtNewMethod.make(
  365. "public Object foo(Object[] obj, int idx) throws Throwable {" +
  366. " return null; }", cc);
  367. cc.addMethod(m1);
  368. CtMethod m2 = CtNewMethod.make(
  369. "public void bar() { this.foo(null, 0); }", cc);
  370. cc.addMethod(m2);
  371. CtMethod m3 = CtNewMethod.make(
  372. "public void bar2() { this.foo((Object[])null, 0); }", cc);
  373. cc.addMethod(m3);
  374. cc.writeFile();
  375. }
  376. public void testAddMethod() throws Exception {
  377. CtClass cc = sloader.get("test2.AddMethod");
  378. CtMethod m = CtNewMethod.make(
  379. "public int f() { return 1; }", cc);
  380. try {
  381. cc.addMethod(m);
  382. fail();
  383. }
  384. catch (CannotCompileException e) {}
  385. CtMethod m2 = CtNewMethod.make(
  386. "public void f(int i, int j) { return 1; }", cc);
  387. cc.addMethod(m2);
  388. try {
  389. cc.addField(new CtField(CtClass.longType, "f", cc));
  390. fail();
  391. }
  392. catch (CannotCompileException e) {}
  393. }
  394. public void testCopyStream() throws Exception {
  395. int[] size = { 100, 4096, 8000, 1023, 1024, 1025, 2047,
  396. 4096*3, 4096*6, 4096*6-1, 4096*256*3, 4096*256*6 };
  397. for (int i = 0; i < size.length; i++) {
  398. byte[] data = new byte[size[i]];
  399. for (int j = 0; j < data.length; j++)
  400. data[j] = (byte)j;
  401. InputStream ins = new ByteArrayInputStream(data);
  402. ByteArrayOutputStream outs = new ByteArrayOutputStream();
  403. ClassPoolTail.copyStream(ins, outs);
  404. byte[] data2 = outs.toByteArray();
  405. if (data2.length != data.length)
  406. throw new Exception("bad size");
  407. for (int k = 0; k < data.length; k++)
  408. if (data[k] != data2[k])
  409. throw new Exception("bad element");
  410. }
  411. }
  412. public void testDeclaringClass() throws Exception {
  413. try {
  414. CtClass cc = sloader.get("test2.NotExistingClass");
  415. }
  416. catch (NotFoundException e) { System.out.println(e); }
  417. CtClass inner = sloader.get("test2.Nested$Inner");
  418. CtClass outer = sloader.get("test2.Nested");
  419. assertEquals(outer, inner.getDeclaringClass());
  420. assertEquals(null, outer.getDeclaringClass());
  421. assertEquals(null, CtClass.intType.getDeclaringClass());
  422. CtClass inner3 = sloader.get("test2.Nested$Inner3");
  423. outer.writeFile();
  424. try {
  425. CtMethod m = CtNewMethod.make(
  426. "public void f(test2.Nested n) { return n.geti(); }",
  427. inner3);
  428. fail();
  429. }
  430. catch (RuntimeException e) {}
  431. outer.defrost();
  432. CtMethod m = CtNewMethod.make(
  433. "public int f(test2.Nested n) { " +
  434. "return n.geti() + test2.Nested.getj(1) + f() + g(); } ",
  435. inner3);
  436. inner3.addMethod(m);
  437. inner3.writeFile();
  438. outer.writeFile();
  439. Object nobj = make(outer.getName());
  440. Object iobj = make(inner3.getName());
  441. Method mth = iobj.getClass().getMethod("f",
  442. new Class[] { nobj.getClass() });
  443. Object resobj = mth.invoke(iobj, new Object[] { nobj });
  444. int res = ((Integer) resobj).intValue();
  445. assertEquals(6, res);
  446. }
  447. public void testDeclaringClass2() throws Exception {
  448. CtClass out = sloader.get("test2.Anon");
  449. CtClass inner = sloader.get("test2.Anon$1");
  450. if (System.getProperty("java.vm.version").startsWith("1.4"))
  451. assertTrue(inner.getEnclosingBehavior() == null);
  452. else {
  453. assertEquals("make", inner.getEnclosingBehavior().getName());
  454. assertEquals(out, inner.getDeclaringClass());
  455. assertEquals(out,
  456. inner.getEnclosingBehavior().getDeclaringClass());
  457. }
  458. assertNull(out.getEnclosingBehavior());
  459. assertNull(out.getEnclosingBehavior());
  460. CtClass inner2 = sloader.get("test2.Anon$Anon2$1");
  461. assertTrue(inner2.getEnclosingBehavior() instanceof CtConstructor);
  462. assertEquals(sloader.get("test2.Anon$Anon2"), inner2.getEnclosingBehavior().getDeclaringClass());
  463. CtClass inner3 = sloader.get("test2.Anon$Anon3$1");
  464. assertTrue(inner3.getEnclosingBehavior() instanceof CtConstructor);
  465. assertTrue(((CtConstructor)inner3.getEnclosingBehavior()).isClassInitializer());
  466. assertEquals(sloader.get("test2.Anon$Anon3"), inner3.getEnclosingBehavior().getDeclaringClass());
  467. }
  468. public void testMethodInInner() throws Exception {
  469. CtClass inner = sloader.get("test2.Nested2$Inner");
  470. CtClass outer = sloader.get("test2.Nested2");
  471. String src =
  472. "public int f(test2.Nested2 n) {" +
  473. " n.i = 1; n.i++; n.i += 2; return n.i; }";
  474. outer.writeFile();
  475. try {
  476. CtMethod m = CtNewMethod.make(src, inner);
  477. fail();
  478. }
  479. catch (RuntimeException e) {}
  480. outer.defrost();
  481. CtMethod m = CtNewMethod.make(src, inner);
  482. inner.addMethod(m);
  483. src = "public int g(test2.Nested2 n) {" +
  484. " n.d = 1.0; n.d++; n.d += 2.0;" +
  485. " return n.d == 4.0 ? 7 : 8; }";
  486. m = CtNewMethod.make(src, inner);
  487. inner.addMethod(m);
  488. src = "public int h(test2.Nested2 n) {" +
  489. " n.s = \"poi\";" +
  490. "return n.s.length() + f(n) + g(n); }";
  491. m = CtNewMethod.make(src, inner);
  492. inner.addMethod(m);
  493. inner.writeFile();
  494. outer.writeFile();
  495. Object nobj = make(outer.getName());
  496. Object iobj = make(inner.getName());
  497. Method mth = iobj.getClass().getMethod("h",
  498. new Class[] { nobj.getClass() });
  499. Object resobj = mth.invoke(iobj, new Object[] { nobj });
  500. int res = ((Integer) resobj).intValue();
  501. assertEquals(14, res);
  502. }
  503. public void testMethodInInner2() throws Exception {
  504. CtClass inner = sloader.get("test2.Nested3$Inner");
  505. CtClass outer = sloader.get("test2.Nested3");
  506. String src =
  507. "public int f() {" +
  508. " int k = 0;" +
  509. " test2.Nested3 n = new test2.Nested3(3);" +
  510. " k += n.geti();" +
  511. " n = new test2.Nested3();" +
  512. " k += n.geti();" +
  513. " n = new test2.Nested3(\"foo\");" +
  514. " k += n.geti();" +
  515. " return k; }";
  516. outer.stopPruning(true);
  517. outer.writeFile();
  518. try {
  519. CtMethod m = CtNewMethod.make(src, inner);
  520. fail();
  521. }
  522. catch (RuntimeException e) {}
  523. outer.defrost();
  524. CtMethod m = CtNewMethod.make(src, inner);
  525. inner.addMethod(m);
  526. inner.writeFile();
  527. outer.writeFile();
  528. Object iobj = make(inner.getName());
  529. assertEquals(6, invoke(iobj, "f"));
  530. }
  531. public void testMakeNestedClass() throws Exception {
  532. CtClass outer = sloader.get("test2.Nested4");
  533. try {
  534. CtClass inner = outer.makeNestedClass("Inner", false);
  535. fail();
  536. }
  537. catch (RuntimeException e) {
  538. print(e.getMessage());
  539. }
  540. CtClass nested = outer.makeNestedClass("Inner", true);
  541. outer.stopPruning(true);
  542. outer.writeFile();
  543. outer.defrost();
  544. String src =
  545. "public int f() { return test2.Nested4.value; }";
  546. CtMethod m = CtNewMethod.make(src, nested);
  547. nested.addMethod(m);
  548. nested.writeFile();
  549. outer.writeFile();
  550. Object iobj = make(nested.getName());
  551. assertEquals(6, invoke(iobj, "f"));
  552. }
  553. public void testPrivateMethod() throws Exception {
  554. CtClass cc = sloader.get("test2.PrivateMethod");
  555. try {
  556. CtMethod m = CtNewMethod.make(
  557. "public int f(test2.PrivateMethod2 p) { return p.f(); }",
  558. cc);
  559. fail();
  560. }
  561. catch (CannotCompileException e) {}
  562. }
  563. public void testArrayLength() throws Exception {
  564. CtClass cc = sloader.makeClass("test2.ArrayLength");
  565. CtMethod m2 = CtNewMethod.make(
  566. "public int f() { String[] s = new String[3]; " +
  567. "return s.length; }", cc);
  568. cc.addMethod(m2);
  569. cc.writeFile();
  570. Object obj = make(cc.getName());
  571. assertEquals(3, invoke(obj, "f"));
  572. }
  573. public void testMakeStaticMethod() throws Exception {
  574. CtClass cc = sloader.makeClass("test2.MakeStaticMethod");
  575. CtMethod m = CtNewMethod.make(Modifier.PUBLIC | Modifier.STATIC,
  576. CtClass.intType, "create",
  577. new CtClass[] { CtClass.intType }, null,
  578. "{ return $1; }", cc);
  579. cc.addMethod(m);
  580. cc.addMethod(CtNewMethod.make(
  581. "public int test() { return create(13); }", cc));
  582. cc.writeFile();
  583. Object obj = make(cc.getName());
  584. assertEquals(13, invoke(obj, "test"));
  585. }
  586. public void testNewExprTry() throws Exception {
  587. ExprEditor ed = new ExprEditor() {
  588. public void edit(NewExpr expr) throws CannotCompileException {
  589. StringBuffer code = new StringBuffer(300);
  590. code.append("{ try ");
  591. code.append("{ $_ = $proceed($$); }");
  592. code.append("catch (OutOfMemoryError e) {}}");
  593. expr.replace(code.toString());
  594. }
  595. };
  596. CtClass cc = sloader.get("test2.NewExprTry");
  597. CtMethod m1 = cc.getDeclaredMethod("foo");
  598. m1.instrument(ed);
  599. cc.writeFile();
  600. Object obj = make(cc.getName());
  601. assertEquals(16, invoke(obj, "run"));
  602. }
  603. public void testToClass() throws Exception {
  604. ClassPool cp = ClassPool.getDefault();
  605. CtClass cc = cp.makeClass("test2.ToClassTest");
  606. Class c = cc.toClass(DefineClassCapability.class);
  607. assertEquals(getClass().getClassLoader(), c.getClassLoader());
  608. }
  609. public void testAddCatchForConstructor() throws Exception {
  610. CtClass cc = sloader.get("test2.AddCatchForConstructor");
  611. CtConstructor m1 = cc.getDeclaredConstructors()[0];
  612. m1.addCatch("return;", sloader.get("java.lang.Exception"));
  613. cc.writeFile();
  614. Object obj = make(cc.getName());
  615. }
  616. public void testAddLocalVar() throws Exception {
  617. CtClass cc = sloader.get("test2.AddLocalVar");
  618. CtMethod m1 = cc.getDeclaredMethod("foo");
  619. m1.addLocalVariable("i", CtClass.intType);
  620. m1.insertBefore("i = 3;");
  621. m1.insertAfter("$_ = i + 1;");
  622. cc.writeFile();
  623. Object obj = make(cc.getName());
  624. assertEquals(4, invoke(obj, "foo"));
  625. }
  626. public void testNewArray() throws Exception {
  627. ExprEditor ed = new ExprEditor() {
  628. int dim[] = { 1, 2, 2, 1, 2, 2, 3 };
  629. int cdim[] = { 1, 1, 2, 1, 1, 2, 2 };
  630. int counter = 0;
  631. public void edit(NewArray expr) throws CannotCompileException {
  632. try {
  633. CtClass str = sloader.get("java.lang.String");
  634. if (counter < 3)
  635. assertEquals(str, expr.getComponentType());
  636. else
  637. assertEquals(CtClass.intType, expr.getComponentType());
  638. assertEquals(dim[counter], expr.getDimension());
  639. assertEquals(cdim[counter], expr.getCreatedDimensions());
  640. expr.replace("{ i += $1; $_ = $proceed($$); }");
  641. ++counter;
  642. }
  643. catch (NotFoundException e) {
  644. throw new CannotCompileException(e);
  645. }
  646. }
  647. };
  648. CtClass cc = sloader.get("test2.NewArray");
  649. CtMethod m1 = cc.getDeclaredMethod("foo");
  650. m1.instrument(ed);
  651. cc.writeFile();
  652. Object obj = make(cc.getName());
  653. assertEquals(48, invoke(obj, "run"));
  654. }
  655. public void testToString() throws Exception {
  656. System.out.println(sloader.get("int"));
  657. System.out.println(sloader.get("int[]"));
  658. System.out.println(sloader.get("java.lang.Object"));
  659. System.out.println(sloader.get("java.lang.String"));
  660. System.out.println(sloader.get("javassist.CtNewClass"));
  661. }
  662. public void testDotClass() throws Exception {
  663. testDotClass("test2.DotClass", false);
  664. testDotClass("test2.DotClass_", true);
  665. }
  666. private void testDotClass(String cname, boolean java5) throws Exception {
  667. CtClass cc = sloader.makeClass(cname);
  668. if (java5)
  669. cc.getClassFile2().setVersionToJava5();
  670. CtMethod m = CtNewMethod.make(
  671. "public String getclass() {" +
  672. " return int.class.getName() + int[].class.getName()" +
  673. " + String.class.getName() + String[].class.getName()" +
  674. " + java.lang.Object.class.getName()" +
  675. " + java.util.Vector.class.getName(); }", cc);
  676. cc.addMethod(m);
  677. CtMethod m2 = CtNewMethod.make(
  678. "public int test() {" +
  679. " String s = getclass(); System.out.println(s);" +
  680. " return s.length(); }", cc);
  681. cc.addMethod(m2);
  682. cc.writeFile();
  683. Object obj = make(cc.getName());
  684. assertEquals(72, invoke(obj, "test"));
  685. }
  686. public void testDotClass2() throws Exception {
  687. testDotClass2("test2.DotClass2", false);
  688. testDotClass2("test2.DotClass2_", true);
  689. }
  690. private void testDotClass2(String cname, boolean java5) throws Exception {
  691. CtClass cc = sloader.makeClass(cname);
  692. CtClass cc3 = sloader.makeClass("test2.DotClass3");
  693. if (java5)
  694. cc.getClassFile2().setVersionToJava5();
  695. CtMethod m = CtNewMethod.make(
  696. "public int test() {" +
  697. " return test2.DotClass3.class.getName().length(); }", cc);
  698. cc.addMethod(m);
  699. cc.writeFile();
  700. // don't execute cc3.writeFile();
  701. Object obj = make(cc.getName());
  702. try {
  703. assertEquals(15, invoke(obj, "test"));
  704. }
  705. catch (java.lang.reflect.InvocationTargetException e) {
  706. Throwable t = e.getCause();
  707. assertTrue(t instanceof java.lang.NoClassDefFoundError);
  708. }
  709. }
  710. public void testDotClass4() throws Exception {
  711. testDotClass4("test2.DotClass4", false);
  712. testDotClass4("test2.DotClass4_", true);
  713. }
  714. private void testDotClass4(String cname, boolean java5) throws Exception {
  715. CtClass cc = sloader.makeClass(cname);
  716. if (java5)
  717. cc.getClassFile2().setVersionToJava5();
  718. CtMethod m = CtNewMethod.make(
  719. "public int test() {" +
  720. " String s = Object.class.getName()" +
  721. " + Object[].class.getName();" +
  722. " return s.length(); }", cc);
  723. cc.addMethod(m);
  724. cc.writeFile();
  725. Object obj = make(cc.getName());
  726. assertEquals(35, invoke(obj, "test"));
  727. }
  728. public void testSuperInterface() throws Exception {
  729. CtClass cc = sloader.makeClass("test2.SuperInterface3");
  730. CtClass cc2 = sloader.get("test2.SuperInterface2");
  731. cc.addInterface(cc2);
  732. cc.addField(new CtField(cc2, "inner", cc));
  733. CtMethod m = CtNewMethod.make(
  734. "public int getAge() { return inner.getAge(); }", cc);
  735. cc.addMethod(m);
  736. cc.writeFile();
  737. }
  738. public void testPrune() throws Exception {
  739. CtClass cc = sloader.get("test2.Prune");
  740. cc.stopPruning(false);
  741. System.out.println(cc);
  742. cc.addField(new CtField(CtClass.intType, "f", cc));
  743. cc.toBytecode();
  744. try {
  745. cc.defrost();
  746. fail("can call defrost()");
  747. }
  748. catch (RuntimeException e) {
  749. assertTrue(e.getMessage().indexOf("prune") >= 0);
  750. }
  751. System.out.println(cc);
  752. }
  753. public void testNewExprInTry() throws Exception {
  754. ExprEditor ed = new ExprEditor() {
  755. public void edit(NewExpr expr) throws CannotCompileException {
  756. expr.replace("$_ = new test2.HashMapWrapper($1, 1);");
  757. }
  758. };
  759. CtClass cc = sloader.get("test2.NewExprInTry");
  760. CtMethod m1 = cc.getDeclaredMethod("foo");
  761. m1.instrument(ed);
  762. cc.writeFile();
  763. Object obj = make(cc.getName());
  764. assertEquals(1, invoke(obj, "run"));
  765. }
  766. public void testConstField() throws Exception {
  767. CtClass cc = sloader.get("test2.ConstField");
  768. CtField f;
  769. f = cc.getField("b");
  770. assertEquals(true, ((Boolean)f.getConstantValue()).booleanValue());
  771. f = cc.getField("i");
  772. assertEquals(3, ((Integer)f.getConstantValue()).intValue());
  773. f = cc.getField("j");
  774. assertEquals(7L, ((Long)f.getConstantValue()).longValue());
  775. f = cc.getField("f");
  776. assertEquals(8.0F, ((Float)f.getConstantValue()).floatValue(), 0.0);
  777. f = cc.getField("d");
  778. assertEquals(9.0, ((Double)f.getConstantValue()).doubleValue(), 0.0);
  779. f = cc.getField("s");
  780. assertEquals("const", f.getConstantValue());
  781. f = cc.getField("obj");
  782. assertEquals(null, f.getConstantValue());
  783. f = cc.getField("integer");
  784. assertEquals(null, f.getConstantValue());
  785. f = cc.getField("k");
  786. assertEquals(null, f.getConstantValue());
  787. cc.getClassFile().prune();
  788. f = cc.getField("i");
  789. assertEquals(3, ((Integer)f.getConstantValue()).intValue());
  790. f = cc.getField("k");
  791. assertEquals(null, f.getConstantValue());
  792. }
  793. public void testWhere() throws Exception {
  794. CtClass cc = sloader.get("test2.Where");
  795. CtConstructor cons = cc.getClassInitializer();
  796. cons.instrument(new ExprEditor() {
  797. public void edit(MethodCall m) throws CannotCompileException {
  798. System.out.println(m.where().getName());
  799. }
  800. });
  801. }
  802. public void testNewOp() throws Exception {
  803. CtClass cc = sloader.get("test2.NewOp");
  804. CtMethod add = CtNewMethod.make(
  805. "public test2.NewOp2 " +
  806. " addMonitoringRemoteEventListener(" +
  807. " test2.NewOp2 listener)" +
  808. " throws java.rmi.RemoteException {" +
  809. " $0.listenerList.addElement(listener);" +
  810. " return new test2.NewOp2(0L, this, null, 0L);" +
  811. "}", cc);
  812. add.setModifiers(Modifier.PUBLIC);
  813. cc.addMethod(add);
  814. /*
  815. CtMethod type= CtNewMethod.make(
  816. "public test2.Where getNewType() { return new test2.Where(); }",
  817. cc);
  818. cc.addMethod(type);
  819. */
  820. cc.writeFile();
  821. }
  822. public void testSwitch() throws Exception {
  823. CtClass cc = sloader.makeClass("test2.Switch");
  824. cc.addMethod(CtNewMethod.make(
  825. "public int test1() {" +
  826. " int i = 1;" +
  827. " int j;" +
  828. " switch (i) {" +
  829. " case 0: j = i; break;" +
  830. " case 1: j = -i; break;" +
  831. " default: j = 0; break;" +
  832. " }" +
  833. " return j; }", cc));
  834. cc.addMethod(CtNewMethod.make(
  835. "public int test2() {" +
  836. " int i = 2;" +
  837. " int j = 7;" +
  838. " switch (i) {" +
  839. " case 0: j = i; break;" +
  840. " case 1: j = -i; break;" +
  841. " }" +
  842. " return j; }", cc));
  843. cc.addMethod(CtNewMethod.make(
  844. "public int test3() {" +
  845. " int i = Byte.MAX_VALUE;" +
  846. " int j;" +
  847. " switch (i) {" +
  848. " case Byte.MAX_VALUE: j = i; break;" +
  849. " case Byte.MIN_VALUE: j = -i; break;" +
  850. " default: j = 0; break;" +
  851. " }" +
  852. " return j; }", cc));
  853. try {
  854. cc.addMethod(CtNewMethod.make(
  855. "public int test4() {" +
  856. " int i = Byte.MAX_VALUE;" +
  857. " int j;" +
  858. " switch (i) {" +
  859. " case Byte.MAX_VALUE: j = i; return j;" +
  860. " case Byte.MIN_VALUE: j = -i; return j;" +
  861. " default: j = 0;" +
  862. " }" +
  863. "}", cc));
  864. fail("does not report an error (no return)");
  865. }
  866. catch (CannotCompileException e) { System.out.println(e); }
  867. try {
  868. cc.addMethod(CtNewMethod.make(
  869. "public int test5() {" +
  870. " int i = Byte.MAX_VALUE;" +
  871. " int j;" +
  872. " switch (i) {" +
  873. " case Byte.MAX_VALUE: j = i; return j;" +
  874. " case Byte.MIN_VALUE: j = -i; return j;" +
  875. " }" +
  876. "}", cc));
  877. fail("does not report an error (not default)");
  878. }
  879. catch (CannotCompileException e) { System.out.println(e); }
  880. try {
  881. cc.addMethod(CtNewMethod.make(
  882. "public int test6() {" +
  883. " int i = Byte.MAX_VALUE;" +
  884. " int j;" +
  885. " switch (i) {" +
  886. " case Byte.MAX_VALUE: j = i; break;" +
  887. " default: j = -i; return j;" +
  888. " }" +
  889. " }", cc));
  890. fail("does not report an error (break)");
  891. }
  892. catch (CannotCompileException e) { System.out.println(e); }
  893. cc.addField(CtField.make("public static int k;", cc));
  894. cc.addMethod(CtNewMethod.make(
  895. "public void foo() {" +
  896. " int i = 0;" +
  897. " k = 3;" +
  898. " switch (i) {" +
  899. " case Byte.MAX_VALUE: k = 1;" +
  900. " case Byte.MIN_VALUE: k = 2;" +
  901. " }" +
  902. "}", cc));
  903. cc.addMethod(CtNewMethod.make(
  904. "public int test7() {" +
  905. " int i = Byte.MAX_VALUE;" +
  906. " int j = 3; foo();" +
  907. " System.out.println(k);" +
  908. " switch (i) {" +
  909. " case Byte.MAX_VALUE: return k;" +
  910. " case Byte.MIN_VALUE: return j;" +
  911. " default: return 0;" +
  912. " }" +
  913. "}", cc));
  914. cc.writeFile();
  915. Object obj = make(cc.getName());
  916. assertEquals(-1, invoke(obj, "test1"));
  917. assertEquals(7, invoke(obj, "test2"));
  918. assertEquals(Byte.MAX_VALUE, invoke(obj, "test3"));
  919. assertEquals(3, invoke(obj, "test7"));
  920. }
  921. public void testGet() throws Exception {
  922. CtClass cc = sloader.get("char[]");
  923. CtClass cc2 = cc.getComponentType();
  924. System.out.println(cc2);
  925. }
  926. public void testSynchronized() throws Exception {
  927. CtClass cc = sloader.makeClass("test2.Synch");
  928. cc.addMethod(CtNewMethod.make(
  929. "public synchronized int test1() {" +
  930. " int i = 0;" +
  931. " synchronized (this) {" +
  932. " i = 3;" +
  933. " }" +
  934. " return i; }", cc));
  935. cc.addMethod(CtNewMethod.make(
  936. "public synchronized int test2() {" +
  937. " int i = 0;" +
  938. " synchronized (this) {" +
  939. " i = 3;" +
  940. " return i;" +
  941. " }" +
  942. "}", cc));
  943. cc.addMethod(CtNewMethod.make(
  944. "public synchronized int test3() {" +
  945. " int i = 0;" +
  946. " synchronized (this) {" +
  947. " if (this instanceof String)" +
  948. " return i;" +
  949. " else" +
  950. " i = 3;" +
  951. " }" +
  952. " return i;" +
  953. "}", cc));
  954. cc.addMethod(CtNewMethod.make(
  955. "public synchronized int test4() {" +
  956. " int i = 0;" +
  957. " synchronized (this) {" +
  958. " }" +
  959. " return i; }", cc));
  960. try {
  961. cc.addMethod(CtNewMethod.make(
  962. "public synchronized int test5() {" +
  963. " while (true)" +
  964. " synchronized (this) {" +
  965. " break;" +
  966. " }" +
  967. " return i; }", cc));
  968. fail("does not report an error");
  969. }
  970. catch (CannotCompileException e) { System.out.println(e); }
  971. cc.addMethod(CtNewMethod.make(
  972. "public synchronized int test6() {" +
  973. " int i = 0;" +
  974. " while (true) {" +
  975. " synchronized (this) {" +
  976. " i = 3;" +
  977. " }" +
  978. " break; }" +
  979. " return i; }", cc));
  980. cc.writeFile();
  981. Object obj = make(cc.getName());
  982. assertEquals(3, invoke(obj, "test1"));
  983. assertEquals(3, invoke(obj, "test2"));
  984. assertEquals(3, invoke(obj, "test3"));
  985. assertEquals(0, invoke(obj, "test4"));
  986. }
  987. public void testTryFinally() throws Exception {
  988. CtClass cc = sloader.get("test2.Finally");
  989. cc.addMethod(CtNewMethod.make(
  990. "public int test1() {" +
  991. " a = 0;" +
  992. " try {" +
  993. " update();" +
  994. " } catch (NullPointerException e) {" +
  995. " a = 1;" +
  996. " } finally {" +
  997. " a = 2;" +
  998. " }" +
  999. " return a; }", cc));
  1000. cc.addMethod(CtNewMethod.make(
  1001. "public int test2() {" +
  1002. " a = 0;" +
  1003. " try {" +
  1004. " update(); return a;" +
  1005. " } catch (NullPointerException e) {" +
  1006. " a = 1; throw e;" +
  1007. " } finally {" +
  1008. " a = 2; return a;" +
  1009. " }" +
  1010. "}", cc));
  1011. cc.addMethod(CtNewMethod.make(
  1012. "public int test3() {" +
  1013. " a = 0;" +
  1014. " try {" +
  1015. " update(); return a;" +
  1016. " } catch (NullPointerException e) {" +
  1017. " a = 1;" +
  1018. " } finally {" +
  1019. " a = 2;" +
  1020. " }" +
  1021. " return a;" +
  1022. "}", cc));
  1023. cc.addMethod(CtNewMethod.make(
  1024. "public int test4() {" +
  1025. " a = 0;" +
  1026. " try {" +
  1027. " update(); return a;" +
  1028. " } catch (NullPointerException e) {" +
  1029. " a = 1; return a;" +
  1030. " } finally {" +
  1031. " a = 2;" +
  1032. " }" +
  1033. "}", cc));
  1034. cc.addMethod(CtNewMethod.make(
  1035. "public double test5() {" +
  1036. " b = 1.0;" +
  1037. " try {" +
  1038. " return b;" +
  1039. // " } catch (NullPointerException e) {" +
  1040. // " b = 2.0; return b;" +
  1041. " } finally {" +
  1042. " b += 3.0;" +
  1043. " }" +
  1044. "}", cc));
  1045. cc.addMethod(CtNewMethod.make(
  1046. "public int test5a() {" +
  1047. " return (int)test5();" +
  1048. "}", cc));
  1049. cc.addMethod(CtNewMethod.make(
  1050. "public int test6() {" +
  1051. " a = 0;" +
  1052. " try {" +
  1053. " if (a > 0)" +
  1054. " return a;" +
  1055. " update(); a = 1;" +
  1056. " }" +
  1057. " catch (RuntimeException e) {" +
  1058. " if (a > 0) a = 2; else a = 3;" +
  1059. " }" +
  1060. " catch (Throwable e) {" +
  1061. " a = 4;" +
  1062. " } finally {" +
  1063. " try { if (a < 0) update(); return a; }" +
  1064. " finally { if (a > 0) return a; a = 5; }" +
  1065. " " +
  1066. " }" +
  1067. "}", cc));
  1068. cc.writeFile();
  1069. Object obj = make(cc.getName());
  1070. assertEquals(2, invoke(obj, "test1"));
  1071. assertEquals(2, invoke(obj, "test2"));
  1072. assertEquals(2, invoke(obj, "test3"));
  1073. assertEquals(1, invoke(obj, "test4"));
  1074. assertEquals(1, invoke(obj, "test5a"));
  1075. assertEquals(3, invoke(obj, "test6"));
  1076. }
  1077. public void testConstructorName() throws Exception {
  1078. CtClass cc = sloader.get("test2.Construct");
  1079. CtConstructor[] cons = cc.getDeclaredConstructors();
  1080. assertEquals("Construct", cons[0].getName());
  1081. assertEquals("Construct", cons[1].getName());
  1082. assertEquals("<clinit>", cc.getClassInitializer().getName());
  1083. }
  1084. public void testRemoveCall() throws Exception {
  1085. CtClass cc = sloader.get("test2.RemoveCall");
  1086. CtMethod m1 = cc.getDeclaredMethod("bar");
  1087. m1.instrument(new ExprEditor() {
  1088. public void edit(MethodCall m) throws CannotCompileException {
  1089. m.replace("{ $_ = ($r)null; }");
  1090. }
  1091. });
  1092. cc.writeFile();
  1093. Object obj = make(cc.getName());
  1094. assertEquals(0, invoke(obj, "bar"));
  1095. }
  1096. public void testRemove() throws Exception {
  1097. CtClass cc = sloader.get("test2.Remove");
  1098. testRemove2(cc, "f1");
  1099. testRemove2(cc, "f6");
  1100. testRemove2(cc, "f3");
  1101. CtField p = cc.getField("p");
  1102. try {
  1103. cc.removeField(p);
  1104. fail("non-existing field has been removed");
  1105. }
  1106. catch (NotFoundException e) {}
  1107. testRemove3(cc, "bar");
  1108. testRemove3(cc, "bar2");
  1109. testRemove4(cc, "(I)V");
  1110. cc.writeFile();
  1111. Object obj = make(cc.getName());
  1112. assertEquals(7, invoke(obj, "foo"));
  1113. }
  1114. private void testRemove2(CtClass cc, String fieldName) throws Exception {
  1115. CtField f = cc.getField(fieldName);
  1116. cc.removeField(f);
  1117. try {
  1118. CtField f2 = cc.getField(fieldName);
  1119. fail("the removed field still exists");
  1120. }
  1121. catch (NotFoundException e) {}
  1122. }
  1123. private void testRemove3(CtClass cc, String methodName) throws Exception {
  1124. CtMethod m = cc.getDeclaredMethod(methodName);
  1125. cc.removeMethod(m);
  1126. try {
  1127. CtMethod m2 = cc.getDeclaredMethod(methodName);
  1128. fail("the removed method still exists");
  1129. }
  1130. catch (NotFoundException e) {}
  1131. }
  1132. private void testRemove4(CtClass cc, String desc) throws Exception {
  1133. CtConstructor c = cc.getConstructor(desc);
  1134. cc.removeConstructor(c);
  1135. try {
  1136. CtConstructor c2 = cc.getConstructor(desc);
  1137. fail("the removed method still exists");
  1138. }
  1139. catch (NotFoundException e) {}
  1140. }
  1141. public void testGetAndRename() throws Exception {
  1142. try {
  1143. CtClass cc = sloader.getAndRename("NotExisting", "Existing");
  1144. }
  1145. catch (NotFoundException e) {
  1146. System.out.println(e);
  1147. }
  1148. }
  1149. public void testConstBody() throws Exception {
  1150. CtClass cc = sloader.get("test2.ConstBody");
  1151. CtConstructor cons = new CtConstructor(new CtClass[] {
  1152. sloader.get("java.lang.String"),
  1153. sloader.get("java.lang.Integer") }, cc);
  1154. cons.setBody("super((String)$1, (Integer)$2);");
  1155. cc.addConstructor(cons);
  1156. cc.writeFile();
  1157. Object obj = make(cc.getName());
  1158. assertEquals(1, invoke(obj, "bar"));
  1159. }
  1160. private String methodCallData = null;
  1161. public void testMethodCall() throws Exception {
  1162. CtClass cc = sloader.get("test2.MethodCall");
  1163. CtMethod m1 = cc.getDeclaredMethod("bar");
  1164. m1.instrument(new ExprEditor() {
  1165. public void edit(MethodCall m) throws CannotCompileException {
  1166. if ("clone".equals(m.getMethodName()))
  1167. methodCallData = m.getClassName();
  1168. }
  1169. });
  1170. cc.writeFile();
  1171. assertEquals("java.lang.String[]", methodCallData);
  1172. assertEquals("java.lang.String[]",
  1173. sloader.get("[Ljava/lang/String;").getName());
  1174. assertEquals("int[][]",
  1175. sloader.get("[[I").getName());
  1176. }
  1177. public void testKmatcha() throws Exception {
  1178. CtClass cc = sloader.makeClass("test2.Kmatcha");
  1179. cc.addMethod(CtNewMethod.make(
  1180. "public void display(String [] params){" +
  1181. " if(params == null){" +
  1182. " System.out.println(\"Nothing to display\");" +
  1183. " }else{" +
  1184. " int k = params.length - 1;" +
  1185. " if(k >= 0)" +
  1186. " do " +
  1187. " System.out.println(params[k]);" +
  1188. " while(--k >= 0);" +
  1189. " }}", cc));
  1190. }
  1191. public void testStrict() throws Exception {
  1192. CtClass cc = sloader.makeClass("test2.StrictTest");
  1193. cc.addMethod(CtNewMethod.make(
  1194. "public strictfp int foo(){ " +
  1195. " int strict = 1; return strict + 1; }", cc));
  1196. }
  1197. public void testArrayLen() throws Exception {
  1198. CtClass cc = sloader.get("test2.ArrayLenTest");
  1199. cc.addMethod(CtNewMethod.make(
  1200. "public int foo(){ return this.length; }", cc));
  1201. cc.writeFile();
  1202. Object obj = make(cc.getName());
  1203. assertEquals(1, invoke(obj, "foo"));
  1204. }
  1205. public void testUnicodeIdentifier() throws Exception {
  1206. CtClass cc = sloader.makeClass("test2.UnicodeIdentifier");
  1207. String src = "public int foo(){ int \u5206 = 0; return \u5206; }";
  1208. cc.addMethod(CtNewMethod.make(src, cc));
  1209. }
  1210. public void testBrennan() throws Exception {
  1211. CtClass cc = sloader.get("test2.Brennan");
  1212. cc.addMethod(CtNewMethod.make(
  1213. "public int foo(){" +
  1214. " java.text.SimpleDateFormat df;" +
  1215. " if((df = (java.text.SimpleDateFormat)format) == null)" +
  1216. " df = new java.text.SimpleDateFormat(\"yyyyMMdd\");" +
  1217. " return 1;}", cc));
  1218. cc.writeFile();
  1219. Object obj = make(cc.getName());
  1220. assertEquals(1, invoke(obj, "foo"));
  1221. }
  1222. public void testArrayAndNull() throws Exception {
  1223. CtClass cc = sloader.get("test2.ArrayAndNull");
  1224. CtMethod m = cc.getDeclaredMethod("test");
  1225. m.insertAfter("if ($_ == null) $_ = new int[0];");
  1226. }
  1227. public void testStaticArrays() throws Exception {
  1228. CtClass cc = sloader.makeClass("StaticArrays");
  1229. CtField f = new CtField(sloader.get("test2.StaticArraysMem[]"),
  1230. "myStaticField", cc);
  1231. f.setModifiers(Modifier.STATIC);
  1232. cc.addField(f);
  1233. CtConstructor init = cc.makeClassInitializer();
  1234. String body = "{\n";
  1235. body += ("myStaticField = new test2.StaticArraysMem[2];\n");
  1236. body += ("\n}");
  1237. init.setBody(body);
  1238. }
  1239. public void testObjectSuper() throws Exception {
  1240. CtClass cc = sloader.get("java.lang.Object");
  1241. try {
  1242. cc.addMethod(CtNewMethod.make(
  1243. "public int foo(){ return super.hashCode(); }", cc));
  1244. fail("could access the super of java.lang.Object");
  1245. }
  1246. catch (CannotCompileException e) {}
  1247. }
  1248. public void testStaticFinal() throws Exception {
  1249. CtClass cc = sloader.makeClass("test2.StaticFinal");
  1250. CtField f = new CtField(CtClass.intType, "sff1", cc);
  1251. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1252. cc.addField(f, "5");
  1253. assertEquals(Integer.valueOf(5), f.getConstantValue());
  1254. f = new CtField(CtClass.longType, "sff2", cc);
  1255. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1256. cc.addField(f, "6");
  1257. assertEquals(Long.valueOf(6), f.getConstantValue());
  1258. f = new CtField(CtClass.floatType, "sff3", cc);
  1259. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1260. cc.addField(f, "7");
  1261. assertEquals(Float.valueOf(7.0F), f.getConstantValue());
  1262. f = new CtField(CtClass.floatType, "sff4", cc);
  1263. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1264. cc.addField(f, "8.0");
  1265. assertEquals(Float.valueOf(8.0F), f.getConstantValue());
  1266. f = new CtField(CtClass.doubleType, "sff5", cc);
  1267. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1268. cc.addField(f, "9");
  1269. assertEquals(Double.valueOf(9.0), f.getConstantValue());
  1270. f = new CtField(CtClass.doubleType, "sff6", cc);
  1271. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1272. cc.addField(f, "10.0");
  1273. assertEquals(Double.valueOf(10.0), f.getConstantValue());
  1274. f = new CtField(sloader.get("java.lang.String"), "sff7", cc);
  1275. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1276. cc.addField(f, "\"test\"");
  1277. assertEquals("test", f.getConstantValue());
  1278. f = new CtField(sloader.get("java.lang.String"), "sff8", cc);
  1279. f.setModifiers(Modifier.STATIC);
  1280. cc.addField(f, "\"static\"");
  1281. assertEquals(null, f.getConstantValue());
  1282. cc.addMethod(CtNewMethod.make(
  1283. "public int foo(){ return sff1 + sff7.length(); }", cc));
  1284. cc.writeFile();
  1285. Object obj = make(cc.getName());
  1286. assertEquals(9, invoke(obj, "foo"));
  1287. }
  1288. public void testLocalVar() throws Exception {
  1289. CtClass cc = sloader.get("test2.LocalVar");
  1290. CtMethod m = cc.getDeclaredMethod("toString");
  1291. m.addLocalVariable("var", CtClass.booleanType);
  1292. m.insertBefore("{var = true; }");
  1293. m.insertAfter("{if (var) hashCode(); }", false);
  1294. cc.writeFile();
  1295. Object obj = make(cc.getName());
  1296. assertEquals(3, invoke(obj, "foo"));
  1297. }
  1298. public void testImportPackage() throws Exception {
  1299. CtClass cc2 = sloader.makeClass("test2.Imported");
  1300. cc2.writeFile();
  1301. CtClass cc = sloader.makeClass("test2.Importer");
  1302. sloader.importPackage("test2");
  1303. cc.addMethod(CtNewMethod.make(
  1304. "public int foo(){ " +
  1305. " Imported obj = new Imported();" +
  1306. " return obj.getClass().getName().length(); }", cc));
  1307. sloader.clearImportedPackages();
  1308. cc.writeFile();
  1309. Object obj = make(cc.getName());
  1310. assertEquals(14, invoke(obj, "foo"));
  1311. }
  1312. public void testArrayInit() throws Exception {
  1313. CtClass cc = sloader.makeClass("test2.ArrayInit");
  1314. cc.addMethod(CtNewMethod.make(
  1315. "public int foo(){ " +
  1316. " int[] i = new int[] { 1, 2 };" +
  1317. " double[] d = new double[] { 3.0, 4.0 };" +
  1318. " String[] s = new String[] { \"foo\", \"12345\" };" +
  1319. " return i[0] + (int)d[0] + s[1].length(); }", cc));
  1320. cc.addMethod(CtNewMethod.make(
  1321. "public int bar(){ " +
  1322. " int[] i = { 1, 2.0 };" +
  1323. " double[] d = { 3.0, 4 };" +
  1324. " String[] s = { \"foo\", \"12345\" };" +
  1325. " return i[0] + (int)d[0] + s[1].length(); }", cc));
  1326. cc.writeFile();
  1327. Object obj = make(cc.getName());
  1328. assertEquals(9, invoke(obj, "foo"));
  1329. assertEquals(9, invoke(obj, "bar"));
  1330. }
  1331. }