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

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