1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.generic;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertNotNull;
21 import static org.junit.jupiter.api.Assertions.assertNull;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23 import static org.junit.jupiter.api.Assertions.fail;
24
25 import java.io.File;
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import org.apache.bcel.AbstractTestCase;
30 import org.apache.bcel.Const;
31 import org.apache.bcel.classfile.AnnotationEntry;
32 import org.apache.bcel.classfile.ArrayElementValue;
33 import org.apache.bcel.classfile.ElementValue;
34 import org.apache.bcel.classfile.ElementValuePair;
35 import org.apache.bcel.classfile.JavaClass;
36 import org.apache.bcel.classfile.Method;
37 import org.apache.bcel.classfile.ParameterAnnotationEntry;
38 import org.apache.bcel.classfile.SimpleElementValue;
39 import org.apache.bcel.util.SyntheticRepository;
40 import org.junit.jupiter.api.Test;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public class GeneratingAnnotatedClassesTestCase extends AbstractTestCase {
62 private void assertArrayElementValue(final int nExpectedArrayValues, final AnnotationEntry anno) {
63 final ElementValuePair elementValuePair = anno.getElementValuePairs()[0];
64 assertEquals("value", elementValuePair.getNameString());
65 final ArrayElementValue ev = (ArrayElementValue) elementValuePair.getValue();
66 final ElementValue[] eva = ev.getElementValuesArray();
67 assertEquals(nExpectedArrayValues, eva.length);
68 }
69
70 private void assertMethodAnnotations(final Method method, final int expectedNumberAnnotations, final int nExpectedArrayValues) {
71 final String methodName = method.getName();
72 final AnnotationEntry[] annos = method.getAnnotationEntries();
73 assertEquals(expectedNumberAnnotations, annos.length, () -> "For " + methodName);
74 if (expectedNumberAnnotations != 0) {
75 assertArrayElementValue(nExpectedArrayValues, annos[0]);
76 }
77 }
78
79 private void assertParameterAnnotations(final Method method, final int... expectedNumberOfParmeterAnnotations) {
80 final String methodName = "For " + method.getName();
81 final ParameterAnnotationEntry[] parameterAnnotations = method.getParameterAnnotationEntries();
82 assertEquals(expectedNumberOfParmeterAnnotations.length, parameterAnnotations.length, methodName);
83
84 int i = 0;
85 for (final ParameterAnnotationEntry parameterAnnotation : parameterAnnotations) {
86 final AnnotationEntry[] annos = parameterAnnotation.getAnnotationEntries();
87 final int expectedLength = expectedNumberOfParmeterAnnotations[i++];
88 final int j = i;
89 assertEquals(expectedLength, annos.length, () -> methodName + " parameter " + j);
90 if (expectedLength != 0) {
91 assertSimpleElementValue(annos[0]);
92 }
93 }
94 assertNotNull(method.getAttribute(Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS));
95 assertNull(method.getAttribute(Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS));
96 }
97
98 private void assertSimpleElementValue(final AnnotationEntry anno) {
99 final ElementValuePair elementValuePair = anno.getElementValuePairs()[0];
100 assertEquals("id", elementValuePair.getNameString());
101 final SimpleElementValue ev = (SimpleElementValue) elementValuePair.getValue();
102 assertEquals(42, ev.getValueInt());
103 }
104
105 private void buildClassContents(final ClassGen cg, final ConstantPoolGen cp, final InstructionList il) {
106
107 final MethodGen mg = createMethodGen("main", il, cp);
108 final InstructionFactory factory = new InstructionFactory(cg);
109
110 final ObjectType iStream = new ObjectType("java.io.InputStream");
111 final ObjectType pStream = new ObjectType("java.io.PrintStream");
112
113
114
115
116 il.append(factory.createNew("java.io.BufferedReader"));
117 il.append(InstructionConst.DUP);
118 il.append(factory.createNew("java.io.InputStreamReader"));
119 il.append(InstructionConst.DUP);
120 il.append(factory.createFieldAccess("java.lang.System", "in", iStream, Const.GETSTATIC));
121 il.append(factory.createInvoke("java.io.InputStreamReader", "<init>", Type.VOID, new Type[] {iStream}, Const.INVOKESPECIAL));
122 il.append(factory.createInvoke("java.io.BufferedReader", "<init>", Type.VOID, new Type[] {new ObjectType("java.io.Reader")}, Const.INVOKESPECIAL));
123 LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null);
124 final int in = lg.getIndex();
125 lg.setStart(il.append(new ASTORE(in)));
126
127 lg = mg.addLocalVariable("name", Type.STRING, null, null);
128 final int name = lg.getIndex();
129 il.append(InstructionConst.ACONST_NULL);
130 lg.setStart(il.append(new ASTORE(name)));
131
132
133
134
135
136
137
138
139
140
141
142 final InstructionHandle tryStart = il.append(new PUSH(cp, "Andy"));
143 il.append(new ASTORE(name));
144
145
146 final GOTO g = new GOTO(null);
147 final InstructionHandle tryEnd = il.append(g);
148
149 final LocalVariableGen varEx = mg.addLocalVariable("ex", Type.getType("Ljava.io.IOException;"), null, null);
150 final int varExSlot = varEx.getIndex();
151 final InstructionHandle handler = il.append(new ASTORE(varExSlot));
152 varEx.setStart(handler);
153 varEx.setEnd(il.append(InstructionConst.RETURN));
154 mg.addExceptionHandler(tryStart, tryEnd, handler, new ObjectType("java.io.IOException"));
155
156
157 final InstructionHandle ih = il.append(factory.createFieldAccess("java.lang.System", "out", pStream, Const.GETSTATIC));
158 g.setTarget(ih);
159
160
161 il.append(factory.createNew(Type.STRINGBUFFER));
162 il.append(InstructionConst.DUP);
163 il.append(new PUSH(cp, "Hello, "));
164 il.append(factory.createInvoke("java.lang.StringBuffer", "<init>", Type.VOID, new Type[] {Type.STRING}, Const.INVOKESPECIAL));
165 il.append(new ALOAD(name));
166 il.append(factory.createInvoke("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {Type.STRING}, Const.INVOKEVIRTUAL));
167 il.append(factory.createInvoke("java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, Const.INVOKEVIRTUAL));
168 il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] {Type.STRING}, Const.INVOKEVIRTUAL));
169 il.append(InstructionConst.RETURN);
170
171
172
173 mg.setMaxStack();
174 mg.setMaxLocals();
175 cg.addMethod(mg.getMethod());
176 il.dispose();
177 cg.addEmptyConstructor(Const.ACC_PUBLIC);
178 }
179
180 private void buildClassContentsWithAnnotatedMethods(final ClassGen cg, final ConstantPoolGen cp, final InstructionList il) {
181
182 final MethodGen mg = createMethodGen("main", il, cp);
183 final InstructionFactory factory = new InstructionFactory(cg);
184 mg.addAnnotationEntry(createSimpleVisibleAnnotation(mg.getConstantPool()));
185
186 final ObjectType iStream = new ObjectType("java.io.InputStream");
187 final ObjectType pStream = new ObjectType("java.io.PrintStream");
188
189
190
191
192 il.append(factory.createNew("java.io.BufferedReader"));
193 il.append(InstructionConst.DUP);
194 il.append(factory.createNew("java.io.InputStreamReader"));
195 il.append(InstructionConst.DUP);
196 il.append(factory.createFieldAccess("java.lang.System", "in", iStream, Const.GETSTATIC));
197 il.append(factory.createInvoke("java.io.InputStreamReader", "<init>", Type.VOID, new Type[] {iStream}, Const.INVOKESPECIAL));
198 il.append(factory.createInvoke("java.io.BufferedReader", "<init>", Type.VOID, new Type[] {new ObjectType("java.io.Reader")}, Const.INVOKESPECIAL));
199 LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null);
200 final int in = lg.getIndex();
201 lg.setStart(il.append(new ASTORE(in)));
202
203 lg = mg.addLocalVariable("name", Type.STRING, null, null);
204 final int name = lg.getIndex();
205 il.append(InstructionConst.ACONST_NULL);
206 lg.setStart(il.append(new ASTORE(name)));
207
208
209
210
211
212
213
214
215
216
217
218 final InstructionHandle tryStart = il.append(new PUSH(cp, "Andy"));
219 il.append(new ASTORE(name));
220
221
222 final GOTO g = new GOTO(null);
223 final InstructionHandle tryEnd = il.append(g);
224
225 final LocalVariableGen varEx = mg.addLocalVariable("ex", Type.getType("Ljava.io.IOException;"), null, null);
226 final int varExSlot = varEx.getIndex();
227 final InstructionHandle handler = il.append(new ASTORE(varExSlot));
228 varEx.setStart(handler);
229 varEx.setEnd(il.append(InstructionConst.RETURN));
230 mg.addExceptionHandler(tryStart, tryEnd, handler, new ObjectType("java.io.IOException"));
231
232
233 final InstructionHandle ih = il.append(factory.createFieldAccess("java.lang.System", "out", pStream, Const.GETSTATIC));
234 g.setTarget(ih);
235
236
237 il.append(factory.createNew(Type.STRINGBUFFER));
238 il.append(InstructionConst.DUP);
239 il.append(new PUSH(cp, "Hello, "));
240 il.append(factory.createInvoke("java.lang.StringBuffer", "<init>", Type.VOID, new Type[] {Type.STRING}, Const.INVOKESPECIAL));
241 il.append(new ALOAD(name));
242 il.append(factory.createInvoke("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {Type.STRING}, Const.INVOKEVIRTUAL));
243 il.append(factory.createInvoke("java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, Const.INVOKEVIRTUAL));
244 il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] {Type.STRING}, Const.INVOKEVIRTUAL));
245 il.append(InstructionConst.RETURN);
246
247
248
249 mg.setMaxStack();
250 mg.setMaxLocals();
251 cg.addMethod(mg.getMethod());
252 il.dispose();
253 cg.addEmptyConstructor(Const.ACC_PUBLIC);
254 }
255
256
257 private ClassGen createClassGen(final String className) {
258 return new ClassGen(className, "java.lang.Object", "<generated>", Const.ACC_PUBLIC | Const.ACC_SUPER, null);
259 }
260
261 public AnnotationEntryGen createCombinedAnnotation(final ConstantPoolGen cp) {
262
263 final AnnotationEntryGen a = createSimpleVisibleAnnotation(cp);
264 final ArrayElementValueGen array = new ArrayElementValueGen(cp);
265 array.addElement(new AnnotationElementValueGen(a, cp));
266 final ElementValuePairGen nvp = new ElementValuePairGen("value", array, cp);
267 final List<ElementValuePairGen> elements = new ArrayList<>();
268 elements.add(nvp);
269 return new AnnotationEntryGen(new ObjectType("CombinedAnnotation"), elements, true, cp);
270 }
271
272 public AnnotationEntryGen createFruitAnnotation(final ConstantPoolGen cp, final String aFruit) {
273 final SimpleElementValueGen evg = new SimpleElementValueGen(ElementValueGen.STRING, cp, aFruit);
274 final ElementValuePairGen nvGen = new ElementValuePairGen("fruit", evg, cp);
275 final ObjectType t = new ObjectType("SimpleStringAnnotation");
276 final List<ElementValuePairGen> elements = new ArrayList<>();
277 elements.add(nvGen);
278 return new AnnotationEntryGen(t, elements, true, cp);
279 }
280
281 private MethodGen createMethodGen(final String methodname, final InstructionList il, final ConstantPoolGen cp) {
282 return new MethodGen(Const.ACC_STATIC | Const.ACC_PUBLIC,
283
284 Type.VOID,
285 new Type[] {new ArrayType(Type.STRING, 1)},
286
287 new String[] {"argv"},
288 methodname, "HelloWorld",
289 il, cp);
290 }
291
292 public AnnotationEntryGen createSimpleInvisibleAnnotation(final ConstantPoolGen cp) {
293 final SimpleElementValueGen evg = new SimpleElementValueGen(ElementValueGen.PRIMITIVE_INT, cp, 4);
294 final ElementValuePairGen nvGen = new ElementValuePairGen("id", evg, cp);
295 final ObjectType t = new ObjectType("SimpleAnnotation");
296 final List<ElementValuePairGen> elements = new ArrayList<>();
297 elements.add(nvGen);
298 return new AnnotationEntryGen(t, elements, false, cp);
299 }
300
301 public AnnotationEntryGen createSimpleVisibleAnnotation(final ConstantPoolGen cp) {
302 final SimpleElementValueGen evg = new SimpleElementValueGen(ElementValueGen.PRIMITIVE_INT, cp, 4);
303 final ElementValuePairGen nvGen = new ElementValuePairGen("id", evg, cp);
304 final ObjectType t = new ObjectType("SimpleAnnotation");
305 final List<ElementValuePairGen> elements = new ArrayList<>();
306 elements.add(nvGen);
307 return new AnnotationEntryGen(t, elements, true, cp);
308 }
309
310 private void dumpClass(final ClassGen cg, final String fname) {
311 try {
312 final File f = createTestdataFile(fname);
313 cg.getJavaClass().dump(f);
314 } catch (final java.io.IOException e) {
315 System.err.println(e);
316 }
317 }
318
319 private void dumpClass(final ClassGen cg, final String dir, final String fname) {
320 dumpClass(cg, dir + File.separator + fname);
321 }
322
323 private JavaClass getClassFrom(final String where, final String clazzname) throws ClassNotFoundException {
324
325 final SyntheticRepository repos = createRepos(where);
326 return repos.loadClass(clazzname);
327 }
328
329
330
331
332
333
334
335
336
337
338
339 @Test
340 public void testGenerateClassLevelAnnotations() throws ClassNotFoundException {
341
342 final ClassGen cg = createClassGen("HelloWorld");
343 cg.setMajor(49);
344 cg.setMinor(0);
345 final ConstantPoolGen cp = cg.getConstantPool();
346 final InstructionList il = new InstructionList();
347 cg.addAnnotationEntry(createSimpleVisibleAnnotation(cp));
348 cg.addAnnotationEntry(createSimpleInvisibleAnnotation(cp));
349 buildClassContents(cg, cp, il);
350
351 dumpClass(cg, "HelloWorld.class");
352 final JavaClass jc = getClassFrom(".", "HelloWorld");
353 final AnnotationEntry[] as = jc.getAnnotationEntries();
354 assertEquals(2, as.length, "Wrong number of AnnotationEntries");
355
356 assertEquals("LSimpleAnnotation;", as[0].getAnnotationType(), "Wrong name of annotation 1");
357 assertEquals("LSimpleAnnotation;", as[1].getAnnotationType(), "Wrong name of annotation 2");
358 final ElementValuePair[] vals = as[0].getElementValuePairs();
359 final ElementValuePair nvp = vals[0];
360 assertEquals("id", nvp.getNameString(), "Wrong name of element in SimpleAnnotation");
361 final ElementValue ev = nvp.getValue();
362 assertEquals(ElementValue.PRIMITIVE_INT, ev.getElementValueType(), "Wrong type of element value");
363 assertEquals("4", ev.stringifyValue(), "Wrong value of element");
364 assertTrue(createTestdataFile("HelloWorld.class").delete());
365 }
366
367
368
369
370 @Test
371 public void testGenerateMethodLevelAnnotations1() throws ClassNotFoundException {
372
373 final ClassGen cg = createClassGen("HelloWorld");
374 final ConstantPoolGen cp = cg.getConstantPool();
375 final InstructionList il = new InstructionList();
376 buildClassContentsWithAnnotatedMethods(cg, cp, il);
377
378 int i = cg.getMethods()[0].getAnnotationEntries().length;
379 assertEquals(1, i, "Wrong number of annotations of main method prior to dumping");
380 dumpClass(cg, "temp1" + File.separator + "HelloWorld.class");
381 final JavaClass jc2 = getClassFrom("temp1", "HelloWorld");
382
383 i = jc2.getMethods()[0].getAnnotationEntries().length;
384 assertEquals(1, i, "Wrong number of annotation on JavaClass");
385 final ClassGen cg2 = new ClassGen(jc2);
386
387 final Method[] m = cg2.getMethods();
388 i = m[0].getAnnotationEntries().length;
389 assertEquals(1, i, "Wrong number of annotations on the main 'Method'");
390 final FieldGenOrMethodGen mg = new MethodGen(m[0], cg2.getClassName(), cg2.getConstantPool());
391
392 i = mg.getAnnotationEntries().length;
393 assertEquals(1, i, "Wrong number of annotations on the main 'MethodGen'");
394
395 assertTrue(delete("temp1", "HelloWorld.class"));
396 }
397
398
399
400
401
402
403 @Test
404 public void testGenerateMethodLevelAnnotations2() throws ClassNotFoundException {
405
406 final ClassGen cg = createClassGen("HelloWorld");
407 final ConstantPoolGen cp = cg.getConstantPool();
408 final InstructionList il = new InstructionList();
409 buildClassContentsWithAnnotatedMethods(cg, cp, il);
410 dumpClass(cg, "temp2", "HelloWorld.class");
411 final JavaClass jc2 = getClassFrom("temp2", "HelloWorld");
412 final ClassGen cg2 = new ClassGen(jc2);
413
414 final Method mainMethod1 = jc2.getMethods()[0];
415 assertEquals(1, mainMethod1.getAnnotationEntries().length, "Wrong number of annotations of the 'Method'");
416 final MethodGen mainMethod2 = new MethodGen(mainMethod1, cg2.getClassName(), cg2.getConstantPool());
417 assertEquals(1, mainMethod2.getAnnotationEntries().length, "Wrong number of annotations of the 'MethodGen'");
418 final AnnotationEntryGen fruit = createFruitAnnotation(cg2.getConstantPool(), "Pear");
419 mainMethod2.addAnnotationEntry(fruit);
420 cg2.removeMethod(mainMethod1);
421 cg2.addMethod(mainMethod2.getMethod());
422 dumpClass(cg2, "temp3", "HelloWorld.class");
423 final JavaClass jc3 = getClassFrom("temp3", "HelloWorld");
424 final ClassGen cg3 = new ClassGen(jc3);
425 final Method mainMethod3 = cg3.getMethods()[1];
426 final int i = mainMethod3.getAnnotationEntries().length;
427 assertEquals(2, i, "Wrong number of annotations on the 'Method'");
428 mainMethod2.removeAnnotationEntry(fruit);
429 assertEquals(1, mainMethod2.getAnnotationEntries().length, "Wrong number of annotations on the 'MethodGen'");
430 mainMethod2.removeAnnotationEntries();
431 assertEquals(0, mainMethod2.getAnnotationEntries().length, 0, "Wrong number of annotations on the 'MethodGen'");
432 assertTrue(delete("temp2", "HelloWorld.class"));
433 assertTrue(delete("temp3", "HelloWorld.class"));
434 }
435
436
437
438
439 @Test
440 public void testModifyingClasses1() throws ClassNotFoundException {
441 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.SimpleAnnotatedClass");
442 final ClassGen cgen = new ClassGen(jc);
443 final ConstantPoolGen cp = cgen.getConstantPool();
444 cgen.addAnnotationEntry(createFruitAnnotation(cp, "Pineapple"));
445 assertEquals(2, cgen.getAnnotationEntries().length, "Wrong number of annotations");
446 dumpClass(cgen, "SimpleAnnotatedClass.class");
447 assertTrue(delete("SimpleAnnotatedClass.class"));
448 }
449
450
451
452
453 @Test
454 public void testModifyingClasses2() throws ClassNotFoundException {
455 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.SimpleAnnotatedClass");
456 final ClassGen cgen = new ClassGen(jc);
457 final ConstantPoolGen cp = cgen.getConstantPool();
458 cgen.addAnnotationEntry(createCombinedAnnotation(cp));
459 assertEquals(2, cgen.getAnnotationEntries().length, "Wrong number of annotations");
460 dumpClass(cgen, "SimpleAnnotatedClass.class");
461 final JavaClass jc2 = getClassFrom(".", "SimpleAnnotatedClass");
462 jc2.getAnnotationEntries();
463 assertTrue(delete("SimpleAnnotatedClass.class"));
464
465 }
466
467
468
469
470
471 @Test
472 public void testTransformClassToClassGen_ArrayAndAnnotationTypes() throws ClassNotFoundException {
473 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.AnnotatedWithCombinedAnnotation");
474 final ClassGen cgen = new ClassGen(jc);
475
476 final AnnotationEntryGen[] annotations = cgen.getAnnotationEntries();
477 assertEquals(1, annotations.length, "Wrong number of annotations");
478 final AnnotationEntryGen a = annotations[0];
479 assertEquals(1, a.getValues().size(), "Wrong number of values for the annotation");
480 final ElementValuePairGen nvp = a.getValues().get(0);
481 final ElementValueGen value = nvp.getValue();
482 assertTrue(value instanceof ArrayElementValueGen, "Value should be ArrayElementValueGen but is " + value);
483 final ArrayElementValueGen arrayValue = (ArrayElementValueGen) value;
484 assertEquals(1, arrayValue.getElementValuesSize(), "Wrong size of the array");
485 final ElementValueGen innerValue = arrayValue.getElementValues().get(0);
486 assertTrue(innerValue instanceof AnnotationElementValueGen, "Value in the array should be AnnotationElementValueGen but is " + innerValue);
487 final AnnotationElementValueGen innerAnnotationValue = (AnnotationElementValueGen) innerValue;
488 assertEquals("L" + PACKAGE_BASE_SIG + "/data/SimpleAnnotation;", innerAnnotationValue.getAnnotation().getTypeSignature(), "Wrong type signature");
489
490
491 final Method[] methods = cgen.getMethods();
492 assertEquals(3, methods.length);
493 for (final Method method : methods) {
494 final String methodName = method.getName();
495 if (methodName.equals("<init>")) {
496 assertMethodAnnotations(method, 0, 1);
497 assertParameterAnnotations(method, 0, 1);
498 } else if (methodName.equals("methodWithArrayOfZeroAnnotations")) {
499 assertMethodAnnotations(method, 1, 0);
500 } else if (methodName.equals("methodWithArrayOfTwoAnnotations")) {
501 assertMethodAnnotations(method, 1, 2);
502 } else {
503 fail(() -> "unexpected method " + method.getName());
504 }
505 }
506 }
507
508
509
510
511
512 @Test
513 public void testTransformClassToClassGen_EnumType() throws ClassNotFoundException {
514 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.AnnotatedWithEnumClass");
515 final ClassGen cgen = new ClassGen(jc);
516
517 final AnnotationEntryGen[] annotations = cgen.getAnnotationEntries();
518 assertEquals(1, annotations.length, "Wrong number of annotations");
519 }
520
521
522
523
524
525 @Test
526 public void testTransformClassToClassGen_SimpleTypes() throws ClassNotFoundException {
527 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.SimpleAnnotatedClass");
528 final ClassGen cgen = new ClassGen(jc);
529
530 final AnnotationEntryGen[] annotations = cgen.getAnnotationEntries();
531 assertEquals(1, annotations.length, "Wrong number of annotations");
532 }
533
534
535
536
537 @Test
538 public void testTransformComplexClassToClassGen() throws ClassNotFoundException {
539 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.ComplexAnnotatedClass");
540 final ClassGen cgen = new ClassGen(jc);
541
542 final AnnotationEntryGen[] annotations = cgen.getAnnotationEntries();
543 assertEquals(1, annotations.length, "Wrong number of annotations");
544 final List<?> l = annotations[0].getValues();
545 boolean found = false;
546 for (final Object name : l) {
547 final ElementValuePairGen element = (ElementValuePairGen) name;
548 if (element.getNameString().equals("dval") && element.getValue().stringifyValue().equals("33.4")) {
549 found = true;
550 }
551 }
552 assertTrue(found, "Did not find double annotation value with value 33.4");
553 }
554 }