xref: /aosp_15_r20/external/javassist/src/test/javassist/JvstTest3.java (revision f1fbf3c2ab775ce834e0af96b7a85bdc7a0eac65)
1 package javassist;
2 
3 import javassist.bytecode.*;
4 import javassist.bytecode.annotation.*;
5 import javassist.expr.*;
6 import test3.*;
7 
8 @SuppressWarnings({"rawtypes","unchecked","unused"})
9 public class JvstTest3 extends JvstTestRoot {
JvstTest3(String name)10     public JvstTest3(String name) {
11          super(name);
12     }
13 
testAnnotation()14     public void testAnnotation() throws Exception {
15         CtClass cc = sloader.get("test3.AnnoTest");
16         Object[] all = cc.getAnnotations();
17         Anno a = (Anno)all[0];
18         assertEquals('0', a.c());
19         assertEquals(true, a.bool());
20         assertEquals(1, a.b());
21         assertEquals(2, a.s());
22         assertEquals(3, a.i());
23         assertEquals(4L, a.j());
24         assertEquals(5.0F, a.f());
25         assertEquals(6.0, a.d());
26         assertEquals("7", a.str());
27         assertEquals(AnnoTest.class, a.clazz());
28         assertEquals(3, a.anno2().str().length);
29     }
30 
testAnnotation2()31     public void testAnnotation2() throws Exception {
32         CtClass cc = sloader.get("test3.AnnoTest2");
33         Object[] all = cc.getAnnotations();
34         Anno a = (Anno)all[0];
35         assertEquals('a', a.c());
36         assertEquals(false, a.bool());
37         assertEquals(11, a.b());
38         assertEquals(12, a.s());
39         assertEquals(13, a.i());
40         assertEquals(14L, a.j());
41         assertEquals(15.0F, a.f());
42         assertEquals(16.0, a.d());
43         assertEquals("17", a.str());
44         assertEquals(String.class, a.clazz());
45         assertEquals(11, a.anno2().i()[0]);
46     }
47 
testAnnotation3()48     public void testAnnotation3() throws Exception {
49         CtClass cc = sloader.get("test3.AnnoTest3");
50         Object[] all = cc.getAnnotations();
51         assertEquals(2, all.length);
52         int i;
53         if (all[0] instanceof Anno2)
54             i = 0;
55         else
56             i = 1;
57 
58         Anno2 a = (Anno2)all[i];
59         assertEquals(1, a.i()[0]);
60         assertEquals(test3.ColorName.RED, a.color());
61         assertEquals(test3.ColorName.BLUE, a.color2()[0]);
62     }
63 
testAnnotation4()64     public void testAnnotation4() throws Exception {
65         CtClass cc = sloader.get("test3.AnnoTest4");
66         Object[] all = cc.getAnnotations();
67         Anno3 a = null;
68         for (int i = 0; i < all.length; i++)
69             if (all[i] instanceof Anno3)
70                 a = (Anno3)all[i];
71 
72         assertTrue(a != null);
73         assertEquals('0', a.c()[0]);
74         assertEquals(true, a.bool()[0]);
75         assertEquals(1, a.b()[0]);
76         assertEquals(2, a.s()[0]);
77         assertEquals(3, a.i()[0]);
78         assertEquals(4L, a.j()[0]);
79         assertEquals(5.0F, a.f()[0]);
80         assertEquals(6.0, a.d()[0]);
81         assertEquals("7", a.str()[0]);
82         assertEquals(AnnoTest.class, a.clazz()[0]);
83         assertEquals(11, a.anno2()[0].i()[0]);
84     }
85 
testAnnotation5()86     public void testAnnotation5() throws Exception {
87         CtClass cc = sloader.get("test3.AnnoTest5");
88         Object[] all = cc.getField("bar").getAnnotations();
89         Anno2 a2 = (Anno2)all[0];
90         assertEquals(test3.ColorName.RED, a2.color());
91 
92         all = cc.getDeclaredMethod("foo").getAnnotations();
93         Anno a = (Anno)all[0];
94         assertEquals("7", a.str());
95     }
96 
testAnnotation6()97     public void testAnnotation6() throws Exception {
98         CtClass cc = sloader.get("test3.AnnoTest6");
99         Object[] all = cc.getAnnotations();
100         Anno6 a = (Anno6)all[0];
101         assertEquals(0, a.str1().length);
102         assertEquals(0, a.str2().length);
103     }
104 
testChainedException()105     public void testChainedException() throws Exception {
106         try {
107             throwChainedException();
108         }
109         catch (CannotCompileException e) {
110             e.printStackTrace(System.out);
111         }
112 
113         try {
114             throwChainedException2();
115         }
116         catch (CannotCompileException e) {
117             e.printStackTrace(System.out);
118         }
119 
120         try {
121             throwChainedException3();
122         }
123         catch (Exception e) {
124             e.printStackTrace(System.out);
125         }
126 
127     }
128 
throwChainedException()129     public void throwChainedException() throws Exception {
130         throw new CannotCompileException("test");
131     }
132 
throwChainedException2()133     public void throwChainedException2() throws Exception {
134         Throwable e = new CannotCompileException("test");
135         throw new CannotCompileException("test2", e);
136     }
137 
throwChainedException3()138     public void throwChainedException3() throws Exception {
139         Throwable e = new CannotCompileException("testA");
140         Throwable e2 = new CannotCompileException("testB", e);
141         throw new Exception(e2);
142     }
143 
144     // JIRA Javassist-12
testInnerClassMethod()145     public void testInnerClassMethod() throws Exception {
146         CtClass cc = sloader.get("test3.InnerMethod");
147         CtMethod m1 = cc.getDeclaredMethod("test");
148         m1.setBody("{inner.test();}");
149 
150         CtMethod m2 = CtNewMethod.make(
151             "public int bar() {"
152           + "  if (counter-- <= 0) return 3;"
153           + "  else return bar();"
154           + "}",
155             cc);
156         cc.addMethod(m2);
157 
158         cc.writeFile();
159         Object obj = make(cc.getName());
160         assertEquals(1, invoke(obj, "foo"));
161         assertEquals(3, invoke(obj, "bar"));
162     }
163 
testCheckModifyAndPruned()164     public void testCheckModifyAndPruned() throws Exception {
165         CtClass cc = sloader.get("test3.CheckModify");
166         cc.addField(new CtField(CtClass.intType, "j", cc));
167         cc.stopPruning(false);
168         cc.toBytecode();
169         try {
170             cc.getClassFile();
171             fail();
172         }
173         catch (RuntimeException e) {
174             // System.err.println(e.getMessage());
175             assertTrue(e.getMessage().indexOf("prune") >= 0);
176         }
177     }
178 
testReplaceNew()179     public void testReplaceNew() throws Exception {
180         CtClass cc = sloader.get("test3.ReplaceNew");
181         CtMethod m1 = cc.getDeclaredMethod("run");
182         m1.instrument(new ExprEditor() {
183             public void edit(NewExpr n) throws CannotCompileException {
184                 n.replace("{ i++; $_ = null; }");
185             }
186         });
187 
188         CtMethod m2 = cc.getDeclaredMethod("run2");
189         m2.instrument(new ExprEditor() {
190             public void edit(NewExpr n) throws CannotCompileException {
191                 n.replace("{ j++; $_ = null; }");
192             }
193         });
194 
195         cc.writeFile();
196         Object obj = make(cc.getName());
197         assertEquals(5, invoke(obj, "run"));
198         assertEquals(2, invoke(obj, "run2"));
199     }
200 
testPublicInner()201     public void testPublicInner() throws Exception {
202         CtClass cc0 = sloader.get("test3.PublicInner2");
203         int mod = cc0.getClassFile2().getAccessFlags();
204         System.out.println("testPublicInner: " + mod);
205 
206         CtClass cc = sloader.get("test3.PublicInner");
207         CtClass jp = cc.makeNestedClass("Inner", true);
208         assertEquals(Modifier.PUBLIC | Modifier.STATIC, jp.getModifiers());
209         assertEquals(Modifier.PUBLIC | Modifier.STATIC,
210                      getPublicInner(jp, "Inner"));
211         assertEquals(Modifier.PUBLIC | Modifier.STATIC,
212                      getPublicInner(cc, "Inner"));
213 
214         jp.setModifiers(Modifier.STATIC);
215         assertEquals(Modifier.STATIC, jp.getModifiers());
216         assertEquals(Modifier.STATIC, getPublicInner(jp, "Inner"));
217         assertEquals(Modifier.STATIC, getPublicInner(cc, "Inner"));
218 
219         jp.setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT);
220         assertEquals(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STATIC, jp.getModifiers());
221         assertEquals(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STATIC,
222                      getPublicInner(jp, "Inner"));
223         assertEquals(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STATIC,
224                      getPublicInner(cc, "Inner"));
225 
226         cc.writeFile();
227         jp.writeFile();
228     }
229 
getPublicInner(CtClass cc, String name)230     private int getPublicInner(CtClass cc, String name) throws Exception {
231         ClassFile cf = cc.getClassFile();
232         InnerClassesAttribute ica
233             = (InnerClassesAttribute)cf.getAttribute(
234                                          InnerClassesAttribute.tag);
235         assertEquals(name, ica.innerName(0));
236         return ica.accessFlags(0);
237     }
238 
testConstructorToMethod()239     public void testConstructorToMethod() throws Exception {
240         CtClass cc = sloader.get("test3.Constructor");
241         CtConstructor[] cons = cc.getConstructors();
242         CtConstructor sinit = cc.getClassInitializer();
243 
244         for (int i = 0; i < cons.length; i++) {
245             CtConstructor ccons = cons[i];
246             String desc = ccons.getSignature();
247             boolean result = false;
248             if (desc.equals("()V"))
249                 result = false;
250             else if (desc.equals("(I)V"))
251                 result = true;
252             else if (desc.equals("(Ljava/lang/String;)V"))
253                 result = false;
254             else if (desc.equals("(D)V"))
255                 result = true;
256             else
257                 fail("unknonw constructor");
258 
259             assertEquals(result, ccons.callsSuper());
260         }
261 
262         CtClass cc2 = sloader.get("test3.Constructor2");
263         for (int i = 0; i < cons.length; i++)
264             cc2.addMethod(cons[i].toMethod("m", cc2));
265 
266         cc2.addMethod(sinit.toMethod("sinit", cc2));
267         cc2.addMethod(CtMethod.make(
268             "public int run() { m(); m(5); m(\"s\"); m(0.0);" +
269             "  sinit(); return i + str.length(); }",
270             cc2));
271         cc2.writeFile();
272 
273         Object obj = make(cc2.getName());
274         assertEquals(119, invoke(obj, "run"));
275     }
276 
testUnique()277     public void testUnique() throws Exception {
278         CtClass cc = sloader.get("test3.Unique");
279         CtClass cc2 = sloader.get("test3.Unique3");
280         assertEquals("poi", cc.makeUniqueName("poi"));
281         assertEquals("foo102", cc.makeUniqueName("foo"));
282         assertEquals("bar102", cc2.makeUniqueName("bar"));
283         assertEquals("foo100", cc2.makeUniqueName("foo"));
284     }
285 
testGetMethods()286     public void testGetMethods() throws Exception {
287         CtClass cc = sloader.get("test3.GetMethods");
288         assertEquals(3, cc.getConstructors().length);
289         assertEquals(6, cc.getFields().length);
290         assertEquals(6 + Object.class.getMethods().length + 2,
291                      cc.getMethods().length);
292     }
293 
testVisiblity()294     public void testVisiblity() throws Exception {
295         CtClass cc = sloader.get("test3.Visible");
296         CtClass cc2 = sloader.get("test3.Visible2");
297         CtClass subcc = sloader.get("test3.sub.Visible");
298         CtClass subcc2 = sloader.get("test3.sub.Visible2");
299         CtClass top = sloader.get("VisibleTop");
300         CtClass top2 = sloader.get("VisibleTop2");
301 
302         assertEquals(true, cc.getField("pub").visibleFrom(cc2));
303         assertEquals(true, cc.getField("pub").visibleFrom(subcc));
304 
305         assertEquals(true, cc.getField("pri").visibleFrom(cc));
306         assertEquals(false, cc.getField("pri").visibleFrom(cc2));
307 
308         assertEquals(true, cc.getField("pack").visibleFrom(cc));
309         assertEquals(true, cc.getField("pack").visibleFrom(cc2));
310         assertEquals(false, cc.getField("pack").visibleFrom(subcc));
311         assertEquals(false, cc.getField("pack").visibleFrom(top));
312 
313         assertEquals(true, cc.getField("pro").visibleFrom(cc));
314         assertEquals(true, cc.getField("pro").visibleFrom(cc2));
315         assertEquals(true, cc.getField("pro").visibleFrom(subcc2));
316         assertEquals(false, cc.getField("pro").visibleFrom(subcc));
317         assertEquals(false, cc.getField("pro").visibleFrom(top));
318 
319         assertEquals(true, top.getField("pack").visibleFrom(top2));
320         assertEquals(false, top.getField("pack").visibleFrom(cc));
321     }
322 
testNewAnnotation()323     public void testNewAnnotation() throws Exception {
324         CtClass c = sloader.makeClass("test3.NewClass");
325         ClassFile cf = c.getClassFile();
326         ConstPool cp = cf.getConstPool();
327         AnnotationsAttribute attr
328             = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag);
329         javassist.bytecode.annotation.Annotation a
330             = new Annotation("test3.ChibaAnnotation", cp);
331         a.addMemberValue("name", new StringMemberValue("Chiba", cp));
332         a.addMemberValue("version", new StringMemberValue("Chiba", cp));
333         a.addMemberValue("description", new StringMemberValue("Chiba", cp));
334         a.addMemberValue("interfaceName", new StringMemberValue("Chiba", cp));
335         attr.setAnnotation(a);
336         System.out.println(attr);
337         cf.addAttribute(attr);
338         cf.setVersionToJava5();
339         Object [] ans = c.getAnnotations() ;
340         System.out.println("Num Annotation : " +ans.length);
341 
342         // c.debugWriteFile();
343         Class newclass = c.toClass(DefineClassCapability.class);
344         java.lang.annotation.Annotation[] anns = newclass.getAnnotations();
345         System.out.println("Num NewClass Annotation : " +anns.length);
346         assertEquals(ans.length, anns.length);
347     }
348 
testRecursiveReplace()349     public void testRecursiveReplace() throws Exception {
350         CtClass cc = sloader.get("test3.RecReplace");
351         CtMethod m1 = cc.getDeclaredMethod("run");
352         final ExprEditor e2 = new ExprEditor() {
353             public void edit(MethodCall mc) throws CannotCompileException {
354                 if (mc.getMethodName().equals("bar")) {
355                     mc.replace("{ double k = 10.0; $_ = $proceed($1 + k); }");
356                 }
357             }
358         };
359         m1.instrument(new ExprEditor() {
360             public void edit(MethodCall mc) throws CannotCompileException {
361                 if (mc.getMethodName().equals("foo")) {
362                     mc.replace("{ int k = bar($$); $_ = k + $proceed(7.0); }",
363                     e2);
364                 }
365             }
366         });
367 
368         CtMethod m2 = cc.getDeclaredMethod("run2");
369         m2.instrument(new ExprEditor() {
370             public void edit(MethodCall mc) throws CannotCompileException {
371                 if (mc.getMethodName().equals("foo")) {
372                     mc.replace("{ int k = bar($$); $_ = k + $proceed(7.0); }");
373                 }
374             }
375         });
376 
377         cc.writeFile();
378         Object obj = make(cc.getName());
379         assertEquals(26, invoke(obj, "run"));
380         assertEquals(16, invoke(obj, "run2"));
381     }
382 
testRecursiveReplace2()383     public void testRecursiveReplace2() throws Exception {
384         final ExprEditor[] ref = new ExprEditor[1];
385         ExprEditor e2 = new ExprEditor() {
386             public void edit(FieldAccess fa) throws CannotCompileException {
387                 if (fa.getFieldName().equals("value2")
388                     && fa.isWriter()) {
389                     fa.replace("{ $_ = $proceed($1 + 2); }");
390                 }
391             }
392         };
393         ExprEditor e1 = new ExprEditor() {
394             public void edit(FieldAccess fa) throws CannotCompileException {
395                 if (fa.getFieldName().equals("value")
396                     && fa.isWriter()) {
397                     fa.replace("{ value2 = $1; value = value2; }",
398                                ref[0]);
399                 }
400             }
401         };
402 
403         CtClass cc = sloader.get("test3.RecReplace2");
404         CtMethod m1 = cc.getDeclaredMethod("run");
405         ref[0] = e2;
406         m1.instrument(e1);
407         CtMethod m2 = cc.getDeclaredMethod("run2");
408         ref[0] = null;
409         m2.instrument(e1);
410 
411         cc.writeFile();
412         Object obj = make(cc.getName());
413         assertEquals(28, invoke(obj, "run"));
414         assertEquals(24, invoke(obj, "run2"));
415     }
416 
testInnerModifier()417     public void testInnerModifier() throws Exception {
418         CtClass cc = sloader.get("test3.InnerClass$Inner");
419         assertEquals(Modifier.PUBLIC | Modifier.STATIC, cc.getModifiers());
420         CtClass cc2 = sloader.get("test3.InnerClass$Inner2");
421         assertEquals(Modifier.PUBLIC, cc2.getModifiers());
422     }
423 
testMethodLookup()424     public void testMethodLookup() throws Exception {
425         CtClass cc = sloader.get("test3.SubValue");
426         CtMethod m1 = CtNewMethod.make(
427                 "public int run() {" +
428                 " test3.SuperValue sup = new test3.SuperValue();" +
429                 " test3.SubValue sub = new test3.SubValue();" +
430                 " return this.after(sup, sub, sub) == null ? 0 : 1;" +
431                 "}",
432                 cc);
433         cc.addMethod(m1);
434         cc.writeFile();
435         Object obj = make(cc.getName());
436         assertEquals(1, invoke(obj, "run"));
437     }
438 
testFieldAccessType()439     public void testFieldAccessType() throws Exception {
440         CtClass cc = sloader.get("test3.FieldAccessType");
441         CtMethod m1 = cc.getDeclaredMethod("access");
442         final boolean[] result = new boolean[1];
443         result[0] = true;
444         ExprEditor e = new ExprEditor() {
445             public void edit(FieldAccess fa) throws CannotCompileException {
446                 if (!fa.getSignature().equals("[I"))
447                     result[0] = false;
448             }
449         };
450         m1.instrument(e);
451         assertTrue(result[0]);
452     }
453 
testGetNestedClasses()454     public void testGetNestedClasses() throws Exception {
455         CtClass cc = sloader.get("test3.NestedClass");
456         CtClass[] nested = cc.getNestedClasses();
457         assertEquals(4, nested.length);
458         testGetNestedClasses("test3.NestedClass$Inner", nested);
459         testGetNestedClasses("test3.NestedClass$StaticNested", nested);
460         testGetNestedClasses("test3.NestedClass$1Local", nested);
461         testGetNestedClasses("test3.NestedClass$1", nested);
462     }
463 
testGetNestedClasses(String name, CtClass[] classes)464     private void testGetNestedClasses(String name, CtClass[] classes) {
465         for (int i = 0; i < classes.length; i++)
466             if (classes[i].getName().equals(name))
467                 return;
468 
469         fail("no class: " + name);
470     }
471 
testGetParmeterAnnotations()472     public void testGetParmeterAnnotations() throws Exception {
473         CtClass cc = sloader.get("test3.ParamAnno");
474         Object[][] anno = cc.getDeclaredMethod("foo").getParameterAnnotations();
475         assertEquals(4, anno.length);
476         assertEquals(0, anno[0].length);
477         assertEquals(0, anno[1].length);
478         assertEquals(0, anno[2].length);
479         assertEquals(0, anno[3].length);
480 
481         Object[][] anno2 = cc.getDeclaredMethod("bar").getParameterAnnotations();
482         assertEquals(0, anno2.length);
483 
484         Class rc = Class.forName("test3.ParamAnno");
485         java.lang.reflect.Method[] ms = rc.getDeclaredMethods();
486         java.lang.reflect.Method m1, m2;
487         if (ms[0].getName().equals("foo")) {
488             m1 = ms[0];
489             m2 = ms[1];
490         }
491         else {
492             m1 = ms[1];
493             m2 = ms[0];
494         }
495 
496         java.lang.annotation.Annotation[][] ja;
497         ja = m1.getParameterAnnotations();
498         assertEquals(4, ja.length);
499         assertEquals(0, ja[0].length);
500         assertEquals(0, ja[1].length);
501         assertEquals(0, ja[2].length);
502         assertEquals(0, ja[3].length);
503 
504         assertEquals(0, m2.getParameterAnnotations().length);
505     }
506 
testSetModifiers()507     public void testSetModifiers() throws Exception {
508         CtClass cc = sloader.get("test3.SetModifiers");
509         try {
510             cc.setModifiers(Modifier.STATIC | Modifier.PUBLIC);
511             fail("static public class SetModifiers");
512         }
513         catch (RuntimeException e) {
514             assertEquals("cannot change test3.SetModifiers into a static class", e.getMessage());
515         }
516 
517         cc = sloader.get("test3.SetModifiers$A");
518         cc.setModifiers(Modifier.STATIC | Modifier.PUBLIC);
519         assertTrue(Modifier.isStatic(cc.getModifiers()));
520         assertTrue((cc.getClassFile2().getAccessFlags() & AccessFlag.STATIC) == 0);
521     }
522 
testFieldCopy()523     public void testFieldCopy() throws Exception {
524         CtClass cc = sloader.get("test3.FieldCopy");
525         CtClass cc2 = sloader.get("test3.FieldCopy2");
526         CtField f = cc.getDeclaredField("foo");
527         cc2.addField(new CtField(f, cc2));
528         CtField f2 = cc2.getDeclaredField("foo");
529         Object[] anno = f2.getAnnotations();
530         assertTrue(anno[0] instanceof test3.FieldCopy.Test);
531         assertEquals(Modifier.PRIVATE | Modifier.STATIC,
532                      f2.getModifiers());
533     }
534 
testMethodRedirect()535     public void testMethodRedirect() throws Exception {
536         CtClass cc = sloader.get("test3.MethodRedirect");
537         CtClass cc2 = sloader.get("test3.MethodRedirectIntf");
538         CtMethod foo = cc.getDeclaredMethod("foo");
539         CtMethod poi = cc.getDeclaredMethod("poi");
540         CtMethod bar = cc.getDeclaredMethod("bar");
541         CtMethod afo = cc2.getDeclaredMethod("afo");
542         CodeConverter conv = new CodeConverter();
543 
544         try {
545             conv.redirectMethodCall(foo, bar);
546             fail("foo");
547         }
548         catch (CannotCompileException e) {}
549 
550         try {
551             conv.redirectMethodCall(poi, bar);
552             fail("bar");
553         }
554         catch (CannotCompileException e) {}
555 
556         try {
557             conv.redirectMethodCall(bar, afo);
558             fail("afo");
559         }
560         catch (CannotCompileException e) {}
561         bar.setName("bar2");
562         conv.redirectMethodCall("bar", bar);
563         cc.instrument(conv);
564         // cc.writeFile();
565         Object obj = make(cc.getName());
566         assertEquals(2, invoke(obj, "test"));
567     }
568 
testMethodRedirect2()569     public void testMethodRedirect2() throws Exception {
570         CtClass cc = sloader.get("test3.MethodRedirect2");
571         CtClass sup = sloader.get("test3.MethodRedirect2Sup");
572         CtClass supsup = sloader.get("test3.MethodRedirect2SupSup");
573         CtClass intf = sloader.get("test3.MethodRedirect2SupIntf");
574         CtMethod bfo2 = supsup.getDeclaredMethod("bfo2");
575         CtMethod afo2 = sup.getDeclaredMethod("afo2");
576         CtMethod foo = intf.getDeclaredMethod("foo");
577         CodeConverter conv = new CodeConverter();
578 
579         conv.redirectMethodCall("bfo", bfo2);
580         conv.redirectMethodCall("afo", afo2);
581         conv.redirectMethodCall("bar", foo);
582         conv.redirectMethodCall("bar2", foo);
583         cc.instrument(conv);
584         cc.writeFile();
585         Object obj = make(cc.getName());
586         assertEquals(524, invoke(obj, "test"));
587     }
588 
testClassMap()589     public void testClassMap() throws Exception {
590         ClassMap map = new ClassMap();
591         map.put("aa", "AA");
592         map.put("xx", "XX");
593         assertEquals("AA", map.get("aa"));
594         assertEquals(null, map.get("bb"));
595         ClassMap map2 = new ClassMap(map);
596         map2.put("aa", "A1");
597         map2.put("cc", "CC");
598         assertEquals("A1", map2.get("aa"));
599         assertEquals("CC", map2.get("cc"));
600         assertEquals("XX", map2.get("xx"));
601         assertEquals(null, map2.get("bb"));
602     }
603 
testEmptyConstructor()604     public void testEmptyConstructor() throws Exception {
605         CtClass cc = sloader.get("test3.EmptyConstructor");
606         CtConstructor[] cons = cc.getDeclaredConstructors();
607         for (int i = 0; i < cons.length; i++)
608             assertTrue("index: " + i, cons[i].isEmpty());
609 
610         cc = sloader.get("test3.EmptyConstructor2");
611         cons = cc.getDeclaredConstructors();
612         for (int i = 0; i < cons.length; i++)
613             assertTrue("index: " + i, cons[i].isEmpty());
614 
615         cc = sloader.get("test3.EmptyConstructor3");
616         cons = cc.getDeclaredConstructors();
617         for (int i = 0; i < cons.length; i++)
618             assertTrue("index: " + i, cons[i].isEmpty());
619 
620         cc = sloader.get("test3.EmptyConstructor4");
621         cons = cc.getDeclaredConstructors();
622         for (int i = 0; i < cons.length; i++)
623             assertFalse("index: " + i, cons[i].isEmpty());
624     }
625 
testTransformRead()626     public void testTransformRead() throws Exception {
627         CtClass cc = sloader.get("test3.TransformRead");
628         CtClass parent = cc.getSuperclass();
629         CtMethod m = cc.getDeclaredMethod("foo");
630         CodeConverter conv = new CodeConverter();
631         conv.replaceFieldRead(parent.getField("value"), cc, "getValue");
632         conv.replaceFieldRead(parent.getField("value2"), cc, "getValue2");
633         m.instrument(conv);
634         cc.writeFile();
635         Object obj = make(cc.getName());
636         assertEquals(11100, invoke(obj, "foo"));
637     }
638 
testDescriptor()639     public void testDescriptor() throws Exception {
640         assertEquals("int", Descriptor.toString("I"));
641         assertEquals("long[][]", Descriptor.toString("[[J"));
642         assertEquals("java.lang.Object", Descriptor.toString("Ljava/lang/Object;"));
643         assertEquals("()", Descriptor.toString("()V"));
644         assertEquals("(int)", Descriptor.toString("(I)V"));
645         assertEquals("(int,int[])", Descriptor.toString("(I[I)V"));
646         assertEquals("(java.lang.String,Foo[][])", Descriptor.toString("(Ljava/lang/String;[[LFoo;)V"));
647     }
648 
testLongName()649     public void testLongName() throws Exception {
650         CtClass cc = sloader.get("test3.Name");
651         assertEquals("test3.Name.<clinit>()", cc.getClassInitializer().getLongName());
652         assertEquals("test3.Name()", cc.getConstructor("()V").getLongName());
653         assertEquals("test3.Name(int)", cc.getConstructor("(I)V").getLongName());
654         assertEquals("test3.Name(test3.Name)", cc.getConstructor("(Ltest3/Name;)V").getLongName());
655         assertEquals("test3.Name(test3.Name,java.lang.String)",
656                      cc.getConstructor("(Ltest3/Name;Ljava/lang/String;)V").getLongName());
657 
658         assertEquals("test3.Name.foo()", cc.getDeclaredMethod("foo").getLongName());
659         assertEquals("test3.Name.foo2(int)", cc.getDeclaredMethod("foo2").getLongName());
660         assertEquals("test3.Name.foo3(java.lang.String)", cc.getDeclaredMethod("foo3").getLongName());
661         assertEquals("test3.Name.foo4(java.lang.String[])", cc.getDeclaredMethod("foo4").getLongName());
662         assertEquals("test3.Name.foo5(int,java.lang.String)", cc.getDeclaredMethod("foo5").getLongName());
663     }
664 
testPackageName()665     public void testPackageName() throws Exception {
666         CtClass cc = sloader.get("test3.PackName");
667         CtMethod m1 = CtNewMethod.make(
668                 "public int run() {" +
669                 " return test3.PackName.get() + test3.sub.SubPackName.get(); }",
670                 cc);
671         cc.addMethod(m1);
672         cc.writeFile();
673         Object obj = make(cc.getName());
674         assertEquals(8, invoke(obj, "run"));
675     }
676 
testErasure()677     public void testErasure() throws Exception {
678         CtClass cc = sloader.get("test3.Erasure");
679         cc.addInterface(sloader.get("test3.ErasureGet"));
680         CtMethod m1 = CtNewMethod.make(
681                 "public Object get() { return value; }",
682                 cc);
683         cc.addMethod(m1);
684         cc.writeFile();
685         Object obj = make(cc.getName());
686         assertEquals(4, invoke(obj, "run"));
687     }
688 
689     /* Check the result of JvstTest#testFieldInit()
690      * This tests CtClassType#saveClassFile().
691      */
testFieldInitAgain()692     public void testFieldInitAgain() throws Exception {
693         System.gc();
694         CtClass cc = sloader.get("test1.FieldInit");
695         CtField f = cc.getDeclaredField("f1");
696         assertEquals(CtClass.intType, f.getType());
697         assertTrue("f.hashCode() doesn't change!", f.hashCode() != JvstTest.testFieldInitHash);
698     }
699 
700     /* This tests CtClassType#saveClassFile().
701      * A CtMethod is not garbage collected, its CtClass is never
702      * compressed.
703      */
testCalleeBeforeAgain()704     public void testCalleeBeforeAgain() throws Exception {
705         CtClass cc = sloader.get("test1.CalleeBefore");
706         assertEquals(JvstTest.testCalleeBeforeMethod,
707                      cc.getDeclaredMethod("m1"));
708         assertEquals(JvstTest.testCalleeBeforeMethod2,
709                      cc.getDeclaredMethod("m2").getMethodInfo2().hashCode());
710     }
711 
testSetSuper()712     public void testSetSuper() throws Exception {
713         CtClass cc = sloader.get("test3.Superclass");
714         CtClass cc3 = sloader.get("test3.Superclass3");
715         cc3.setModifiers(Modifier.setPublic(cc3.getModifiers()));
716         cc.setSuperclass(sloader.get("test3.Superclass3"));
717         cc.writeFile();
718         cc3.writeFile();
719         Object obj = make(cc.getName());
720         assertEquals(21, invoke(obj, "test"));
721     }
722 
testFrozen2()723     public void testFrozen2() throws Exception {
724         CtClass cc = sloader.get("test3.Frozen");
725         cc.addField(new CtField(CtClass.intType, "k", cc));
726         cc.toBytecode();
727         cc.toBytecode();
728         cc = sloader.makeClass("test3.Frozen2");
729         cc.toBytecode();
730         cc.toBytecode();
731     }
732 
testCopyAnnotation()733     public void testCopyAnnotation() throws Exception {
734         CtClass cc1 = sloader.get("test3.CopyAnnoBase");
735         CtMethod m1 = cc1.getDeclaredMethod("getX");
736         CtClass cc2 = sloader.get("test3.CopyAnno");
737         CtMethod m2 = cc2.getDeclaredMethod("getX");
738         copyAnnotations(m1, m2);
739         cc2.getClassFile();
740         Class clazz = cc2.toClass(DefineClassCapability.class);
741         java.lang.reflect.Method m = clazz.getDeclaredMethod("getX", new Class[0]);
742         assertEquals(1, m.getAnnotations().length);
743         test3.VisibleAnno a = m.getAnnotation(test3.VisibleAnno.class);
744         assertNotNull(a);
745     }
746 
copyAnnotations(CtMethod src, CtMethod dest)747     private void copyAnnotations(CtMethod src, CtMethod dest)
748         throws NotFoundException
749     {
750        MethodInfo srcInfo = src.getMethodInfo2();
751        MethodInfo destInfo = dest.getMethodInfo2();
752        copyAnnotations(srcInfo, destInfo, AnnotationsAttribute.invisibleTag);
753        copyAnnotations(srcInfo, destInfo, AnnotationsAttribute.visibleTag);
754     }
755 
copyAnnotations(MethodInfo src, MethodInfo dest, String annotationTag)756     private void copyAnnotations(MethodInfo src, MethodInfo dest, String annotationTag) {
757        AnnotationsAttribute attribute = (AnnotationsAttribute)src.getAttribute(annotationTag);
758        if (attribute != null)
759           dest.addAttribute(attribute.copy(dest.getConstPool(), new java.util.HashMap()));
760     }
761 
testStaticFinalField()762     public void testStaticFinalField() throws Exception {
763         CtClass cc = sloader.makeClass("test3.StaticFinalField");
764         CtField fj = new CtField(CtClass.longType, "j", cc);
765         fj.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
766         cc.addField(fj, CtField.Initializer.constant(2L));
767         CtField fi = new CtField(CtClass.intType, "i", cc);
768         fi.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
769         cc.addField(fi, CtField.Initializer.constant(3));
770         CtField fs = new CtField(CtClass.shortType, "s", cc);
771         fs.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
772         cc.addField(fs, CtField.Initializer.constant(4));
773         CtField fc = new CtField(CtClass.charType, "c", cc);
774         fc.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
775         cc.addField(fc, CtField.Initializer.constant('5'));
776         CtField fby = new CtField(CtClass.byteType, "by", cc);
777         fby.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
778         cc.addField(fby, CtField.Initializer.constant(6));
779         CtField fb = new CtField(CtClass.booleanType, "b", cc);
780         fb.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
781         cc.addField(fb, CtField.Initializer.constant(true));
782         CtField ff = new CtField(CtClass.floatType, "f", cc);
783         ff.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
784         cc.addField(ff, CtField.Initializer.constant(7.0F));
785         CtField fstr = new CtField(sloader.get("java.lang.String"), "str", cc);
786         fstr.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
787         cc.addField(fstr, CtField.Initializer.constant("foo"));
788         CtField fobj = new CtField(sloader.get("java.lang.Object"), "obj", cc);
789         fobj.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
790         cc.addField(fobj, CtField.Initializer.constant("bar"));
791 
792         cc.writeFile();
793         Class clazz = cc.toClass(DefineClassCapability.class);
794         assertEquals(2L, clazz.getField("j").getLong(null));
795         assertEquals(3, clazz.getField("i").getInt(null));
796         assertEquals(4, clazz.getField("s").getShort(null));
797         assertEquals('5', clazz.getField("c").getChar(null));
798         assertEquals(6, clazz.getField("by").getByte(null));
799         assertEquals(true, clazz.getField("b").getBoolean(null));
800         assertEquals(7.0F, clazz.getField("f").getFloat(null));
801         assertEquals("foo", clazz.getField("str").get(null));
802         assertEquals("bar", clazz.getField("obj").get(null));
803     }
804 
805     /*
806     public void testClassPath() throws Exception {
807         ClassPool cp = new ClassPool(null);
808         cp.appendClassPath("./test-classpath.JaR");
809         assertNotNull(cp.get("test.Point"));
810         cp = new ClassPool(null);
811         cp.appendClassPath("./*");
812         assertNotNull(cp.get("javassist.bytecode.Gap0Example"));
813     }*/
814 
testVoidReturn()815     public void testVoidReturn() throws Exception {
816         CtClass cc = sloader.get("test3.VoidReturn");
817         CtMethod m1 = cc.getDeclaredMethod("foo");
818         m1.insertAfter("System.out.println(\"return value: \" + $_);", true);
819         cc.writeFile();
820         make(cc.getName());
821     }
822 
testInsertParam0()823     public void testInsertParam0() throws Exception {
824         assertEquals("(I)V", Descriptor.insertParameter(CtClass.intType, "()V"));
825         assertEquals("(ILjava/lang/Object;)V", Descriptor.insertParameter(CtClass.intType, "(Ljava/lang/Object;)V"));
826         assertEquals("(IJ)V", Descriptor.appendParameter(CtClass.longType, "(I)V"));
827         assertEquals("(Ljava/lang/String;I)V", Descriptor.insertParameter(sloader.get("java.lang.String"), "(I)V"));
828     }
829 
testInsertParam()830     public void testInsertParam() throws Exception {
831         CtClass cc = sloader.get("test3.InsParam");
832         CtMethod m1 = cc.getDeclaredMethod("foo");
833         m1.insertParameter(CtClass.longType);
834         m1.insertBefore("$2 += (int)$1;");
835 
836         CtMethod m2 = cc.getDeclaredMethod("bar");
837         m2.addParameter(CtClass.doubleType);
838         m2.insertBefore("$1 += (int)$2;");
839 
840         CtMethod m3 = cc.getDeclaredMethod("poi");
841         m3.addParameter(sloader.get("java.lang.Object"));
842         m3.insertBefore("$2 = (String)$3;");
843 
844         cc.writeFile();
845         Object obj = make(cc.getName());
846         assertEquals(11, invoke(obj, "foo", 10L, 1));
847         assertEquals(11, invoke(obj, "bar", 1, 10.0));
848         assertEquals(3, invoke(obj, "poi", 1, "x", "xx"));
849     }
850 
invoke(Object target, String method, long arg1, int arg2)851     private int invoke(Object target, String method, long arg1, int arg2)
852         throws Exception
853     {
854         java.lang.reflect.Method m =
855             target.getClass().getMethod(method, new Class[] { long.class, int.class });
856         Object res = m.invoke(target, new Object[] { Long.valueOf(arg1), Integer.valueOf(arg2)});
857         return ((Integer)res).intValue();
858     }
859 
invoke(Object target, String method, int arg1, double arg2)860     private int invoke(Object target, String method, int arg1, double arg2)
861         throws Exception
862     {
863         java.lang.reflect.Method m =
864             target.getClass().getMethod(method, new Class[] { int.class, double.class });
865         Object res = m.invoke(target, new Object[] { Integer.valueOf(arg1), Double.valueOf(arg2)});
866         return ((Integer)res).intValue();
867     }
868 
invoke(Object target, String method, int arg1, String arg2, Object arg3)869     private int invoke(Object target, String method, int arg1, String arg2, Object arg3)
870         throws Exception
871     {
872         java.lang.reflect.Method m =
873             target.getClass().getMethod(method, new Class[] { int.class, String.class, Object.class });
874         Object res = m.invoke(target, new Object[] { Integer.valueOf(arg1), arg2, arg3});
875         return ((Integer)res).intValue();
876     }
877 
testInvokeinterface()878     public void testInvokeinterface() throws Exception {
879         // JIRA JASSIST-60
880         CtClass cc = sloader.get("test3.InvokeIntf");
881         CtMethod mth = cc.getDeclaredMethod("doit");
882         ExprEditor e = new ExprEditor() {
883             public void edit(MethodCall m) throws CannotCompileException {
884                 String block = "{$_=$proceed($$);}";
885                 m.replace(block);
886             }
887         };
888         mth.instrument(e);
889         cc.writeFile();
890         Object obj = make(cc.getName());
891         assertEquals(7, invoke(obj, "test"));
892     }
893 
testInvokeArrayObj()894     public void testInvokeArrayObj() throws Exception {
895         // JIRA JASSIST-61
896         CtClass cc = sloader.get("test3.InvokeArray");
897         CtMethod mth = cc.getDeclaredMethod("doit");
898         ExprEditor e = new ExprEditor() {
899             public void edit(MethodCall m) throws CannotCompileException {
900                 String block = "{$_=$proceed($$);}";
901                 m.replace(block);
902             }
903         };
904         mth.instrument(e);
905         cc.writeFile();
906         Object obj = make(cc.getName());
907         assertEquals(3, invoke(obj, "test"));
908     }
909 
testNewExprTry()910     public void testNewExprTry() throws Exception {
911         CtClass cc = sloader.get("test3.NewExprTryCatch");
912         CtMethod mth = cc.getDeclaredMethod("instrumentMe");
913         ExprEditor e = new ExprEditor() {
914             public void edit(NewExpr m) throws CannotCompileException {
915                 String block = "{$_=$proceed($$);}";
916                 m.replace(block);
917             }
918         };
919         mth.instrument(e);
920 
921         // JIRA JASSIST-52
922         CtMethod mth2 = cc.getDeclaredMethod("me2");
923         ExprEditor e2 = new ExprEditor() {
924             public void edit(MethodCall m) throws CannotCompileException {
925                 String block = "{try{$_=$proceed($$);} catch(Throwable t) {}}";
926                 m.replace(block);
927             }
928         };
929         //mth2.instrument(e2);
930 
931         /*
932         // JIRA JASSIST-53
933         CtClass cc2 = sloader.get("test3.NewExprTryCatch2");
934         CtBehavior mth3 = cc2.getDeclaredConstructors()[0];
935         ExprEditor e3 = new ExprEditor() {
936             public void edit(ConstructorCall m) throws CannotCompileException {
937                 String block = "{try {$_=$proceed($$);} catch (Throwable t) {}}";
938                 m.replace(block);
939             }
940         };
941         mth3.instrument(e3);
942         */
943 
944         cc.writeFile();
945         // cc2.writeFile();
946         Object obj = make(cc.getName());
947         assertEquals(0, invoke(obj, "test"));
948         // Object obj2 = make(cc2.getName());
949     }
950 
testJIRA63()951     public void testJIRA63() throws Exception {
952         frameTypeTest(2);
953         frameTypeTest(7);
954     }
955 
frameTypeTest(final int initializerRepeatCount)956     private void frameTypeTest(final int initializerRepeatCount) throws Exception {
957         // Get a class
958         final CtClass cTst = sloader.get("test3.JIRA63");
959         cTst.getClassFile().setMajorVersion(ClassFile.JAVA_6);
960         try {
961             // Create an initializer for the fields
962             String initializer = "test3.JIRA63Helper";
963             for(int i=0; i < initializerRepeatCount; i++)
964                 initializer += ".getAnObject(new Integer(1))";
965 
966             initializer += ";";
967 
968             // Add some fields
969             final CtClass cObj = sloader.get("java.lang.Object");
970             for(int i = 0; i < 7; i++)
971                 cTst.addField(new CtField(cObj, "a" + i, cTst), initializer);
972 
973             // Modify the constructors
974             for(final CtConstructor m : cTst.getConstructors()) {
975                 m.insertAfter(initializer, true);
976                 m.insertBefore(initializer);
977             }
978 
979             // Get the byte code.
980             // cTst.toBytecode();
981             cTst.writeFile();
982             //make(cTst.getName());
983         }
984         finally {
985             cTst.detach();
986         }
987     }
988 
testInsertBeforeType()989     public void testInsertBeforeType() throws Exception {
990         CtClass cc = sloader.get("test3.InsertBeforeType");
991         CtMethod m1 = cc.getDeclaredMethod("foo");
992         m1.insertBefore("value = $type.getName();");
993         cc.writeFile();
994         Object obj = make(cc.getName());
995         assertEquals(5, invoke(obj, "test"));
996     }
997 
testTransformNewClass()998     public void testTransformNewClass() throws Exception {
999         CodeConverter conv = new CodeConverter();
1000         conv.replaceNew(sloader.get("test3.TransNewClassOld"),
1001                         sloader.get("test3.TransNewClassNew"));
1002         CtClass cc = sloader.get("test3.TransNewClass");
1003         cc.instrument(conv);
1004         cc.writeFile();
1005 
1006         CtClass cc2 = sloader.get("test3.TransNewClass$TransNewClass2");
1007         cc2.instrument(conv);
1008         cc2.writeFile();
1009 
1010         Object obj = make(cc.getName());
1011         assertEquals(170, invoke(obj, "test"));
1012         Object obj2 = make(cc2.getName());
1013         assertEquals(50, invoke(obj2, "test"));
1014     }
1015 
testInsertAfter()1016     public void testInsertAfter() throws Exception {
1017         CtClass cc = sloader.get("test3.InsertAfter");
1018         CtMethod m1 = cc.getDeclaredMethod("foo");
1019         m1.insertAfter("k++;", true);
1020         CtConstructor cons = cc.getConstructor("()V");
1021         cons.insertAfter("k++;", true);
1022         cc.writeFile();
1023         Object obj = make(cc.getName());
1024         assertEquals(6, invoke(obj, "test"));
1025     }
1026 
testInsertSwitch()1027     public void testInsertSwitch() throws Exception {
1028         CtClass cc = sloader.get("test3.Switch");
1029         CtMethod m1 = cc.getDeclaredMethod("foo");
1030         String sourceCode = "{"
1031             + "System.out.println(\"Bla!\");"
1032             + "}";
1033         String toInsert =
1034             " try " +
1035             " {   " +
1036             sourceCode +
1037             " }   " +
1038             " catch(Throwable e) " +
1039             " {   " +
1040             "   e.printStackTrace(); " +
1041             " }   ";
1042 
1043         m1.insertBefore(toInsert);
1044         cc.writeFile();
1045         Object obj = make(cc.getName());
1046         assertEquals(0, invoke(obj, "test"));
1047     }
1048 
testStringBuilder()1049     public void testStringBuilder() throws Exception {
1050         CtClass cc = sloader.get("test3.StrBuild");
1051         CtMethod mth = cc.getDeclaredMethod("test");
1052         ExprEditor ed = new ExprEditor() {
1053             public void edit(MethodCall m) throws CannotCompileException {
1054                 String block = "$_=$proceed($$);";
1055                 m.replace(block);
1056             }
1057         };
1058         mth.instrument(ed);
1059         cc.writeFile();
1060         Object obj = make(cc.getName());
1061         assertEquals('t', invoke(obj, "test"));
1062     }
1063 
testInheritCons()1064     public void testInheritCons() throws Exception {
1065         CtClass s = sloader.get("test3.InheritCons");
1066         CtClass cc = sloader.makeClass("test3.InheritCons2", s);
1067         cc.writeFile();
1068         Object obj = make(cc.getName());
1069         assertEquals("test3.InheritCons2", obj.getClass().getName());
1070         assertEquals(3, obj.getClass().getDeclaredConstructors().length);
1071 
1072         cc = sloader.makeClass("InheritCons3", s);
1073         cc.writeFile();
1074         obj = make(cc.getName());
1075         assertEquals("InheritCons3", obj.getClass().getName());
1076         assertEquals(2, obj.getClass().getDeclaredConstructors().length);
1077     }
1078 
testAddInterfaceMethod()1079     public void testAddInterfaceMethod() throws Exception {
1080         CtClass cc = sloader.makeInterface("test3.AddIntfMth");
1081         CtMethod m = CtMethod.make("void foo();", cc);
1082         cc.addMethod(m);
1083         assertTrue(Modifier.isPublic(m.getModifiers()));
1084         CtMethod m2 = CtMethod.make("public void foo2();", cc);
1085         cc.addMethod(m2);
1086         assertTrue(Modifier.isPublic(m2.getModifiers()));
1087         CtMethod m3 = CtMethod.make("public void foo3() {}", cc);
1088         try {
1089             cc.addMethod(m3);
1090             if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_8)
1091                 fail();
1092         }
1093         catch (CannotCompileException e) {
1094             // System.out.println(e);
1095         }
1096     }
1097 
1098     // JIRA-67
test67()1099     public void test67() throws Exception {
1100         ClassPool pool = new ClassPool(true);
1101         CtClass ctc = pool.makeClass("test3.Clazz67");
1102         StringBuilder sb = new StringBuilder("public void test() {");
1103         for (int i = 0; i < 1000; i++) {
1104             sb.append("for(int i=0; i<10; i++) {}"); // line 1
1105             // sb.append("for(int i=0; i<10; i++) {int j=i;}"); // line 2
1106         }
1107 
1108         sb.append("}");
1109         ctc.addMethod(CtNewMethod.make(sb.toString(), ctc));
1110         ctc.debugWriteFile();
1111         ctc.toClass(DefineClassCapability.class).getConstructor().newInstance();
1112     }
1113 
1114     // JIRA-83
testEmptyCatch()1115     public void testEmptyCatch() throws Exception {
1116         CtClass cc = sloader.get("test3.EmptyCatch");
1117         CtMethod mth = cc.getDeclaredMethod("test");
1118         mth.instrument(new ExprEditor() {
1119             public void edit(Handler h) throws CannotCompileException {
1120                 try {
1121                     assertEquals(null, h.getType());
1122                     assertTrue(h.isFinally());
1123                 } catch (NotFoundException e) {}
1124             }
1125         });
1126     }
1127 }
1128