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

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