Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/annotation/AnnotationsInheritanceOrderRedefinitionTest.java
38813 views
1
/*
2
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
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 8011940
27
* @summary Test inheritance, order and class redefinition behaviour of RUNTIME
28
* class annotations
29
* @author plevart
30
*/
31
32
import sun.reflect.annotation.AnnotationParser;
33
34
import java.lang.annotation.Annotation;
35
import java.lang.annotation.Inherited;
36
import java.lang.annotation.Retention;
37
import java.lang.annotation.RetentionPolicy;
38
import java.lang.reflect.Field;
39
import java.lang.reflect.InvocationTargetException;
40
import java.util.ArrayList;
41
import java.util.Arrays;
42
import java.util.Collections;
43
import java.util.List;
44
import java.util.StringJoiner;
45
46
public class AnnotationsInheritanceOrderRedefinitionTest {
47
48
@Retention(RetentionPolicy.RUNTIME)
49
@Inherited
50
@interface Ann1 {
51
String value();
52
}
53
54
@Retention(RetentionPolicy.RUNTIME)
55
@Inherited
56
@interface Ann2 {
57
String value();
58
}
59
60
@Retention(RetentionPolicy.RUNTIME)
61
@Inherited
62
@interface Ann3 {
63
String value();
64
}
65
66
@Ann1("A")
67
@Ann2("A")
68
static class A {}
69
70
@Ann3("B")
71
static class B extends A {}
72
73
@Ann1("C")
74
@Ann3("C")
75
static class C extends B {}
76
77
public static void main(String[] args) {
78
79
StringBuilder msgs = new StringBuilder();
80
boolean ok = true;
81
82
ok &= annotationsEqual(msgs, A.class, true,
83
ann(Ann1.class, "A"), ann(Ann2.class, "A"));
84
ok &= annotationsEqual(msgs, A.class, false,
85
ann(Ann1.class, "A"), ann(Ann2.class, "A"));
86
ok &= annotationsEqual(msgs, B.class, true,
87
ann(Ann3.class, "B"));
88
ok &= annotationsEqual(msgs, B.class, false,
89
ann(Ann1.class, "A"), ann(Ann2.class, "A"), ann(Ann3.class, "B"));
90
ok &= annotationsEqual(msgs, C.class, true,
91
ann(Ann1.class, "C"), ann(Ann3.class, "C"));
92
ok &= annotationsEqual(msgs, C.class, false,
93
ann(Ann1.class, "C"), ann(Ann2.class, "A"), ann(Ann3.class, "C"));
94
95
Annotation[] declaredAnnotatiosA = A.class.getDeclaredAnnotations();
96
Annotation[] annotationsA = A.class.getAnnotations();
97
Annotation[] declaredAnnotatiosB = B.class.getDeclaredAnnotations();
98
Annotation[] annotationsB = B.class.getAnnotations();
99
Annotation[] declaredAnnotatiosC = C.class.getDeclaredAnnotations();
100
Annotation[] annotationsC = C.class.getAnnotations();
101
102
incrementClassRedefinedCount(A.class);
103
incrementClassRedefinedCount(B.class);
104
incrementClassRedefinedCount(C.class);
105
106
ok &= annotationsEqualButNotSame(msgs, A.class, true, declaredAnnotatiosA);
107
ok &= annotationsEqualButNotSame(msgs, A.class, false, annotationsA);
108
ok &= annotationsEqualButNotSame(msgs, B.class, true, declaredAnnotatiosB);
109
ok &= annotationsEqualButNotSame(msgs, B.class, false, annotationsB);
110
ok &= annotationsEqualButNotSame(msgs, C.class, true, declaredAnnotatiosC);
111
ok &= annotationsEqualButNotSame(msgs, C.class, false, annotationsC);
112
113
if (!ok) {
114
throw new RuntimeException("test failure\n" + msgs);
115
}
116
}
117
118
// utility methods
119
120
private static boolean annotationsEqualButNotSame(StringBuilder msgs,
121
Class<?> declaringClass, boolean declaredOnly, Annotation[] oldAnns) {
122
if (!annotationsEqual(msgs, declaringClass, declaredOnly, oldAnns)) {
123
return false;
124
}
125
Annotation[] anns = declaredOnly
126
? declaringClass.getDeclaredAnnotations()
127
: declaringClass.getAnnotations();
128
List<Annotation> sameAnns = new ArrayList<>();
129
for (int i = 0; i < anns.length; i++) {
130
if (anns[i] == oldAnns[i]) {
131
sameAnns.add(anns[i]);
132
}
133
}
134
if (!sameAnns.isEmpty()) {
135
msgs.append(declaredOnly ? "declared " : "").append("annotations for ")
136
.append(declaringClass.getSimpleName())
137
.append(" not re-parsed after class redefinition: ")
138
.append(toSimpleString(sameAnns)).append("\n");
139
return false;
140
} else {
141
return true;
142
}
143
}
144
145
private static boolean annotationsEqual(StringBuilder msgs,
146
Class<?> declaringClass, boolean declaredOnly, Annotation... expectedAnns) {
147
Annotation[] anns = declaredOnly
148
? declaringClass.getDeclaredAnnotations()
149
: declaringClass.getAnnotations();
150
if (!Arrays.equals(anns, expectedAnns)) {
151
msgs.append(declaredOnly ? "declared " : "").append("annotations for ")
152
.append(declaringClass.getSimpleName()).append(" are: ")
153
.append(toSimpleString(anns)).append(", expected: ")
154
.append(toSimpleString(expectedAnns)).append("\n");
155
return false;
156
} else {
157
return true;
158
}
159
}
160
161
private static Annotation ann(Class<? extends Annotation> annotationType,
162
Object value) {
163
return AnnotationParser.annotationForMap(annotationType,
164
Collections.singletonMap("value", value));
165
}
166
167
private static String toSimpleString(List<Annotation> anns) {
168
return toSimpleString(anns.toArray(new Annotation[anns.size()]));
169
}
170
171
private static String toSimpleString(Annotation[] anns) {
172
StringJoiner joiner = new StringJoiner(", ");
173
for (Annotation ann : anns) {
174
joiner.add(toSimpleString(ann));
175
}
176
return joiner.toString();
177
}
178
179
private static String toSimpleString(Annotation ann) {
180
Class<? extends Annotation> annotationType = ann.annotationType();
181
Object value;
182
try {
183
value = annotationType.getDeclaredMethod("value").invoke(ann);
184
} catch (IllegalAccessException | InvocationTargetException
185
| NoSuchMethodException e) {
186
throw new RuntimeException(e);
187
}
188
return "@" + annotationType.getSimpleName() + "(" + value + ")";
189
}
190
191
private static final Field classRedefinedCountField;
192
193
static {
194
try {
195
classRedefinedCountField = Class.class.getDeclaredField("classRedefinedCount");
196
classRedefinedCountField.setAccessible(true);
197
} catch (NoSuchFieldException e) {
198
throw new Error(e);
199
}
200
}
201
202
private static void incrementClassRedefinedCount(Class<?> clazz) {
203
try {
204
classRedefinedCountField.set(clazz,
205
((Integer) classRedefinedCountField.get(clazz)) + 1);
206
} catch (IllegalAccessException e) {
207
throw new RuntimeException(e);
208
}
209
}
210
}
211
212