13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 8046171
27 * @summary Test the new nestmate reflection API
28 * @compile TestReflectionAPI.java
29 * PackagedNestHost.java
30 * PackagedNestHost2.java
31 * SampleNest.java
32 * Hosts.java
33 *
34 * @compile MemberNoHost.jcod
35 * MemberMissingHost.jcod
36 * MemberNotInstanceHost.jcod
37 * MemberNotOurHost.jcod
38 * MemberMalformedHost.jcod
39 * MalformedHost.jcod
40 * PackagedNestHost.jcod
41 * PackagedNestHost2Member.jcod
42 * PackagedNestHostMember.jcod
43 * HostOfMemberNoHost.jcod
44 * HostOfMemberMissingHost.jcod
45 * HostOfMemberNotInstanceHost.jcod
46 * HostOfMemberNotOurHost.jcod
47 * HostOfMemberMalformedHost.jcod
48 *
49 * @run main/othervm TestReflectionAPI
50 */
51
52 // We need a nest member class that is invalid for each of the possible reasons,
53 // plus we need some external classes to test other failure modes.
54 // For each nested class below there is a corresponding .jcod file which breaks one
55 // of the rules regarding nest membership. For the package related tests we have
56 // additional PackageNestHost*.java sources.
57 // For testing getNestMembers we need an external host class that has a nested class
58 // which we can form a jcod file from such that we get all the expected failure modes.
59 // Note that all the .java files must be compiled in the same step, while all
60 // .jcod files must be compiled in a later step.
61
62 import java.util.Arrays;
63 import java.util.Comparator;
64
65 public class TestReflectionAPI {
66
67 // Valid nest member
68 static class Member {}
69
70 // Missing NestHost attribute
71 static class MemberNoHost {}
72
73 // Missing NestHost class
74 static class MemberMissingHost {}
75
76 // Invalid NestHost class (not instance class)
77 static class MemberNotInstanceHost {
78 Object[] oa; // create CP entry to use in jcod change
79 }
80
81 // Valid but different NestHost class
82 static class MemberNotOurHost {}
83
137 continue;
138 checkNestmates(host, c, false);
139 }
140
141 // 'special' classes
142 checkNestmates(int.class, int.class, true); // primitive
143 checkNestmates(int.class, long.class, false); // primitive
144 checkNestmates(Object[].class, Object[].class, true); // array
145 checkNestmates(Object[].class, int[].class, false); // array
146 checkNestmates(Thread.State.class, Thread.class, true); // enum
147 checkNestmates(java.lang.annotation.Documented.class, // annotation
148 java.lang.annotation.Documented.class, true);
149 }
150
151 static void test_getNestMembers() {
152 // Sampling of "good" checks
153 Class<?>[] good = { Object.class, Object[].class, int.class};
154 checkSingletonNests(good);
155
156 // More thorough correctness check
157 checkNest(SampleNest.class, SampleNest.nestedTypes());
158
159 // Hosts with "bad" members
160 Class<?>[] bad = {
161 HostOfMemberNoHost.class,
162 HostOfMemberMissingHost.class,
163 HostOfMemberNotOurHost.class,
164 HostOfMemberNotInstanceHost.class,
165 HostOfMemberMalformedHost.class,
166 };
167 Class<?>[] exceptions = {
168 IncompatibleClassChangeError.class,
169 NoClassDefFoundError.class,
170 IncompatibleClassChangeError.class,
171 IncompatibleClassChangeError.class,
172 ClassFormatError.class,
173 };
174 String[] messages = {
175 "Nest member HostOfMemberNoHost$MemberNoHost in HostOfMemberNoHost " +
176 "declares a different nest host of HostOfMemberNoHost$MemberNoHost",
177 "Unable to load nest-host class (NestHost) of " +
178 "HostOfMemberMissingHost$MemberMissingHost",
179 "Type HostOfMemberNotOurHost$MemberNotOurHost is not a nest member " +
180 "of java.lang.Object: current type is not listed as a nest member",
181 "Type HostOfMemberNotInstanceHost$MemberNotInstanceHost is not a nest " +
182 "member of [Ljava.lang.Object;: nest-host is not an instance class!",
183 "Incompatible magic value 3735928559 in class file MalformedHost",
184 };
185 for (int i = 0; i < bad.length; i++) {
186 try {
187 bad[i].getNestMembers();
188 throw new Error("getNestMembers() succeeded for class " +
189 bad[i].getName());
190 } catch (LinkageError e) {
191 checkException(e, messages[i], exceptions[i]);
192 }
193 }
194 }
195
196 static void checkException(Throwable actual, String msg, Class<?> expected) {
197 if (!actual.getClass().equals(expected))
198 throw new Error("Unexpected exception: got " + actual.getClass().getName()
199 + " but expected " + expected.getName());
200 if (!actual.getMessage().contains(msg))
201 throw new Error("Wrong " + actual.getClass().getSimpleName() +": \"" +
202 actual.getMessage() + "\" does not contain \"" +
209 Class<?> host = target.getNestHost();
210 if (host != expected)
211 throw new Error("Class " + target.getName() +
212 " has nest host " + host.getName() +
213 " but expected " + expected.getName());
214 }
215
216 static void checkNestmates(Class<?> a, Class<?> b, boolean mates) {
217 System.out.println("Checking if " + a.getName() +
218 " isNestmateOf " + b.getName());
219
220 if (a.isNestmateOf(b) != mates)
221 throw new Error("Class " + a.getName() + " is " +
222 (mates ? "not " : "") +
223 "a nestmate of " + b.getName() + " but should " +
224 (mates ? "" : "not ") + "be");
225 }
226
227 static Comparator<Class<?>> cmp = Comparator.comparing(Class::getName);
228
229 static void checkNest(Class<?> host, Class<?>[] unsortedTypes) {
230 Class<?>[] members = host.getNestMembers();
231 Arrays.sort(members, cmp);
232 Class<?>[] nestedTypes = unsortedTypes.clone();
233 Arrays.sort(nestedTypes, cmp);
234 printMembers(host, members);
235 printDeclared(host, nestedTypes);
236 if (!Arrays.equals(members, nestedTypes)) {
237 throw new Error("Class " + host.getName() + " has different members " +
238 "compared to declared classes");
239 }
240 // verify all the relationships that must hold for nest members
241 for (Class<?> a : members) {
242 checkHost(a, host);
243 checkNestmates(a, host, true);
244 Class<?>[] aMembers = a.getNestMembers();
245 if (aMembers[0] != host) {
246 throw new Error("Class " + a.getName() + " getNestMembers()[0] = " +
247 aMembers[0].getName() + " not " + host.getName());
248
249 }
250 Arrays.sort(aMembers, cmp);
251 if (!Arrays.equals(members, aMembers)) {
252 throw new Error("Class " + a.getName() + " has different members " +
253 "compared to host " + host.getName());
254 }
255 for (Class<?> b : members) {
256 checkNestmates(a, b, true);
257 }
258 }
|
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 8046171
27 * @summary Test the new nestmate reflection API
28 * @compile TestReflectionAPI.java
29 * PackagedNestHost.java
30 * PackagedNestHost2.java
31 * SampleNest.java
32 * Hosts.java
33 * InvalidNestHost.java
34 *
35 * @compile MemberNoHost.jcod
36 * MemberMissingHost.jcod
37 * MemberNotInstanceHost.jcod
38 * MemberNotOurHost.jcod
39 * MemberMalformedHost.jcod
40 * MalformedHost.jcod
41 * PackagedNestHost.jcod
42 * PackagedNestHost2Member.jcod
43 * PackagedNestHostMember.jcod
44 * HostOfMemberNoHost.jcod
45 * HostOfMemberMissingHost.jcod
46 * HostOfMemberNotInstanceHost.jcod
47 * HostOfMemberNotOurHost.jcod
48 * HostOfMemberMalformedHost.jcod
49 * HostWithSelfMember.jcod
50 * HostWithDuplicateMembers.jcod
51 *
52 * @run main/othervm TestReflectionAPI
53 */
54
55 // We need a nest member class that is invalid for each of the possible reasons,
56 // plus we need some external classes to test other failure modes.
57 // For each nested class below there is a corresponding .jcod file which breaks one
58 // of the rules regarding nest membership. For the package related tests we have
59 // additional PackageNestHost*.java sources.
60 // For testing getNestMembers we need an external host class that has a nested class
61 // which we can form a jcod file from such that we get all the expected failure modes.
62 // Note that all the .java files must be compiled in the same step, while all
63 // .jcod files must be compiled in a later step.
64
65 import java.util.Arrays;
66 import java.util.Comparator;
67 import java.util.HashSet;
68
69 public class TestReflectionAPI {
70
71 // Valid nest member
72 static class Member {}
73
74 // Missing NestHost attribute
75 static class MemberNoHost {}
76
77 // Missing NestHost class
78 static class MemberMissingHost {}
79
80 // Invalid NestHost class (not instance class)
81 static class MemberNotInstanceHost {
82 Object[] oa; // create CP entry to use in jcod change
83 }
84
85 // Valid but different NestHost class
86 static class MemberNotOurHost {}
87
141 continue;
142 checkNestmates(host, c, false);
143 }
144
145 // 'special' classes
146 checkNestmates(int.class, int.class, true); // primitive
147 checkNestmates(int.class, long.class, false); // primitive
148 checkNestmates(Object[].class, Object[].class, true); // array
149 checkNestmates(Object[].class, int[].class, false); // array
150 checkNestmates(Thread.State.class, Thread.class, true); // enum
151 checkNestmates(java.lang.annotation.Documented.class, // annotation
152 java.lang.annotation.Documented.class, true);
153 }
154
155 static void test_getNestMembers() {
156 // Sampling of "good" checks
157 Class<?>[] good = { Object.class, Object[].class, int.class};
158 checkSingletonNests(good);
159
160 // More thorough correctness check
161 checkNest(SampleNest.class, SampleNest.nestedTypes(), false);
162
163 // Special cases - legal but not produced by javac
164 checkNest(HostWithSelfMember.class,
165 new Class<?>[] { HostWithSelfMember.class,
166 HostWithSelfMember.Member.class },
167 true);
168 checkNest(HostWithDuplicateMembers.class,
169 new Class<?>[] { HostWithDuplicateMembers.class,
170 HostWithDuplicateMembers.Member1.class,
171 HostWithDuplicateMembers.Member2.class },
172 true);
173
174 // Hosts with "bad" members
175 Class<?>[] bad = {
176 HostOfMemberNoHost.class,
177 HostOfMemberMissingHost.class,
178 HostOfMemberNotOurHost.class,
179 HostOfMemberNotInstanceHost.class,
180 HostOfMemberMalformedHost.class,
181 };
182 Class<?>[] exceptions = {
183 IncompatibleClassChangeError.class,
184 NoClassDefFoundError.class,
185 IncompatibleClassChangeError.class,
186 IncompatibleClassChangeError.class,
187 ClassFormatError.class,
188 };
189 String[] messages = {
190 "Nest member HostOfMemberNoHost$MemberNoHost in HostOfMemberNoHost " +
191 "declares a different nest host of HostOfMemberNoHost$MemberNoHost",
192 "Unable to load nest-host class (NestHost) of " +
193 "HostOfMemberMissingHost$MemberMissingHost",
194 "Type HostOfMemberNotOurHost$MemberNotOurHost is not a nest member " +
195 "of InvalidNestHost: current type is not listed as a nest member",
196 "Type HostOfMemberNotInstanceHost$MemberNotInstanceHost is not a nest " +
197 "member of [LInvalidNestHost;: current type is not listed as a nest member",
198 "Incompatible magic value 3735928559 in class file MalformedHost",
199 };
200 for (int i = 0; i < bad.length; i++) {
201 try {
202 bad[i].getNestMembers();
203 throw new Error("getNestMembers() succeeded for class " +
204 bad[i].getName());
205 } catch (LinkageError e) {
206 checkException(e, messages[i], exceptions[i]);
207 }
208 }
209 }
210
211 static void checkException(Throwable actual, String msg, Class<?> expected) {
212 if (!actual.getClass().equals(expected))
213 throw new Error("Unexpected exception: got " + actual.getClass().getName()
214 + " but expected " + expected.getName());
215 if (!actual.getMessage().contains(msg))
216 throw new Error("Wrong " + actual.getClass().getSimpleName() +": \"" +
217 actual.getMessage() + "\" does not contain \"" +
224 Class<?> host = target.getNestHost();
225 if (host != expected)
226 throw new Error("Class " + target.getName() +
227 " has nest host " + host.getName() +
228 " but expected " + expected.getName());
229 }
230
231 static void checkNestmates(Class<?> a, Class<?> b, boolean mates) {
232 System.out.println("Checking if " + a.getName() +
233 " isNestmateOf " + b.getName());
234
235 if (a.isNestmateOf(b) != mates)
236 throw new Error("Class " + a.getName() + " is " +
237 (mates ? "not " : "") +
238 "a nestmate of " + b.getName() + " but should " +
239 (mates ? "" : "not ") + "be");
240 }
241
242 static Comparator<Class<?>> cmp = Comparator.comparing(Class::getName);
243
244 static void checkNest(Class<?> host, Class<?>[] unsortedTypes, boolean expectDups) {
245 Class<?>[] members = host.getNestMembers();
246 Arrays.sort(members, cmp);
247 Class<?>[] nestedTypes = unsortedTypes.clone();
248 Arrays.sort(nestedTypes, cmp);
249 printMembers(host, members);
250 printDeclared(host, nestedTypes);
251 if (!Arrays.equals(members, nestedTypes)) {
252 if (!expectDups) {
253 throw new Error("Class " + host.getName() + " has different members " +
254 "compared to declared classes");
255 }
256 else {
257 // get rid of duplicates
258 Class<?>[] memberSet =
259 new HashSet<Class<?>>(Arrays.asList(members)).toArray(new Class<?>[0]);
260 Arrays.sort(memberSet, cmp);
261 if (!Arrays.equals(memberSet, nestedTypes)) {
262 throw new Error("Class " + host.getName() + " has different members " +
263 "compared to declared classes, even after duplicate removal");
264 }
265 }
266 }
267 // verify all the relationships that must hold for nest members
268 for (Class<?> a : members) {
269 checkHost(a, host);
270 checkNestmates(a, host, true);
271 Class<?>[] aMembers = a.getNestMembers();
272 if (aMembers[0] != host) {
273 throw new Error("Class " + a.getName() + " getNestMembers()[0] = " +
274 aMembers[0].getName() + " not " + host.getName());
275
276 }
277 Arrays.sort(aMembers, cmp);
278 if (!Arrays.equals(members, aMembers)) {
279 throw new Error("Class " + a.getName() + " has different members " +
280 "compared to host " + host.getName());
281 }
282 for (Class<?> b : members) {
283 checkNestmates(a, b, true);
284 }
285 }
|