45
46 interface Test<T> {
47 String test(T t);
48 }
49
50 class HiddenClassSig<T> implements Test<T> {
51 private String realTest() { return "HiddenClassSig: "; }
52
53 public String test(T t) {
54 String str = realTest();
55 return str + t.toString();
56 }
57 }
58
59 public class HiddenClassSigTest {
60 private static void log(String str) { System.out.println(str); }
61
62 private static final String HCName = "P/Q/HiddenClassSig.class";
63 private static final String DIR = Utils.TEST_CLASSES;
64 private static final String LOG_PREFIX = "HiddenClassSigTest: ";
65 private static final String ARR_PREFIX = "[[L";
66 private static final String ARR_POSTFIX = "[][]";
67 private static final String CLASS_PREFIX = "class ";
68
69 static native void checkHiddenClass(Class klass, String sig);
70 static native void checkHiddenClassArray(Class array, String sig);
71 static native boolean checkFailed();
72
73 static {
74 try {
75 System.loadLibrary("HiddenClassSigTest");
76 } catch (UnsatisfiedLinkError ule) {
77 System.err.println("Could not load HiddenClassSigTest library");
78 System.err.println("java.library.path: "
79 + System.getProperty("java.library.path"));
80 throw ule;
81 }
82 }
83
84 static byte[] readClassFile(String classFileName) throws Exception {
85 File classFile = new File(classFileName);
86 try (FileInputStream in = new FileInputStream(classFile);
87 ByteArrayOutputStream out = new ByteArrayOutputStream())
94 }
95 }
96
97 static Class<?> defineHiddenClass(String classFileName) throws Exception {
98 Lookup lookup = MethodHandles.lookup();
99 byte[] bytes = readClassFile(DIR + File.separator + classFileName);
100 Class<?> hc = lookup.defineHiddenClass(bytes, false).lookupClass();
101 return hc;
102 }
103
104 static void logClassInfo(Class<?> klass) {
105 log("\n### Testing class: " + klass);
106 log(LOG_PREFIX + "isHidden: " + klass.isHidden());
107 log(LOG_PREFIX + "getName: " + klass.getName());
108 log(LOG_PREFIX + "typeName: " + klass.getTypeName());
109 log(LOG_PREFIX + "toString: " + klass.toString());
110 log(LOG_PREFIX + "toGenStr: " + klass.toGenericString());
111 log(LOG_PREFIX + "elem type: " + klass.componentType());
112 }
113
114 static boolean checkName(String name, String expName, String msgPart) {
115 boolean failed = false;
116 if (!name.equals(expName)) {
117 log("Test FAIL: result of " + msgPart + " does not match expectation");
118 failed = true;
119 }
120 return failed;
121 }
122
123 static boolean checkNameHas(String name, String expNamePart, String msgPart) {
124 boolean failed = false;
125 if (name.indexOf(expNamePart) < 0) {
126 log("Test FAIL: result of " + msgPart + " does not match expectation");
127 failed = true;
128 }
129 return failed;
130 }
131
132 static boolean checkArray(Class<?> arrClass) {
133 boolean failed = false;
134 Class<?> elemClass = arrClass.componentType();
135
136 String arrName = arrClass.getName();
137 String arrType = arrClass.getTypeName();
138 String arrStr = arrClass.toString().substring(CLASS_PREFIX.length());
139 String arrGen = arrClass.toGenericString();
140
141 String elemName = elemClass.getName();
142 String elemType = elemClass.getTypeName();
143 String elemStr = elemClass.toString().substring(CLASS_PREFIX.length());
144 String elemGen = elemClass.toGenericString();
145
146 if (elemClass.isHidden()) {
147 elemGen = elemGen.substring(CLASS_PREFIX.length());
148 }
149 failed |= checkNameHas(arrName, elemName, "klass.getName()");
150 failed |= checkNameHas(arrStr, elemStr, "klass.toString()");
151 failed |= checkNameHas(arrType, elemType, "klass.getTypeName()");
152 failed |= checkNameHas(arrGen, elemGen, "klass.getGenericString()");
153 return failed;
154 }
155
156 static boolean testClass(Class<?> klass, int arrLevel, String baseName) {
157 boolean failed = false;
158 boolean isHidden = (arrLevel == 0);
159 String prefix = (arrLevel == 0) ? "" : ARR_PREFIX.substring(2 - arrLevel);
160 String postfix = (arrLevel == 0) ? "" : ";";
161
162 logClassInfo(klass);
163
164 String expName = ("" + klass).substring(CLASS_PREFIX.length());
165 String expType = baseName;
166 String expStr = CLASS_PREFIX + prefix + baseName + postfix;
167 String expGen = baseName + "<T>" + ARR_POSTFIX.substring(0, 2*arrLevel);
168
169 if (arrLevel > 0) {
170 expType = expType + ARR_POSTFIX.substring(0, 2*arrLevel);
171 } else {
172 expGen = CLASS_PREFIX + expGen;
173 }
174 failed |= checkName(klass.getName(), expName, "klass.getName()");
175 failed |= checkName(klass.getTypeName(), expType, "klass.getTypeName()");
176 failed |= checkName(klass.toString(), expStr, "klass.toString()");
177 failed |= checkName(klass.toGenericString(), expGen, "klass.toGenericString()");
178
179 if (klass.isHidden() != isHidden) {
180 log("Test FAIL: result of klass.isHidden() does not match expectation");
181 failed = true;
182 }
183 String sig = hcSignature(klass);
184 if (arrLevel == 0) {
185 checkHiddenClass(klass, sig);
186 } else {
187 failed |= checkArray(klass);
188 checkHiddenClassArray(klass, sig);
189 }
190 return failed;
191 }
192
193 static String hcSignature(Class<?> klass) {
194 boolean isArray = klass.isArray();
195 String sig = klass.getName();
196 String prefix = isArray ? "" : "L";
197 String postfix = isArray ? "" : ";";
198 int idx = sig.indexOf("/");
199
200 sig = prefix + sig.substring(0, idx).replace('.', '/')
201 + "."
202 + sig.substring(idx + 1, sig.length())
203 + postfix;
204 return sig;
205 }
206
207 public static void main(String args[]) throws Exception {
208 log(LOG_PREFIX + "started");
209 Class<?> hc = defineHiddenClass(HCName);
210 String baseName = ("" + hc).substring("class ".length());
211
212 Test<String> t = (Test<String>)hc.newInstance();
213 String str = t.test("Test generic hidden class");
214 log(LOG_PREFIX + "hc.test() returned string: " + str);
215
216 boolean failed = testClass(hc, 0, baseName);
217
218 Class<?> hcArr = hc.arrayType();
219 failed |= testClass(hcArr, 1, baseName);
220
221 Class<?> hcArrArr = hcArr.arrayType();
222 failed |= testClass(hcArrArr, 2, baseName);
223
224 if (failed) {
225 throw new RuntimeException("FAIL: failed status from java part");
226 }
227 if (checkFailed()) {
228 throw new RuntimeException("FAIL: failed status from native agent");
229 }
230 log(LOG_PREFIX + "finished");
231 }
232 }
|
45
46 interface Test<T> {
47 String test(T t);
48 }
49
50 class HiddenClassSig<T> implements Test<T> {
51 private String realTest() { return "HiddenClassSig: "; }
52
53 public String test(T t) {
54 String str = realTest();
55 return str + t.toString();
56 }
57 }
58
59 public class HiddenClassSigTest {
60 private static void log(String str) { System.out.println(str); }
61
62 private static final String HCName = "P/Q/HiddenClassSig.class";
63 private static final String DIR = Utils.TEST_CLASSES;
64 private static final String LOG_PREFIX = "HiddenClassSigTest: ";
65
66 static native void checkHiddenClass(Class klass, String sig);
67 static native void checkHiddenClassArray(Class array, String sig);
68 static native boolean checkFailed();
69
70 static {
71 try {
72 System.loadLibrary("HiddenClassSigTest");
73 } catch (UnsatisfiedLinkError ule) {
74 System.err.println("Could not load HiddenClassSigTest library");
75 System.err.println("java.library.path: "
76 + System.getProperty("java.library.path"));
77 throw ule;
78 }
79 }
80
81 static byte[] readClassFile(String classFileName) throws Exception {
82 File classFile = new File(classFileName);
83 try (FileInputStream in = new FileInputStream(classFile);
84 ByteArrayOutputStream out = new ByteArrayOutputStream())
91 }
92 }
93
94 static Class<?> defineHiddenClass(String classFileName) throws Exception {
95 Lookup lookup = MethodHandles.lookup();
96 byte[] bytes = readClassFile(DIR + File.separator + classFileName);
97 Class<?> hc = lookup.defineHiddenClass(bytes, false).lookupClass();
98 return hc;
99 }
100
101 static void logClassInfo(Class<?> klass) {
102 log("\n### Testing class: " + klass);
103 log(LOG_PREFIX + "isHidden: " + klass.isHidden());
104 log(LOG_PREFIX + "getName: " + klass.getName());
105 log(LOG_PREFIX + "typeName: " + klass.getTypeName());
106 log(LOG_PREFIX + "toString: " + klass.toString());
107 log(LOG_PREFIX + "toGenStr: " + klass.toGenericString());
108 log(LOG_PREFIX + "elem type: " + klass.componentType());
109 }
110
111 private static final String HC_NAME = "P.Q.HiddenClassSig";
112 private static final String HC_SUFFIX_REGEX = "0x[0-9a-f]+";
113 static boolean checkName(Class<?> klass, String name, String toString) {
114 boolean failed = false;
115 String regex = "";
116 Class<?> c = klass;
117 while (c.isArray()) {
118 regex = "\\[" + regex;
119 c = c.componentType();
120 }
121 if (klass.isArray()) {
122 regex += "L" + HC_NAME + "/" + HC_SUFFIX_REGEX + ";";
123 } else {
124 regex = HC_NAME + "/" + HC_SUFFIX_REGEX;
125 }
126 if (!name.matches(regex)) {
127 log("Test FAIL: result of Class::getName" + " \"" + name + "\" does not match " + regex);
128 failed = true;
129 }
130 if (!toString.matches("class " + regex)) {
131 log("Test FAIL: result of Class::toString" + " \"" + name + "\" does not match " + regex);
132 failed = true;
133 }
134 return failed;
135 }
136
137 static boolean checkTypeName(Class<?> klass, String name) {
138 boolean failed = false;
139 String regex = HC_NAME + "/" + HC_SUFFIX_REGEX;
140 Class<?> c = klass;
141 while (c.isArray()) {
142 c = c.componentType();
143 regex = regex + "\\[\\]";
144 }
145 if (!name.matches(regex)) {
146 log("Test FAIL: result of Class::getTypeName" + " \"" + name + "\" does not match " + regex);
147 failed = true;
148 }
149 return failed;
150 }
151
152 static boolean checkGenericString(Class<?> klass, String name) {
153 boolean failed = false;
154 Class<?> c = klass;
155 String regex = HC_NAME + "/" + HC_SUFFIX_REGEX + "<T>";
156 if (!klass.isArray()) {
157 regex = "class " + regex;
158 }
159 while (c.isArray()) {
160 c = c.componentType();
161 regex = regex + "\\[\\]";
162 }
163 if (!name.matches(regex)) {
164 log("Test FAIL: result of Class::toGenericString" + " \"" + name + "\" does not match " + regex);
165 failed = true;
166 }
167 return failed;
168 }
169
170 static boolean checkDescriptorString(Class<?> klass, String name) {
171 boolean failed = false;
172 String regex = "L" + HC_NAME.replace('.', '/') + "." + HC_SUFFIX_REGEX + ";";
173 Class<?> c = klass;
174 while (c.isArray()) {
175 regex = "\\[" + regex;
176 c = c.componentType();
177 }
178 if (!name.matches(regex)) {
179 log("Test FAIL: result of Class::descriptorString" + " \"" + name + "\" does not match " + regex);
180 failed = true;
181 }
182 return failed;
183 }
184
185 static boolean testClass(Class<?> klass) {
186 boolean failed = false;
187 logClassInfo(klass);
188
189 failed |= checkName(klass, klass.getName(), klass.toString());
190 failed |= checkTypeName(klass, klass.getTypeName());
191 failed |= checkGenericString(klass, klass.toGenericString());
192 failed |= checkDescriptorString(klass, klass.descriptorString());
193
194 if (klass.isArray() && klass.isHidden()) {
195 log("Test FAIL: an array class is never hidden");
196 failed = true;
197 }
198 if (klass.isArray()) {
199 checkHiddenClassArray(klass, klass.descriptorString());
200 } else {
201 checkHiddenClass(klass, klass.descriptorString());
202 }
203 return failed;
204 }
205
206 public static void main(String args[]) throws Exception {
207 log(LOG_PREFIX + "started");
208 Class<?> hc = defineHiddenClass(HCName);
209 String baseName = ("" + hc).substring("class ".length());
210
211 Test<String> t = (Test<String>)hc.newInstance();
212 String str = t.test("Test generic hidden class");
213 log(LOG_PREFIX + "hc.test() returned string: " + str);
214
215 boolean failed = testClass(hc);
216
217 Class<?> hcArr = hc.arrayType();
218 failed |= testClass(hcArr);
219
220 Class<?> hcArrArr = hcArr.arrayType();
221 failed |= testClass(hcArrArr);
222
223 if (failed) {
224 throw new RuntimeException("FAIL: failed status from java part");
225 }
226 if (checkFailed()) {
227 throw new RuntimeException("FAIL: failed status from native agent");
228 }
229 log(LOG_PREFIX + "finished");
230 }
231 }
|