1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.bcel.classfile;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.fail;
24
25 import java.io.IOException;
26
27 import org.apache.bcel.AbstractTestCase;
28 import org.apache.bcel.Const;
29 import org.apache.bcel.generic.ConstantPoolGen;
30 import org.apache.bcel.generic.InstructionHandle;
31 import org.apache.bcel.generic.MethodGen;
32 import org.apache.bcel.util.ClassPath;
33 import org.apache.bcel.util.ClassPathRepository;
34 import org.junit.jupiter.api.Test;
35
36 final class ClassWithDoubleConstantPoolItem {
37 double d = 42;
38 }
39
40 final class ClassWithLongConstantPoolItem {
41 long l = 42;
42 }
43
44 public class ConstantPoolTestCase extends AbstractTestCase {
45
46 private static InstructionHandle[] getInstructionHandles(final JavaClass clazz, final ConstantPoolGen cp, final Method method) {
47 final MethodGen methodGen = new MethodGen(method, clazz.getClassName(), cp);
48 return methodGen.getInstructionList().getInstructionHandles();
49 }
50
51 @Test
52 public void testClassWithDoubleConstantPoolItem() throws ClassNotFoundException, IOException {
53 try (final ClassPath cp = new ClassPath("target/test-classes/org/apache/bcel/classfile")) {
54 final ClassWithDoubleConstantPoolItem classWithDoubleConstantPoolItem = new ClassWithDoubleConstantPoolItem();
55 final JavaClass c = new ClassPathRepository(cp).loadClass(classWithDoubleConstantPoolItem.getClass());
56 final Field[] fields = c.getFields();
57 assertNotNull(fields);
58 assertEquals(1, fields.length);
59 assertEquals(ClassWithDoubleConstantPoolItem.class.getDeclaredFields()[0].getName(), fields[0].getName());
60 final ConstantPool pool = c.getConstantPool();
61 for (int i = 1; i < pool.getLength(); i++) {
62 try {
63 final Constant constant = pool.getConstant(i);
64 if (constant instanceof ConstantDouble) {
65 assertEquals(classWithDoubleConstantPoolItem.d, ((ConstantDouble) constant).getBytes());
66
67 i++;
68 }
69 } catch (final Throwable t) {
70 t.printStackTrace();
71 fail();
72 }
73 }
74 }
75 }
76
77 @Test
78 public void testClassWithLongConstantPoolItem() throws ClassNotFoundException, IOException {
79 try (final ClassPath cp = new ClassPath("target/test-classes/org/apache/bcel/classfile")) {
80 final ClassWithLongConstantPoolItem classWithLongConstantPoolItem = new ClassWithLongConstantPoolItem();
81 final JavaClass c = new ClassPathRepository(cp).loadClass(classWithLongConstantPoolItem.getClass());
82 final Field[] fields = c.getFields();
83 assertNotNull(fields);
84 assertEquals(1, fields.length);
85 assertEquals(ClassWithLongConstantPoolItem.class.getDeclaredFields()[0].getName(), fields[0].getName());
86 final ConstantPool pool = c.getConstantPool();
87 for (int i = 1; i < pool.getLength(); i++) {
88 try {
89 final Constant constant = pool.getConstant(i);
90 if (constant instanceof ConstantLong) {
91 assertEquals(classWithLongConstantPoolItem.l, ((ConstantLong) constant).getBytes());
92
93 i++;
94 }
95 } catch (final Throwable t) {
96 t.printStackTrace();
97 fail();
98 }
99 }
100 }
101 }
102
103 @Test
104 public void testConstantToString() throws ClassNotFoundException {
105 final JavaClass clazz = getTestJavaClass(PACKAGE_BASE_NAME + ".data.SimpleClassWithDefaultConstructor");
106 final ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
107 final Method[] methods = clazz.getMethods();
108 for (final Method method : methods) {
109 if (method.getName().equals("<init>")) {
110 for (final InstructionHandle instructionHandle : getInstructionHandles(clazz, cp, method)) {
111 final String instruction = instructionHandle.getInstruction().toString(cp.getConstantPool());
112 assertNotNull(instruction);
113 switch (instructionHandle.getPosition()) {
114 case 0:
115 assertEquals("aload_0", instruction);
116 break;
117 case 1:
118 assertEquals("invokespecial java/lang/Object/<init>()V", instruction);
119 break;
120 case 4:
121 assertEquals("return", instruction);
122 break;
123 default:
124 break;
125 }
126 }
127 }
128 }
129 }
130
131 @Test
132 public void testTooManyConstants() throws ClassNotFoundException {
133 final JavaClass clazz = getTestJavaClass(PACKAGE_BASE_NAME + ".data.SimpleClassWithDefaultConstructor");
134 final ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
135 int i = cp.getSize();
136 while (i < Const.MAX_CP_ENTRIES - 1) {
137 cp.addLong(i);
138 i = cp.getSize();
139 }
140 assertThrows(IllegalStateException.class, () -> cp.addLong(0));
141 }
142 }