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

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