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