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/misc/JarIndex/metaInfFilenames/Basic.java
38853 views
1
/*
2
* Copyright (c) 2011, 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 6887710
27
* @summary Verify the impact of sun.misc.JarIndex.metaInfFilenames on Service loaders
28
* @run main/othervm Basic
29
*/
30
31
import java.io.IOException;
32
import java.io.BufferedReader;
33
import java.io.File;
34
import java.io.FileInputStream;
35
import java.io.InputStream;
36
import java.io.InputStreamReader;
37
import java.io.OutputStream;
38
import java.net.InetSocketAddress;
39
import java.net.URI;
40
import java.net.URL;
41
import java.net.URLClassLoader;
42
import java.util.Arrays;
43
import java.util.Iterator;
44
import java.util.ServiceLoader;
45
import com.sun.net.httpserver.Headers;
46
import com.sun.net.httpserver.HttpExchange;
47
import com.sun.net.httpserver.HttpHandler;
48
import com.sun.net.httpserver.HttpServer;
49
50
/**
51
* Verifies the impact of sun.misc.JarIndex.metaInfFilenames on service loaders
52
* (sun.misc.Service & java.util.ServiceLoader), as well as finding resources
53
* through Class.getResouce.
54
*
55
* 1) Compile the test sources:
56
* jarA:
57
* META-INF/services/my.happy.land
58
* com/message/spi/MessageService.java
59
* a/A.java
60
* jarB:
61
* META-INF/JAVA2.DS
62
* META-INF/services/no.name.service
63
* b/B.java
64
* jarC:
65
* META-INF/fonts.mf
66
* META-INF/fonts/Company-corporate.ttf
67
* META-INF/fonts/kidpr.ttf
68
* META-INF/services/com.message.spi.MessageService
69
* my/impl/StandardMessageService.java
70
*
71
* 2) Build three jar files a.jar, b.jar, c.jar
72
*
73
* 3) Create an index in a.jar (jar -i a.jar b.jar c.jar)
74
* with sun.misc.JarIndex.metaInfFilenames=true
75
*
76
* 4) Start a HTTP server serving out the three jars.
77
*
78
* The test then tries to locate services/resources within the jars using
79
* URLClassLoader. Each request to the HTTP server is recorded to ensure
80
* only the correct amount of requests are being made.
81
*
82
* Note: Needs jdk/lib/tools.jar in the classpath to compile and run.
83
*/
84
85
public class Basic {
86
static final String slash = File.separator;
87
static final String[] testSources = {
88
"jarA" + slash + "a" + slash + "A.java",
89
"jarA" + slash + "com" + slash + "message" + slash + "spi" + slash + "MessageService.java",
90
"jarB" + slash + "b" + slash + "B.java",
91
"jarC" + slash + "my" + slash + "impl" + slash + "StandardMessageService.java"};
92
93
static final String testSrc = System.getProperty("test.src");
94
static final String testSrcDir = testSrc != null ? testSrc : ".";
95
static final String testClasses = System.getProperty("test.classes");
96
static final String testClassesDir = testClasses != null ? testClasses : ".";
97
98
static JarHttpServer httpServer;
99
100
public static void main(String[] args) throws Exception {
101
102
// Set global url cache to false so that we can track every jar request.
103
(new URL("http://localhost/")).openConnection().setDefaultUseCaches(false);
104
105
buildTest();
106
107
try {
108
httpServer = new JarHttpServer(testClassesDir);
109
httpServer.start();
110
111
doTest(httpServer.getAddress());
112
113
} catch (IOException ioe) {
114
ioe.printStackTrace();
115
} finally {
116
if (httpServer != null) { httpServer.stop(2); }
117
}
118
}
119
120
static void buildTest() {
121
/* compile the source that will be used to generate the jars */
122
for (int i=0; i<testSources.length; i++)
123
testSources[i] = testSrcDir + slash + testSources[i];
124
125
compile("-d" , testClassesDir,
126
"-sourcepath", testSrcDir,
127
testSources[0], testSources[1], testSources[2], testSources[3]);
128
129
/* build the 3 jar files */
130
jar("-cf", testClassesDir + slash + "a.jar",
131
"-C", testClassesDir, "a",
132
"-C", testClassesDir, "com",
133
"-C", testSrcDir + slash + "jarA", "META-INF");
134
jar("-cf", testClassesDir + slash + "b.jar",
135
"-C", testClassesDir, "b",
136
"-C", testSrcDir + slash + "jarB", "META-INF");
137
jar("-cf", testClassesDir + slash + "c.jar",
138
"-C", testClassesDir, "my",
139
"-C", testSrcDir + slash + "jarC", "META-INF");
140
141
/* Create an index in a.jar for b.jar and c.jar */
142
createIndex(testClassesDir);
143
}
144
145
/* run jar <args> */
146
static void jar(String... args) {
147
debug("Running: jar " + Arrays.toString(args));
148
sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");
149
if (!jar.run(args)) {
150
throw new RuntimeException("jar failed: args=" + Arrays.toString(args));
151
}
152
}
153
154
/* run javac <args> */
155
static void compile(String... args) {
156
debug("Running: javac " + Arrays.toString(args));
157
if (com.sun.tools.javac.Main.compile(args) != 0) {
158
throw new RuntimeException("javac failed: args=" + Arrays.toString(args));
159
}
160
}
161
162
static String jar;
163
static {
164
String javaHome = System.getProperty("java.home");
165
if (javaHome.endsWith("jre")) {
166
int index = javaHome.lastIndexOf(slash);
167
if (index != -1)
168
javaHome = javaHome.substring(0, index);
169
}
170
171
jar = javaHome + slash+ "bin" + slash + "jar";
172
}
173
174
/* create the index */
175
static void createIndex(String workingDir) {
176
// ProcessBuilder is used so that the current directory can be set
177
// to the directory that directly contains the jars.
178
debug("Running jar to create the index");
179
ProcessBuilder pb = new ProcessBuilder(
180
jar, "-J-Dsun.misc.JarIndex.metaInfFilenames=true", "-i", "a.jar", "b.jar", "c.jar");
181
pb.directory(new File(workingDir));
182
//pd.inheritIO();
183
try {
184
Process p = pb.start();
185
if(p.waitFor() != 0)
186
throw new RuntimeException("jar indexing failed");
187
188
if(debug && p != null) {
189
String line = null;
190
BufferedReader reader =
191
new BufferedReader(new InputStreamReader(p.getInputStream()));
192
while((line = reader.readLine()) != null)
193
debug(line);
194
reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
195
while((line = reader.readLine()) != null)
196
debug(line);
197
}
198
} catch(InterruptedException ie) { throw new RuntimeException(ie);
199
} catch(IOException e) { throw new RuntimeException(e); }
200
}
201
202
static final boolean debug = true;
203
204
static void debug(Object message) { if (debug) System.out.println(message); }
205
206
/* service define in c.jar */
207
static final String messageService = "com.message.spi.MessageService";
208
209
/* a service that is not defined in any of the jars */
210
static final String unknownService = "java.lang.Object";
211
212
static void doTest(InetSocketAddress serverAddress) throws IOException {
213
URL baseURL = new URL("http://localhost:" + serverAddress.getPort() + "/");
214
215
int failed = 0;
216
217
// Tests using sun.misc.Service
218
if (!sunMiscServiceTest(baseURL, messageService, true, false, true)) {
219
System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");
220
failed++;
221
}
222
if (!sunMiscServiceTest(baseURL, unknownService, false, false, false)) {
223
System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");
224
failed++;
225
}
226
227
// Tests using java.util.SerivceLoader
228
if (!javaUtilServiceLoaderTest(baseURL, messageService, true, false, true)) {
229
System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");
230
failed++;
231
}
232
if (!javaUtilServiceLoaderTest(baseURL, unknownService, false, false, false)) {
233
System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");
234
failed++;
235
}
236
237
// Tests using java.lang.Class (similar to the FontManager in javafx)
238
if (!klassLoader(baseURL, "/META-INF/fonts.mf", true, false, true)) {
239
System.out.println("Test: klassLoader looking for /META-INF/fonts.mf failed");
240
failed++;
241
}
242
if (!klassLoader(baseURL, "/META-INF/unknown.mf", false, false, false)) {
243
System.out.println("Test: klassLoader looking for /META-INF/unknown.mf failed");
244
failed++;
245
}
246
247
if (failed > 0)
248
throw new RuntimeException("Failed: " + failed + " tests");
249
}
250
251
static boolean sunMiscServiceTest(URL baseURL,
252
String serviceClass,
253
boolean expectToFind,
254
boolean expectbDotJar,
255
boolean expectcDotJar) throws IOException {
256
debug("----------------------------------");
257
debug("Running test with sun.misc.Service looking for " + serviceClass);
258
URLClassLoader loader = getLoader(baseURL);
259
httpServer.reset();
260
261
Class<?> messageServiceClass = null;
262
try {
263
messageServiceClass = loader.loadClass(serviceClass);
264
} catch (ClassNotFoundException cnfe) {
265
System.err.println(cnfe);
266
throw new RuntimeException("Error in test: " + cnfe);
267
}
268
269
Iterator<?> iterator = sun.misc.Service.providers(messageServiceClass, loader);
270
if (expectToFind && !iterator.hasNext()) {
271
debug(messageServiceClass + " NOT found.");
272
return false;
273
}
274
275
while (iterator.hasNext()) {
276
debug("found " + iterator.next() + " " + messageService);
277
}
278
279
debug("HttpServer: " + httpServer);
280
281
if (!expectbDotJar && httpServer.bDotJar > 0) {
282
debug("Unexpeced request sent to the httpserver for b.jar");
283
return false;
284
}
285
if (!expectcDotJar && httpServer.cDotJar > 0) {
286
debug("Unexpeced request sent to the httpserver for c.jar");
287
return false;
288
}
289
290
return true;
291
}
292
293
static boolean javaUtilServiceLoaderTest(URL baseURL,
294
String serviceClass,
295
boolean expectToFind,
296
boolean expectbDotJar,
297
boolean expectcDotJar) throws IOException {
298
debug("----------------------------------");
299
debug("Running test with java.util.ServiceLoader looking for " + serviceClass);
300
URLClassLoader loader = getLoader(baseURL);
301
httpServer.reset();
302
303
Class<?> messageServiceClass = null;
304
try {
305
messageServiceClass = loader.loadClass(serviceClass);
306
} catch (ClassNotFoundException cnfe) {
307
System.err.println(cnfe);
308
throw new RuntimeException("Error in test: " + cnfe);
309
}
310
311
Iterator<?> iterator = (ServiceLoader.load(messageServiceClass, loader)).iterator();
312
if (expectToFind && !iterator.hasNext()) {
313
debug(messageServiceClass + " NOT found.");
314
return false;
315
}
316
317
while (iterator.hasNext()) {
318
debug("found " + iterator.next() + " " + messageService);
319
}
320
321
debug("HttpServer: " + httpServer);
322
323
if (!expectbDotJar && httpServer.bDotJar > 0) {
324
debug("Unexpeced request sent to the httpserver for b.jar");
325
return false;
326
}
327
if (!expectcDotJar && httpServer.cDotJar > 0) {
328
debug("Unexpeced request sent to the httpserver for c.jar");
329
return false;
330
}
331
332
return true;
333
}
334
335
/* Tries to find a resource in a similar way to the font manager in javafx
336
* com.sun.javafx.scene.text.FontManager */
337
static boolean klassLoader(URL baseURL,
338
String resource,
339
boolean expectToFind,
340
boolean expectbDotJar,
341
boolean expectcDotJar) throws IOException {
342
debug("----------------------------------");
343
debug("Running test looking for " + resource);
344
URLClassLoader loader = getLoader(baseURL);
345
httpServer.reset();
346
347
Class<?> ADotAKlass = null;
348
try {
349
ADotAKlass = loader.loadClass("a.A");
350
} catch (ClassNotFoundException cnfe) {
351
System.err.println(cnfe);
352
throw new RuntimeException("Error in test: " + cnfe);
353
}
354
355
URL u = ADotAKlass.getResource(resource);
356
if (expectToFind && u == null) {
357
System.out.println("Expected to find " + resource + " but didn't");
358
return false;
359
}
360
361
debug("HttpServer: " + httpServer);
362
363
if (!expectbDotJar && httpServer.bDotJar > 0) {
364
debug("Unexpeced request sent to the httpserver for b.jar");
365
return false;
366
}
367
if (!expectcDotJar && httpServer.cDotJar > 0) {
368
debug("Unexpeced request sent to the httpserver for c.jar");
369
return false;
370
}
371
372
return true;
373
}
374
375
static URLClassLoader getLoader(URL baseURL) throws IOException {
376
ClassLoader loader = Basic.class.getClassLoader();
377
378
while (loader.getParent() != null)
379
loader = loader.getParent();
380
381
return new URLClassLoader( new URL[]{
382
new URL(baseURL, "a.jar"),
383
new URL(baseURL, "b.jar"),
384
new URL(baseURL, "c.jar")}, loader );
385
}
386
387
/**
388
* HTTP Server to server the jar files.
389
*/
390
static class JarHttpServer implements HttpHandler {
391
final String docsDir;
392
final HttpServer httpServer;
393
int aDotJar, bDotJar, cDotJar;
394
395
JarHttpServer(String docsDir) throws IOException {
396
this.docsDir = docsDir;
397
398
httpServer = HttpServer.create(new InetSocketAddress(0), 0);
399
httpServer.createContext("/", this);
400
}
401
402
void start() throws IOException {
403
httpServer.start();
404
}
405
406
void stop(int delay) {
407
httpServer.stop(delay);
408
}
409
410
InetSocketAddress getAddress() {
411
return httpServer.getAddress();
412
}
413
414
void reset() {
415
aDotJar = bDotJar = cDotJar = 0;
416
}
417
418
@Override
419
public String toString() {
420
return "aDotJar=" + aDotJar + ", bDotJar=" + bDotJar + ", cDotJar=" + cDotJar;
421
}
422
423
public void handle(HttpExchange t) throws IOException {
424
InputStream is = t.getRequestBody();
425
Headers map = t.getRequestHeaders();
426
Headers rmap = t.getResponseHeaders();
427
URI uri = t.getRequestURI();
428
429
debug("Server: received request for " + uri);
430
String path = uri.getPath();
431
if (path.endsWith("a.jar"))
432
aDotJar++;
433
else if (path.endsWith("b.jar"))
434
bDotJar++;
435
else if (path.endsWith("c.jar"))
436
cDotJar++;
437
else
438
System.out.println("Unexpected resource request" + path);
439
440
while (is.read() != -1);
441
is.close();
442
443
File file = new File(docsDir, path);
444
if (!file.exists())
445
throw new RuntimeException("Error: request for " + file);
446
long clen = file.length();
447
t.sendResponseHeaders (200, clen);
448
OutputStream os = t.getResponseBody();
449
FileInputStream fis = new FileInputStream(file);
450
try {
451
byte[] buf = new byte [16 * 1024];
452
int len;
453
while ((len=fis.read(buf)) != -1) {
454
os.write (buf, 0, len);
455
}
456
} catch (IOException e) {
457
e.printStackTrace();
458
}
459
fis.close();
460
os.close();
461
}
462
}
463
}
464
465