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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515
  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. assertNull(out.getEnclosingMethod());
  451. assertNull(out.getEnclosingBehavior());
  452. CtClass inner2 = sloader.get("test2.Anon$Anon2$1");
  453. assertTrue(inner2.getEnclosingBehavior() instanceof CtConstructor);
  454. assertEquals(sloader.get("test2.Anon$Anon2"), inner2.getEnclosingBehavior().getDeclaringClass());
  455. CtClass inner3 = sloader.get("test2.Anon$Anon3$1");
  456. assertTrue(inner3.getEnclosingBehavior() instanceof CtConstructor);
  457. assertTrue(((CtConstructor)inner3.getEnclosingBehavior()).isClassInitializer());
  458. assertEquals(sloader.get("test2.Anon$Anon3"), inner3.getEnclosingBehavior().getDeclaringClass());
  459. }
  460. public void testMethodInInner() throws Exception {
  461. CtClass inner = sloader.get("test2.Nested2$Inner");
  462. CtClass outer = sloader.get("test2.Nested2");
  463. String src =
  464. "public int f(test2.Nested2 n) {" +
  465. " n.i = 1; n.i++; n.i += 2; return n.i; }";
  466. outer.writeFile();
  467. try {
  468. CtMethod m = CtNewMethod.make(src, inner);
  469. fail();
  470. }
  471. catch (RuntimeException e) {}
  472. outer.defrost();
  473. CtMethod m = CtNewMethod.make(src, inner);
  474. inner.addMethod(m);
  475. src = "public int g(test2.Nested2 n) {" +
  476. " n.d = 1.0; n.d++; n.d += 2.0;" +
  477. " return n.d == 4.0 ? 7 : 8; }";
  478. m = CtNewMethod.make(src, inner);
  479. inner.addMethod(m);
  480. src = "public int h(test2.Nested2 n) {" +
  481. " n.s = \"poi\";" +
  482. "return n.s.length() + f(n) + g(n); }";
  483. m = CtNewMethod.make(src, inner);
  484. inner.addMethod(m);
  485. inner.writeFile();
  486. outer.writeFile();
  487. Object nobj = make(outer.getName());
  488. Object iobj = make(inner.getName());
  489. Method mth = iobj.getClass().getMethod("h",
  490. new Class[] { nobj.getClass() });
  491. Object resobj = mth.invoke(iobj, new Object[] { nobj });
  492. int res = ((Integer) resobj).intValue();
  493. assertEquals(14, res);
  494. }
  495. public void testMethodInInner2() throws Exception {
  496. CtClass inner = sloader.get("test2.Nested3$Inner");
  497. CtClass outer = sloader.get("test2.Nested3");
  498. String src =
  499. "public int f() {" +
  500. " int k = 0;" +
  501. " test2.Nested3 n = new test2.Nested3(3);" +
  502. " k += n.geti();" +
  503. " n = new test2.Nested3();" +
  504. " k += n.geti();" +
  505. " n = new test2.Nested3(\"foo\");" +
  506. " k += n.geti();" +
  507. " return k; }";
  508. outer.stopPruning(true);
  509. outer.writeFile();
  510. try {
  511. CtMethod m = CtNewMethod.make(src, inner);
  512. fail();
  513. }
  514. catch (RuntimeException e) {}
  515. outer.defrost();
  516. CtMethod m = CtNewMethod.make(src, inner);
  517. inner.addMethod(m);
  518. inner.writeFile();
  519. outer.writeFile();
  520. Object iobj = make(inner.getName());
  521. assertEquals(6, invoke(iobj, "f"));
  522. }
  523. public void testMakeNestedClass() throws Exception {
  524. CtClass outer = sloader.get("test2.Nested4");
  525. try {
  526. CtClass inner = outer.makeNestedClass("Inner", false);
  527. fail();
  528. }
  529. catch (RuntimeException e) {
  530. print(e.getMessage());
  531. }
  532. CtClass nested = outer.makeNestedClass("Inner", true);
  533. outer.stopPruning(true);
  534. outer.writeFile();
  535. outer.defrost();
  536. String src =
  537. "public int f() { return test2.Nested4.value; }";
  538. CtMethod m = CtNewMethod.make(src, nested);
  539. nested.addMethod(m);
  540. nested.writeFile();
  541. outer.writeFile();
  542. Object iobj = make(nested.getName());
  543. assertEquals(6, invoke(iobj, "f"));
  544. }
  545. public void testPrivateMethod() throws Exception {
  546. CtClass cc = sloader.get("test2.PrivateMethod");
  547. try {
  548. CtMethod m = CtNewMethod.make(
  549. "public int f(test2.PrivateMethod2 p) { return p.f(); }",
  550. cc);
  551. fail();
  552. }
  553. catch (CannotCompileException e) {}
  554. }
  555. public void testArrayLength() throws Exception {
  556. CtClass cc = sloader.makeClass("test2.ArrayLength");
  557. CtMethod m2 = CtNewMethod.make(
  558. "public int f() { String[] s = new String[3]; " +
  559. "return s.length; }", cc);
  560. cc.addMethod(m2);
  561. cc.writeFile();
  562. Object obj = make(cc.getName());
  563. assertEquals(3, invoke(obj, "f"));
  564. }
  565. public void testMakeStaticMethod() throws Exception {
  566. CtClass cc = sloader.makeClass("test2.MakeStaticMethod");
  567. CtMethod m = CtNewMethod.make(Modifier.PUBLIC | Modifier.STATIC,
  568. CtClass.intType, "create",
  569. new CtClass[] { CtClass.intType }, null,
  570. "{ return $1; }", cc);
  571. cc.addMethod(m);
  572. cc.addMethod(CtNewMethod.make(
  573. "public int test() { return create(13); }", cc));
  574. cc.writeFile();
  575. Object obj = make(cc.getName());
  576. assertEquals(13, invoke(obj, "test"));
  577. }
  578. public void testNewExprTry() throws Exception {
  579. ExprEditor ed = new ExprEditor() {
  580. public void edit(NewExpr expr) throws CannotCompileException {
  581. StringBuffer code = new StringBuffer(300);
  582. code.append("{ try ");
  583. code.append("{ $_ = $proceed($$); }");
  584. code.append("catch (OutOfMemoryError e) {}}");
  585. expr.replace(code.toString());
  586. }
  587. };
  588. CtClass cc = sloader.get("test2.NewExprTry");
  589. CtMethod m1 = cc.getDeclaredMethod("foo");
  590. m1.instrument(ed);
  591. cc.writeFile();
  592. Object obj = make(cc.getName());
  593. assertEquals(16, invoke(obj, "run"));
  594. }
  595. public void testToClass() throws Exception {
  596. ClassPool cp = ClassPool.getDefault();
  597. CtClass cc = cp.makeClass("test2.ToClassTest");
  598. Class c = cc.toClass();
  599. assertEquals(getClass().getClassLoader(), c.getClassLoader());
  600. }
  601. public void testAddCatchForConstructor() throws Exception {
  602. CtClass cc = sloader.get("test2.AddCatchForConstructor");
  603. CtConstructor m1 = cc.getDeclaredConstructors()[0];
  604. m1.addCatch("return;", sloader.get("java.lang.Exception"));
  605. cc.writeFile();
  606. Object obj = make(cc.getName());
  607. }
  608. public void testAddLocalVar() throws Exception {
  609. CtClass cc = sloader.get("test2.AddLocalVar");
  610. CtMethod m1 = cc.getDeclaredMethod("foo");
  611. m1.addLocalVariable("i", CtClass.intType);
  612. m1.insertBefore("i = 3;");
  613. m1.insertAfter("$_ = i + 1;");
  614. cc.writeFile();
  615. Object obj = make(cc.getName());
  616. assertEquals(4, invoke(obj, "foo"));
  617. }
  618. public void testNewArray() throws Exception {
  619. ExprEditor ed = new ExprEditor() {
  620. int dim[] = { 1, 2, 2, 1, 2, 2, 3 };
  621. int cdim[] = { 1, 1, 2, 1, 1, 2, 2 };
  622. int counter = 0;
  623. public void edit(NewArray expr) throws CannotCompileException {
  624. try {
  625. CtClass str = sloader.get("java.lang.String");
  626. if (counter < 3)
  627. assertEquals(str, expr.getComponentType());
  628. else
  629. assertEquals(CtClass.intType, expr.getComponentType());
  630. assertEquals(dim[counter], expr.getDimension());
  631. assertEquals(cdim[counter], expr.getCreatedDimensions());
  632. expr.replace("{ i += $1; $_ = $proceed($$); }");
  633. ++counter;
  634. }
  635. catch (NotFoundException e) {
  636. throw new CannotCompileException(e);
  637. }
  638. }
  639. };
  640. CtClass cc = sloader.get("test2.NewArray");
  641. CtMethod m1 = cc.getDeclaredMethod("foo");
  642. m1.instrument(ed);
  643. cc.writeFile();
  644. Object obj = make(cc.getName());
  645. assertEquals(48, invoke(obj, "run"));
  646. }
  647. public void testToString() throws Exception {
  648. System.out.println(sloader.get("int"));
  649. System.out.println(sloader.get("int[]"));
  650. System.out.println(sloader.get("java.lang.Object"));
  651. System.out.println(sloader.get("java.lang.String"));
  652. System.out.println(sloader.get("javassist.CtNewClass"));
  653. }
  654. public void testDotClass() throws Exception {
  655. testDotClass("test2.DotClass", false);
  656. testDotClass("test2.DotClass_", true);
  657. }
  658. private void testDotClass(String cname, boolean java5) throws Exception {
  659. CtClass cc = sloader.makeClass(cname);
  660. if (java5)
  661. cc.getClassFile2().setVersionToJava5();
  662. CtMethod m = CtNewMethod.make(
  663. "public String getclass() {" +
  664. " return int.class.getName() + int[].class.getName()" +
  665. " + String.class.getName() + String[].class.getName()" +
  666. " + java.lang.Object.class.getName()" +
  667. " + java.util.Vector.class.getName(); }", cc);
  668. cc.addMethod(m);
  669. CtMethod m2 = CtNewMethod.make(
  670. "public int test() {" +
  671. " String s = getclass(); System.out.println(s);" +
  672. " return s.length(); }", cc);
  673. cc.addMethod(m2);
  674. cc.writeFile();
  675. Object obj = make(cc.getName());
  676. assertEquals(72, invoke(obj, "test"));
  677. }
  678. public void testDotClass2() throws Exception {
  679. testDotClass2("test2.DotClass2", false);
  680. testDotClass2("test2.DotClass2_", true);
  681. }
  682. private void testDotClass2(String cname, boolean java5) throws Exception {
  683. CtClass cc = sloader.makeClass(cname);
  684. CtClass cc3 = sloader.makeClass("test2.DotClass3");
  685. if (java5)
  686. cc.getClassFile2().setVersionToJava5();
  687. CtMethod m = CtNewMethod.make(
  688. "public int test() {" +
  689. " return test2.DotClass3.class.getName().length(); }", cc);
  690. cc.addMethod(m);
  691. cc.writeFile();
  692. // don't execute cc3.writeFile();
  693. Object obj = make(cc.getName());
  694. try {
  695. assertEquals(15, invoke(obj, "test"));
  696. }
  697. catch (java.lang.reflect.InvocationTargetException e) {
  698. Throwable t = e.getCause();
  699. assertTrue(t instanceof java.lang.NoClassDefFoundError);
  700. }
  701. }
  702. public void testDotClass4() throws Exception {
  703. testDotClass4("test2.DotClass4", false);
  704. testDotClass4("test2.DotClass4_", true);
  705. }
  706. private void testDotClass4(String cname, boolean java5) throws Exception {
  707. CtClass cc = sloader.makeClass(cname);
  708. if (java5)
  709. cc.getClassFile2().setVersionToJava5();
  710. CtMethod m = CtNewMethod.make(
  711. "public int test() {" +
  712. " String s = Object.class.getName()" +
  713. " + Object[].class.getName();" +
  714. " return s.length(); }", cc);
  715. cc.addMethod(m);
  716. cc.writeFile();
  717. Object obj = make(cc.getName());
  718. assertEquals(35, invoke(obj, "test"));
  719. }
  720. public void testSuperInterface() throws Exception {
  721. CtClass cc = sloader.makeClass("test2.SuperInterface3");
  722. CtClass cc2 = sloader.get("test2.SuperInterface2");
  723. cc.addInterface(cc2);
  724. cc.addField(new CtField(cc2, "inner", cc));
  725. CtMethod m = CtNewMethod.make(
  726. "public int getAge() { return inner.getAge(); }", cc);
  727. cc.addMethod(m);
  728. cc.writeFile();
  729. }
  730. public void testPrune() throws Exception {
  731. CtClass cc = sloader.get("test2.Prune");
  732. cc.stopPruning(false);
  733. System.out.println(cc);
  734. cc.addField(new CtField(CtClass.intType, "f", cc));
  735. cc.toBytecode();
  736. try {
  737. cc.defrost();
  738. fail("can call defrost()");
  739. }
  740. catch (RuntimeException e) {
  741. assertTrue(e.getMessage().indexOf("prune") >= 0);
  742. }
  743. System.out.println(cc);
  744. }
  745. public void testNewExprInTry() throws Exception {
  746. ExprEditor ed = new ExprEditor() {
  747. public void edit(NewExpr expr) throws CannotCompileException {
  748. expr.replace("$_ = new test2.HashMapWrapper($1, 1);");
  749. }
  750. };
  751. CtClass cc = sloader.get("test2.NewExprInTry");
  752. CtMethod m1 = cc.getDeclaredMethod("foo");
  753. m1.instrument(ed);
  754. cc.writeFile();
  755. Object obj = make(cc.getName());
  756. assertEquals(1, invoke(obj, "run"));
  757. }
  758. public void testConstField() throws Exception {
  759. CtClass cc = sloader.get("test2.ConstField");
  760. CtField f;
  761. f = cc.getField("b");
  762. assertEquals(true, ((Boolean)f.getConstantValue()).booleanValue());
  763. f = cc.getField("i");
  764. assertEquals(3, ((Integer)f.getConstantValue()).intValue());
  765. f = cc.getField("j");
  766. assertEquals(7L, ((Long)f.getConstantValue()).longValue());
  767. f = cc.getField("f");
  768. assertEquals(8.0F, ((Float)f.getConstantValue()).floatValue(), 0.0);
  769. f = cc.getField("d");
  770. assertEquals(9.0, ((Double)f.getConstantValue()).doubleValue(), 0.0);
  771. f = cc.getField("s");
  772. assertEquals("const", f.getConstantValue());
  773. f = cc.getField("obj");
  774. assertEquals(null, f.getConstantValue());
  775. f = cc.getField("integer");
  776. assertEquals(null, f.getConstantValue());
  777. f = cc.getField("k");
  778. assertEquals(null, f.getConstantValue());
  779. cc.getClassFile().prune();
  780. f = cc.getField("i");
  781. assertEquals(3, ((Integer)f.getConstantValue()).intValue());
  782. f = cc.getField("k");
  783. assertEquals(null, f.getConstantValue());
  784. }
  785. public void testWhere() throws Exception {
  786. CtClass cc = sloader.get("test2.Where");
  787. CtConstructor cons = cc.getClassInitializer();
  788. cons.instrument(new ExprEditor() {
  789. public void edit(MethodCall m) throws CannotCompileException {
  790. System.out.println(m.where().getName());
  791. }
  792. });
  793. }
  794. public void testNewOp() throws Exception {
  795. CtClass cc = sloader.get("test2.NewOp");
  796. CtMethod add = CtNewMethod.make(
  797. "public test2.NewOp2 " +
  798. " addMonitoringRemoteEventListener(" +
  799. " test2.NewOp2 listener)" +
  800. " throws java.rmi.RemoteException {" +
  801. " $0.listenerList.addElement(listener);" +
  802. " return new test2.NewOp2(0L, this, null, 0L);" +
  803. "}", cc);
  804. add.setModifiers(Modifier.PUBLIC);
  805. cc.addMethod(add);
  806. /*
  807. CtMethod type= CtNewMethod.make(
  808. "public test2.Where getNewType() { return new test2.Where(); }",
  809. cc);
  810. cc.addMethod(type);
  811. */
  812. cc.writeFile();
  813. }
  814. public void testSwitch() throws Exception {
  815. CtClass cc = sloader.makeClass("test2.Switch");
  816. cc.addMethod(CtNewMethod.make(
  817. "public int test1() {" +
  818. " int i = 1;" +
  819. " int j;" +
  820. " switch (i) {" +
  821. " case 0: j = i; break;" +
  822. " case 1: j = -i; break;" +
  823. " default: j = 0; break;" +
  824. " }" +
  825. " return j; }", cc));
  826. cc.addMethod(CtNewMethod.make(
  827. "public int test2() {" +
  828. " int i = 2;" +
  829. " int j = 7;" +
  830. " switch (i) {" +
  831. " case 0: j = i; break;" +
  832. " case 1: j = -i; break;" +
  833. " }" +
  834. " return j; }", cc));
  835. cc.addMethod(CtNewMethod.make(
  836. "public int test3() {" +
  837. " int i = Byte.MAX_VALUE;" +
  838. " int j;" +
  839. " switch (i) {" +
  840. " case Byte.MAX_VALUE: j = i; break;" +
  841. " case Byte.MIN_VALUE: j = -i; break;" +
  842. " default: j = 0; break;" +
  843. " }" +
  844. " return j; }", cc));
  845. try {
  846. cc.addMethod(CtNewMethod.make(
  847. "public int test4() {" +
  848. " int i = Byte.MAX_VALUE;" +
  849. " int j;" +
  850. " switch (i) {" +
  851. " case Byte.MAX_VALUE: j = i; return j;" +
  852. " case Byte.MIN_VALUE: j = -i; return j;" +
  853. " default: j = 0;" +
  854. " }" +
  855. "}", cc));
  856. fail("does not report an error (no return)");
  857. }
  858. catch (CannotCompileException e) { System.out.println(e); }
  859. try {
  860. cc.addMethod(CtNewMethod.make(
  861. "public int test5() {" +
  862. " int i = Byte.MAX_VALUE;" +
  863. " int j;" +
  864. " switch (i) {" +
  865. " case Byte.MAX_VALUE: j = i; return j;" +
  866. " case Byte.MIN_VALUE: j = -i; return j;" +
  867. " }" +
  868. "}", cc));
  869. fail("does not report an error (not default)");
  870. }
  871. catch (CannotCompileException e) { System.out.println(e); }
  872. try {
  873. cc.addMethod(CtNewMethod.make(
  874. "public int test6() {" +
  875. " int i = Byte.MAX_VALUE;" +
  876. " int j;" +
  877. " switch (i) {" +
  878. " case Byte.MAX_VALUE: j = i; break;" +
  879. " default: j = -i; return j;" +
  880. " }" +
  881. " }", cc));
  882. fail("does not report an error (break)");
  883. }
  884. catch (CannotCompileException e) { System.out.println(e); }
  885. cc.addField(CtField.make("public static int k;", cc));
  886. cc.addMethod(CtNewMethod.make(
  887. "public void foo() {" +
  888. " int i = 0;" +
  889. " k = 3;" +
  890. " switch (i) {" +
  891. " case Byte.MAX_VALUE: k = 1;" +
  892. " case Byte.MIN_VALUE: k = 2;" +
  893. " }" +
  894. "}", cc));
  895. cc.addMethod(CtNewMethod.make(
  896. "public int test7() {" +
  897. " int i = Byte.MAX_VALUE;" +
  898. " int j = 3; foo();" +
  899. " System.out.println(k);" +
  900. " switch (i) {" +
  901. " case Byte.MAX_VALUE: return k;" +
  902. " case Byte.MIN_VALUE: return j;" +
  903. " default: return 0;" +
  904. " }" +
  905. "}", cc));
  906. cc.writeFile();
  907. Object obj = make(cc.getName());
  908. assertEquals(-1, invoke(obj, "test1"));
  909. assertEquals(7, invoke(obj, "test2"));
  910. assertEquals(Byte.MAX_VALUE, invoke(obj, "test3"));
  911. assertEquals(3, invoke(obj, "test7"));
  912. }
  913. public void testGet() throws Exception {
  914. CtClass cc = sloader.get("char[]");
  915. CtClass cc2 = cc.getComponentType();
  916. System.out.println(cc2);
  917. }
  918. public void testSynchronized() throws Exception {
  919. CtClass cc = sloader.makeClass("test2.Synch");
  920. cc.addMethod(CtNewMethod.make(
  921. "public synchronized int test1() {" +
  922. " int i = 0;" +
  923. " synchronized (this) {" +
  924. " i = 3;" +
  925. " }" +
  926. " return i; }", cc));
  927. cc.addMethod(CtNewMethod.make(
  928. "public synchronized int test2() {" +
  929. " int i = 0;" +
  930. " synchronized (this) {" +
  931. " i = 3;" +
  932. " return i;" +
  933. " }" +
  934. "}", cc));
  935. cc.addMethod(CtNewMethod.make(
  936. "public synchronized int test3() {" +
  937. " int i = 0;" +
  938. " synchronized (this) {" +
  939. " if (this instanceof String)" +
  940. " return i;" +
  941. " else" +
  942. " i = 3;" +
  943. " }" +
  944. " return i;" +
  945. "}", cc));
  946. cc.addMethod(CtNewMethod.make(
  947. "public synchronized int test4() {" +
  948. " int i = 0;" +
  949. " synchronized (this) {" +
  950. " }" +
  951. " return i; }", cc));
  952. try {
  953. cc.addMethod(CtNewMethod.make(
  954. "public synchronized int test5() {" +
  955. " while (true)" +
  956. " synchronized (this) {" +
  957. " break;" +
  958. " }" +
  959. " return i; }", cc));
  960. fail("does not report an error");
  961. }
  962. catch (CannotCompileException e) { System.out.println(e); }
  963. cc.addMethod(CtNewMethod.make(
  964. "public synchronized int test6() {" +
  965. " int i = 0;" +
  966. " while (true) {" +
  967. " synchronized (this) {" +
  968. " i = 3;" +
  969. " }" +
  970. " break; }" +
  971. " return i; }", cc));
  972. cc.writeFile();
  973. Object obj = make(cc.getName());
  974. assertEquals(3, invoke(obj, "test1"));
  975. assertEquals(3, invoke(obj, "test2"));
  976. assertEquals(3, invoke(obj, "test3"));
  977. assertEquals(0, invoke(obj, "test4"));
  978. }
  979. public void testTryFinally() throws Exception {
  980. CtClass cc = sloader.get("test2.Finally");
  981. cc.addMethod(CtNewMethod.make(
  982. "public int test1() {" +
  983. " a = 0;" +
  984. " try {" +
  985. " update();" +
  986. " } catch (NullPointerException e) {" +
  987. " a = 1;" +
  988. " } finally {" +
  989. " a = 2;" +
  990. " }" +
  991. " return a; }", cc));
  992. cc.addMethod(CtNewMethod.make(
  993. "public int test2() {" +
  994. " a = 0;" +
  995. " try {" +
  996. " update(); return a;" +
  997. " } catch (NullPointerException e) {" +
  998. " a = 1; throw e;" +
  999. " } finally {" +
  1000. " a = 2; return a;" +
  1001. " }" +
  1002. "}", cc));
  1003. cc.addMethod(CtNewMethod.make(
  1004. "public int test3() {" +
  1005. " a = 0;" +
  1006. " try {" +
  1007. " update(); return a;" +
  1008. " } catch (NullPointerException e) {" +
  1009. " a = 1;" +
  1010. " } finally {" +
  1011. " a = 2;" +
  1012. " }" +
  1013. " return a;" +
  1014. "}", cc));
  1015. cc.addMethod(CtNewMethod.make(
  1016. "public int test4() {" +
  1017. " a = 0;" +
  1018. " try {" +
  1019. " update(); return a;" +
  1020. " } catch (NullPointerException e) {" +
  1021. " a = 1; return a;" +
  1022. " } finally {" +
  1023. " a = 2;" +
  1024. " }" +
  1025. "}", cc));
  1026. cc.addMethod(CtNewMethod.make(
  1027. "public double test5() {" +
  1028. " b = 1.0;" +
  1029. " try {" +
  1030. " return b;" +
  1031. // " } catch (NullPointerException e) {" +
  1032. // " b = 2.0; return b;" +
  1033. " } finally {" +
  1034. " b += 3.0;" +
  1035. " }" +
  1036. "}", cc));
  1037. cc.addMethod(CtNewMethod.make(
  1038. "public int test5a() {" +
  1039. " return (int)test5();" +
  1040. "}", cc));
  1041. cc.addMethod(CtNewMethod.make(
  1042. "public int test6() {" +
  1043. " a = 0;" +
  1044. " try {" +
  1045. " if (a > 0)" +
  1046. " return a;" +
  1047. " update(); a = 1;" +
  1048. " }" +
  1049. " catch (RuntimeException e) {" +
  1050. " if (a > 0) a = 2; else a = 3;" +
  1051. " }" +
  1052. " catch (Throwable e) {" +
  1053. " a = 4;" +
  1054. " } finally {" +
  1055. " try { if (a < 0) update(); return a; }" +
  1056. " finally { if (a > 0) return a; a = 5; }" +
  1057. " " +
  1058. " }" +
  1059. "}", cc));
  1060. cc.writeFile();
  1061. Object obj = make(cc.getName());
  1062. assertEquals(2, invoke(obj, "test1"));
  1063. assertEquals(2, invoke(obj, "test2"));
  1064. assertEquals(2, invoke(obj, "test3"));
  1065. assertEquals(1, invoke(obj, "test4"));
  1066. assertEquals(1, invoke(obj, "test5a"));
  1067. assertEquals(3, invoke(obj, "test6"));
  1068. }
  1069. public void testConstructorName() throws Exception {
  1070. CtClass cc = sloader.get("test2.Construct");
  1071. CtConstructor[] cons = cc.getDeclaredConstructors();
  1072. assertEquals("Construct", cons[0].getName());
  1073. assertEquals("Construct", cons[1].getName());
  1074. assertEquals("<clinit>", cc.getClassInitializer().getName());
  1075. }
  1076. public void testRemoveCall() throws Exception {
  1077. CtClass cc = sloader.get("test2.RemoveCall");
  1078. CtMethod m1 = cc.getDeclaredMethod("bar");
  1079. m1.instrument(new ExprEditor() {
  1080. public void edit(MethodCall m) throws CannotCompileException {
  1081. m.replace("{ $_ = ($r)null; }");
  1082. }
  1083. });
  1084. cc.writeFile();
  1085. Object obj = make(cc.getName());
  1086. assertEquals(0, invoke(obj, "bar"));
  1087. }
  1088. public void testRemove() throws Exception {
  1089. CtClass cc = sloader.get("test2.Remove");
  1090. testRemove2(cc, "f1");
  1091. testRemove2(cc, "f6");
  1092. testRemove2(cc, "f3");
  1093. CtField p = cc.getField("p");
  1094. try {
  1095. cc.removeField(p);
  1096. fail("non-existing field has been removed");
  1097. }
  1098. catch (NotFoundException e) {}
  1099. testRemove3(cc, "bar");
  1100. testRemove3(cc, "bar2");
  1101. testRemove4(cc, "(I)V");
  1102. cc.writeFile();
  1103. Object obj = make(cc.getName());
  1104. assertEquals(7, invoke(obj, "foo"));
  1105. }
  1106. private void testRemove2(CtClass cc, String fieldName) throws Exception {
  1107. CtField f = cc.getField(fieldName);
  1108. cc.removeField(f);
  1109. try {
  1110. CtField f2 = cc.getField(fieldName);
  1111. fail("the removed field still exists");
  1112. }
  1113. catch (NotFoundException e) {}
  1114. }
  1115. private void testRemove3(CtClass cc, String methodName) throws Exception {
  1116. CtMethod m = cc.getDeclaredMethod(methodName);
  1117. cc.removeMethod(m);
  1118. try {
  1119. CtMethod m2 = cc.getDeclaredMethod(methodName);
  1120. fail("the removed method still exists");
  1121. }
  1122. catch (NotFoundException e) {}
  1123. }
  1124. private void testRemove4(CtClass cc, String desc) throws Exception {
  1125. CtConstructor c = cc.getConstructor(desc);
  1126. cc.removeConstructor(c);
  1127. try {
  1128. CtConstructor c2 = cc.getConstructor(desc);
  1129. fail("the removed method still exists");
  1130. }
  1131. catch (NotFoundException e) {}
  1132. }
  1133. public void testGetAndRename() throws Exception {
  1134. try {
  1135. CtClass cc = sloader.getAndRename("NotExisting", "Existing");
  1136. }
  1137. catch (NotFoundException e) {
  1138. System.out.println(e);
  1139. }
  1140. }
  1141. public void testConstBody() throws Exception {
  1142. CtClass cc = sloader.get("test2.ConstBody");
  1143. CtConstructor cons = new CtConstructor(new CtClass[] {
  1144. sloader.get("java.lang.String"),
  1145. sloader.get("java.lang.Integer") }, cc);
  1146. cons.setBody("super((String)$1, (Integer)$2);");
  1147. cc.addConstructor(cons);
  1148. cc.writeFile();
  1149. Object obj = make(cc.getName());
  1150. assertEquals(1, invoke(obj, "bar"));
  1151. }
  1152. private String methodCallData = null;
  1153. public void testMethodCall() throws Exception {
  1154. CtClass cc = sloader.get("test2.MethodCall");
  1155. CtMethod m1 = cc.getDeclaredMethod("bar");
  1156. m1.instrument(new ExprEditor() {
  1157. public void edit(MethodCall m) throws CannotCompileException {
  1158. if ("clone".equals(m.getMethodName()))
  1159. methodCallData = m.getClassName();
  1160. }
  1161. });
  1162. cc.writeFile();
  1163. assertEquals("java.lang.String[]", methodCallData);
  1164. assertEquals("java.lang.String[]",
  1165. sloader.get("[Ljava/lang/String;").getName());
  1166. assertEquals("int[][]",
  1167. sloader.get("[[I").getName());
  1168. }
  1169. public void testKmatcha() throws Exception {
  1170. CtClass cc = sloader.makeClass("test2.Kmatcha");
  1171. cc.addMethod(CtNewMethod.make(
  1172. "public void display(String [] params){" +
  1173. " if(params == null){" +
  1174. " System.out.println(\"Nothing to display\");" +
  1175. " }else{" +
  1176. " int k = params.length - 1;" +
  1177. " if(k >= 0)" +
  1178. " do " +
  1179. " System.out.println(params[k]);" +
  1180. " while(--k >= 0);" +
  1181. " }}", cc));
  1182. }
  1183. public void testStrict() throws Exception {
  1184. CtClass cc = sloader.makeClass("test2.StrictTest");
  1185. cc.addMethod(CtNewMethod.make(
  1186. "public strictfp int foo(){ " +
  1187. " int strict = 1; return strict + 1; }", cc));
  1188. }
  1189. public void testArrayLen() throws Exception {
  1190. CtClass cc = sloader.get("test2.ArrayLenTest");
  1191. cc.addMethod(CtNewMethod.make(
  1192. "public int foo(){ return this.length; }", cc));
  1193. cc.writeFile();
  1194. Object obj = make(cc.getName());
  1195. assertEquals(1, invoke(obj, "foo"));
  1196. }
  1197. public void testUnicodeIdentifier() throws Exception {
  1198. CtClass cc = sloader.makeClass("test2.UnicodeIdentifier");
  1199. String src = "public int foo(){ int \u5206 = 0; return \u5206; }";
  1200. cc.addMethod(CtNewMethod.make(src, cc));
  1201. }
  1202. public void testBrennan() throws Exception {
  1203. CtClass cc = sloader.get("test2.Brennan");
  1204. cc.addMethod(CtNewMethod.make(
  1205. "public int foo(){" +
  1206. " java.text.SimpleDateFormat df;" +
  1207. " if((df = (java.text.SimpleDateFormat)format) == null)" +
  1208. " df = new java.text.SimpleDateFormat(\"yyyyMMdd\");" +
  1209. " return 1;}", cc));
  1210. cc.writeFile();
  1211. Object obj = make(cc.getName());
  1212. assertEquals(1, invoke(obj, "foo"));
  1213. }
  1214. public void testArrayAndNull() throws Exception {
  1215. CtClass cc = sloader.get("test2.ArrayAndNull");
  1216. CtMethod m = cc.getDeclaredMethod("test");
  1217. m.insertAfter("if ($_ == null) $_ = new int[0];");
  1218. }
  1219. public void testStaticArrays() throws Exception {
  1220. CtClass cc = sloader.makeClass("StaticArrays");
  1221. CtField f = new CtField(sloader.get("test2.StaticArraysMem[]"),
  1222. "myStaticField", cc);
  1223. f.setModifiers(Modifier.STATIC);
  1224. cc.addField(f);
  1225. CtConstructor init = cc.makeClassInitializer();
  1226. String body = "{\n";
  1227. body += ("myStaticField = new test2.StaticArraysMem[2];\n");
  1228. body += ("\n}");
  1229. init.setBody(body);
  1230. }
  1231. public void testObjectSuper() throws Exception {
  1232. CtClass cc = sloader.get("java.lang.Object");
  1233. try {
  1234. cc.addMethod(CtNewMethod.make(
  1235. "public int foo(){ return super.hashCode(); }", cc));
  1236. fail("could access the super of java.lang.Object");
  1237. }
  1238. catch (CannotCompileException e) {}
  1239. }
  1240. public void testStaticFinal() throws Exception {
  1241. CtClass cc = sloader.makeClass("test2.StaticFinal");
  1242. CtField f = new CtField(CtClass.intType, "sff1", cc);
  1243. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1244. cc.addField(f, "5");
  1245. assertEquals(new Integer(5), f.getConstantValue());
  1246. f = new CtField(CtClass.longType, "sff2", cc);
  1247. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1248. cc.addField(f, "6");
  1249. assertEquals(new Long(6), f.getConstantValue());
  1250. f = new CtField(CtClass.floatType, "sff3", cc);
  1251. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1252. cc.addField(f, "7");
  1253. assertEquals(new Float(7.0F), f.getConstantValue());
  1254. f = new CtField(CtClass.floatType, "sff4", cc);
  1255. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1256. cc.addField(f, "8.0");
  1257. assertEquals(new Float(8.0F), f.getConstantValue());
  1258. f = new CtField(CtClass.doubleType, "sff5", cc);
  1259. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1260. cc.addField(f, "9");
  1261. assertEquals(new Double(9.0), f.getConstantValue());
  1262. f = new CtField(CtClass.doubleType, "sff6", cc);
  1263. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1264. cc.addField(f, "10.0");
  1265. assertEquals(new Double(10.0), f.getConstantValue());
  1266. f = new CtField(sloader.get("java.lang.String"), "sff7", cc);
  1267. f.setModifiers(Modifier.STATIC | Modifier.FINAL);
  1268. cc.addField(f, "\"test\"");
  1269. assertEquals("test", f.getConstantValue());
  1270. f = new CtField(sloader.get("java.lang.String"), "sff8", cc);
  1271. f.setModifiers(Modifier.STATIC);
  1272. cc.addField(f, "\"static\"");
  1273. assertEquals(null, f.getConstantValue());
  1274. cc.addMethod(CtNewMethod.make(
  1275. "public int foo(){ return sff1 + sff7.length(); }", cc));
  1276. cc.writeFile();
  1277. Object obj = make(cc.getName());
  1278. assertEquals(9, invoke(obj, "foo"));
  1279. }
  1280. public void testLocalVar() throws Exception {
  1281. CtClass cc = sloader.get("test2.LocalVar");
  1282. CtMethod m = cc.getDeclaredMethod("toString");
  1283. m.addLocalVariable("var", CtClass.booleanType);
  1284. m.insertBefore("{var = true; }");
  1285. m.insertAfter("{if (var) hashCode(); }", false);
  1286. cc.writeFile();
  1287. Object obj = make(cc.getName());
  1288. assertEquals(3, invoke(obj, "foo"));
  1289. }
  1290. public void testImportPackage() throws Exception {
  1291. CtClass cc2 = sloader.makeClass("test2.Imported");
  1292. cc2.writeFile();
  1293. CtClass cc = sloader.makeClass("test2.Importer");
  1294. sloader.importPackage("test2");
  1295. cc.addMethod(CtNewMethod.make(
  1296. "public int foo(){ " +
  1297. " Imported obj = new Imported();" +
  1298. " return obj.getClass().getName().length(); }", cc));
  1299. sloader.clearImportedPackages();
  1300. cc.writeFile();
  1301. Object obj = make(cc.getName());
  1302. assertEquals(14, invoke(obj, "foo"));
  1303. }
  1304. public void testArrayInit() throws Exception {
  1305. CtClass cc = sloader.makeClass("test2.ArrayInit");
  1306. cc.addMethod(CtNewMethod.make(
  1307. "public int foo(){ " +
  1308. " int[] i = new int[] { 1, 2 };" +
  1309. " double[] d = new double[] { 3.0, 4.0 };" +
  1310. " String[] s = new String[] { \"foo\", \"12345\" };" +
  1311. " return i[0] + (int)d[0] + s[1].length(); }", cc));
  1312. cc.addMethod(CtNewMethod.make(
  1313. "public int bar(){ " +
  1314. " int[] i = { 1, 2.0 };" +
  1315. " double[] d = { 3.0, 4 };" +
  1316. " String[] s = { \"foo\", \"12345\" };" +
  1317. " return i[0] + (int)d[0] + s[1].length(); }", cc));
  1318. cc.writeFile();
  1319. Object obj = make(cc.getName());
  1320. assertEquals(9, invoke(obj, "foo"));
  1321. assertEquals(9, invoke(obj, "bar"));
  1322. }
  1323. }