Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java
38841 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
import com.sun.tools.classfile.*;
25
import com.sun.tools.jdeps.ClassFileReader;
26
import static com.sun.tools.classfile.ConstantPool.*;
27
import java.io.File;
28
import java.io.IOException;
29
import java.nio.file.FileVisitResult;
30
import java.nio.file.Files;
31
import java.nio.file.Path;
32
import java.nio.file.Paths;
33
import java.nio.file.SimpleFileVisitor;
34
import java.nio.file.attribute.BasicFileAttributes;
35
import java.util.ArrayList;
36
import java.util.List;
37
import java.util.Set;
38
import java.util.concurrent.Callable;
39
import java.util.concurrent.ExecutionException;
40
import java.util.concurrent.ExecutorService;
41
import java.util.concurrent.Executors;
42
import java.util.concurrent.FutureTask;
43
44
/*
45
* @test
46
* @bug 8010117
47
* @summary Verify if CallerSensitive methods are annotated with
48
* sun.reflect.CallerSensitive annotation
49
* @build CallerSensitiveFinder
50
* @run main/othervm/timeout=900 -mx600m CallerSensitiveFinder
51
*/
52
public class CallerSensitiveFinder {
53
private static int numThreads = 3;
54
private static boolean verbose = false;
55
public static void main(String[] args) throws Exception {
56
List<Path> classes = new ArrayList<>();
57
String testclasses = System.getProperty("test.classes", ".");
58
int i = 0;
59
while (i < args.length) {
60
String arg = args[i++];
61
if (arg.equals("-v")) {
62
verbose = true;
63
} else {
64
Path p = Paths.get(testclasses, arg);
65
if (!p.toFile().exists()) {
66
throw new IllegalArgumentException(arg + " does not exist");
67
}
68
classes.add(p);
69
}
70
}
71
if (classes.isEmpty()) {
72
classes.addAll(PlatformClassPath.getJREClasses());
73
}
74
CallerSensitiveFinder csfinder = new CallerSensitiveFinder();
75
76
List<String> errors = csfinder.run(classes);
77
if (!errors.isEmpty()) {
78
throw new RuntimeException(errors.size() +
79
" caller-sensitive methods are missing @CallerSensitive annotation");
80
}
81
}
82
83
private final List<String> csMethodsMissingAnnotation = new ArrayList<>();
84
private final ReferenceFinder finder;
85
public CallerSensitiveFinder() {
86
this.finder = new ReferenceFinder(getFilter(), getVisitor());
87
}
88
89
private ReferenceFinder.Filter getFilter() {
90
final String classname = "sun/reflect/Reflection";
91
final String method = "getCallerClass";
92
return new ReferenceFinder.Filter() {
93
public boolean accept(ConstantPool cpool, CPRefInfo cpref) {
94
try {
95
CONSTANT_NameAndType_info nat = cpref.getNameAndTypeInfo();
96
return cpref.getClassName().equals(classname) && nat.getName().equals(method);
97
} catch (ConstantPoolException ex) {
98
throw new RuntimeException(ex);
99
}
100
}
101
};
102
}
103
104
private ReferenceFinder.Visitor getVisitor() {
105
return new ReferenceFinder.Visitor() {
106
public void visit(ClassFile cf, Method m, List<CPRefInfo> refs) {
107
try {
108
String name = String.format("%s#%s %s", cf.getName(),
109
m.getName(cf.constant_pool),
110
m.descriptor.getValue(cf.constant_pool));
111
if (!CallerSensitiveFinder.isCallerSensitive(m, cf.constant_pool)) {
112
csMethodsMissingAnnotation.add(name);
113
System.err.println("Missing @CallerSensitive: " + name);
114
} else {
115
if (verbose) {
116
System.out.format("@CS %s%n", name);
117
}
118
}
119
} catch (ConstantPoolException ex) {
120
throw new RuntimeException(ex);
121
}
122
}
123
};
124
}
125
126
public List<String> run(List<Path> classes) throws IOException, InterruptedException,
127
ExecutionException, ConstantPoolException
128
{
129
ExecutorService pool = Executors.newFixedThreadPool(numThreads);
130
for (Path path : classes) {
131
ClassFileReader reader = ClassFileReader.newInstance(path);
132
for (ClassFile cf : reader.getClassFiles()) {
133
String classFileName = cf.getName();
134
// for each ClassFile
135
// parse constant pool to find matching method refs
136
// parse each method (caller)
137
// - visit and find method references matching the given method name
138
pool.submit(getTask(cf));
139
}
140
}
141
waitForCompletion();
142
pool.shutdown();
143
return csMethodsMissingAnnotation;
144
}
145
146
private static final String CALLER_SENSITIVE_ANNOTATION = "Lsun/reflect/CallerSensitive;";
147
private static boolean isCallerSensitive(Method m, ConstantPool cp)
148
throws ConstantPoolException
149
{
150
RuntimeAnnotations_attribute attr =
151
(RuntimeAnnotations_attribute)m.attributes.get(Attribute.RuntimeVisibleAnnotations);
152
int index = 0;
153
if (attr != null) {
154
for (int i = 0; i < attr.annotations.length; i++) {
155
Annotation ann = attr.annotations[i];
156
String annType = cp.getUTF8Value(ann.type_index);
157
if (CALLER_SENSITIVE_ANNOTATION.equals(annType)) {
158
return true;
159
}
160
}
161
}
162
return false;
163
}
164
165
private final List<FutureTask<Void>> tasks = new ArrayList<FutureTask<Void>>();
166
private FutureTask<Void> getTask(final ClassFile cf) {
167
FutureTask<Void> task = new FutureTask<Void>(new Callable<Void>() {
168
public Void call() throws Exception {
169
finder.parse(cf);
170
return null;
171
}
172
});
173
tasks.add(task);
174
return task;
175
}
176
177
private void waitForCompletion() throws InterruptedException, ExecutionException {
178
for (FutureTask<Void> t : tasks) {
179
t.get();
180
}
181
System.out.println("Parsed " + tasks.size() + " classfiles");
182
}
183
184
static class PlatformClassPath {
185
static List<Path> getJREClasses() throws IOException {
186
List<Path> result = new ArrayList<Path>();
187
Path home = Paths.get(System.getProperty("java.home"));
188
189
if (home.endsWith("jre")) {
190
// jar files in <javahome>/jre/lib
191
// skip <javahome>/lib
192
result.addAll(addJarFiles(home.resolve("lib")));
193
} else if (home.resolve("lib").toFile().exists()) {
194
// either a JRE or a jdk build image
195
File classes = home.resolve("classes").toFile();
196
if (classes.exists() && classes.isDirectory()) {
197
// jdk build outputdir
198
result.add(classes.toPath());
199
}
200
// add other JAR files
201
result.addAll(addJarFiles(home.resolve("lib")));
202
} else {
203
throw new RuntimeException("\"" + home + "\" not a JDK home");
204
}
205
return result;
206
}
207
208
static List<Path> addJarFiles(final Path root) throws IOException {
209
final List<Path> result = new ArrayList<Path>();
210
final Path ext = root.resolve("ext");
211
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
212
@Override
213
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
214
throws IOException {
215
if (dir.equals(root) || dir.equals(ext)) {
216
return FileVisitResult.CONTINUE;
217
} else {
218
// skip other cobundled JAR files
219
return FileVisitResult.SKIP_SUBTREE;
220
}
221
}
222
223
@Override
224
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
225
throws IOException {
226
File f = file.toFile();
227
String fn = f.getName();
228
// parse alt-rt.jar as well
229
if (fn.endsWith(".jar") && !fn.equals("jfxrt.jar")) {
230
result.add(file);
231
}
232
return FileVisitResult.CONTINUE;
233
}
234
});
235
return result;
236
}
237
}
238
}
239
240