Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/misc/JarIndex/metaInfFilenames/Basic.java
38853 views
/*1* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 688771026* @summary Verify the impact of sun.misc.JarIndex.metaInfFilenames on Service loaders27* @run main/othervm Basic28*/2930import java.io.IOException;31import java.io.BufferedReader;32import java.io.File;33import java.io.FileInputStream;34import java.io.InputStream;35import java.io.InputStreamReader;36import java.io.OutputStream;37import java.net.InetSocketAddress;38import java.net.URI;39import java.net.URL;40import java.net.URLClassLoader;41import java.util.Arrays;42import java.util.Iterator;43import java.util.ServiceLoader;44import com.sun.net.httpserver.Headers;45import com.sun.net.httpserver.HttpExchange;46import com.sun.net.httpserver.HttpHandler;47import com.sun.net.httpserver.HttpServer;4849/**50* Verifies the impact of sun.misc.JarIndex.metaInfFilenames on service loaders51* (sun.misc.Service & java.util.ServiceLoader), as well as finding resources52* through Class.getResouce.53*54* 1) Compile the test sources:55* jarA:56* META-INF/services/my.happy.land57* com/message/spi/MessageService.java58* a/A.java59* jarB:60* META-INF/JAVA2.DS61* META-INF/services/no.name.service62* b/B.java63* jarC:64* META-INF/fonts.mf65* META-INF/fonts/Company-corporate.ttf66* META-INF/fonts/kidpr.ttf67* META-INF/services/com.message.spi.MessageService68* my/impl/StandardMessageService.java69*70* 2) Build three jar files a.jar, b.jar, c.jar71*72* 3) Create an index in a.jar (jar -i a.jar b.jar c.jar)73* with sun.misc.JarIndex.metaInfFilenames=true74*75* 4) Start a HTTP server serving out the three jars.76*77* The test then tries to locate services/resources within the jars using78* URLClassLoader. Each request to the HTTP server is recorded to ensure79* only the correct amount of requests are being made.80*81* Note: Needs jdk/lib/tools.jar in the classpath to compile and run.82*/8384public class Basic {85static final String slash = File.separator;86static final String[] testSources = {87"jarA" + slash + "a" + slash + "A.java",88"jarA" + slash + "com" + slash + "message" + slash + "spi" + slash + "MessageService.java",89"jarB" + slash + "b" + slash + "B.java",90"jarC" + slash + "my" + slash + "impl" + slash + "StandardMessageService.java"};9192static final String testSrc = System.getProperty("test.src");93static final String testSrcDir = testSrc != null ? testSrc : ".";94static final String testClasses = System.getProperty("test.classes");95static final String testClassesDir = testClasses != null ? testClasses : ".";9697static JarHttpServer httpServer;9899public static void main(String[] args) throws Exception {100101// Set global url cache to false so that we can track every jar request.102(new URL("http://localhost/")).openConnection().setDefaultUseCaches(false);103104buildTest();105106try {107httpServer = new JarHttpServer(testClassesDir);108httpServer.start();109110doTest(httpServer.getAddress());111112} catch (IOException ioe) {113ioe.printStackTrace();114} finally {115if (httpServer != null) { httpServer.stop(2); }116}117}118119static void buildTest() {120/* compile the source that will be used to generate the jars */121for (int i=0; i<testSources.length; i++)122testSources[i] = testSrcDir + slash + testSources[i];123124compile("-d" , testClassesDir,125"-sourcepath", testSrcDir,126testSources[0], testSources[1], testSources[2], testSources[3]);127128/* build the 3 jar files */129jar("-cf", testClassesDir + slash + "a.jar",130"-C", testClassesDir, "a",131"-C", testClassesDir, "com",132"-C", testSrcDir + slash + "jarA", "META-INF");133jar("-cf", testClassesDir + slash + "b.jar",134"-C", testClassesDir, "b",135"-C", testSrcDir + slash + "jarB", "META-INF");136jar("-cf", testClassesDir + slash + "c.jar",137"-C", testClassesDir, "my",138"-C", testSrcDir + slash + "jarC", "META-INF");139140/* Create an index in a.jar for b.jar and c.jar */141createIndex(testClassesDir);142}143144/* run jar <args> */145static void jar(String... args) {146debug("Running: jar " + Arrays.toString(args));147sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");148if (!jar.run(args)) {149throw new RuntimeException("jar failed: args=" + Arrays.toString(args));150}151}152153/* run javac <args> */154static void compile(String... args) {155debug("Running: javac " + Arrays.toString(args));156if (com.sun.tools.javac.Main.compile(args) != 0) {157throw new RuntimeException("javac failed: args=" + Arrays.toString(args));158}159}160161static String jar;162static {163String javaHome = System.getProperty("java.home");164if (javaHome.endsWith("jre")) {165int index = javaHome.lastIndexOf(slash);166if (index != -1)167javaHome = javaHome.substring(0, index);168}169170jar = javaHome + slash+ "bin" + slash + "jar";171}172173/* create the index */174static void createIndex(String workingDir) {175// ProcessBuilder is used so that the current directory can be set176// to the directory that directly contains the jars.177debug("Running jar to create the index");178ProcessBuilder pb = new ProcessBuilder(179jar, "-J-Dsun.misc.JarIndex.metaInfFilenames=true", "-i", "a.jar", "b.jar", "c.jar");180pb.directory(new File(workingDir));181//pd.inheritIO();182try {183Process p = pb.start();184if(p.waitFor() != 0)185throw new RuntimeException("jar indexing failed");186187if(debug && p != null) {188String line = null;189BufferedReader reader =190new BufferedReader(new InputStreamReader(p.getInputStream()));191while((line = reader.readLine()) != null)192debug(line);193reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));194while((line = reader.readLine()) != null)195debug(line);196}197} catch(InterruptedException ie) { throw new RuntimeException(ie);198} catch(IOException e) { throw new RuntimeException(e); }199}200201static final boolean debug = true;202203static void debug(Object message) { if (debug) System.out.println(message); }204205/* service define in c.jar */206static final String messageService = "com.message.spi.MessageService";207208/* a service that is not defined in any of the jars */209static final String unknownService = "java.lang.Object";210211static void doTest(InetSocketAddress serverAddress) throws IOException {212URL baseURL = new URL("http://localhost:" + serverAddress.getPort() + "/");213214int failed = 0;215216// Tests using sun.misc.Service217if (!sunMiscServiceTest(baseURL, messageService, true, false, true)) {218System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");219failed++;220}221if (!sunMiscServiceTest(baseURL, unknownService, false, false, false)) {222System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");223failed++;224}225226// Tests using java.util.SerivceLoader227if (!javaUtilServiceLoaderTest(baseURL, messageService, true, false, true)) {228System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");229failed++;230}231if (!javaUtilServiceLoaderTest(baseURL, unknownService, false, false, false)) {232System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");233failed++;234}235236// Tests using java.lang.Class (similar to the FontManager in javafx)237if (!klassLoader(baseURL, "/META-INF/fonts.mf", true, false, true)) {238System.out.println("Test: klassLoader looking for /META-INF/fonts.mf failed");239failed++;240}241if (!klassLoader(baseURL, "/META-INF/unknown.mf", false, false, false)) {242System.out.println("Test: klassLoader looking for /META-INF/unknown.mf failed");243failed++;244}245246if (failed > 0)247throw new RuntimeException("Failed: " + failed + " tests");248}249250static boolean sunMiscServiceTest(URL baseURL,251String serviceClass,252boolean expectToFind,253boolean expectbDotJar,254boolean expectcDotJar) throws IOException {255debug("----------------------------------");256debug("Running test with sun.misc.Service looking for " + serviceClass);257URLClassLoader loader = getLoader(baseURL);258httpServer.reset();259260Class<?> messageServiceClass = null;261try {262messageServiceClass = loader.loadClass(serviceClass);263} catch (ClassNotFoundException cnfe) {264System.err.println(cnfe);265throw new RuntimeException("Error in test: " + cnfe);266}267268Iterator<?> iterator = sun.misc.Service.providers(messageServiceClass, loader);269if (expectToFind && !iterator.hasNext()) {270debug(messageServiceClass + " NOT found.");271return false;272}273274while (iterator.hasNext()) {275debug("found " + iterator.next() + " " + messageService);276}277278debug("HttpServer: " + httpServer);279280if (!expectbDotJar && httpServer.bDotJar > 0) {281debug("Unexpeced request sent to the httpserver for b.jar");282return false;283}284if (!expectcDotJar && httpServer.cDotJar > 0) {285debug("Unexpeced request sent to the httpserver for c.jar");286return false;287}288289return true;290}291292static boolean javaUtilServiceLoaderTest(URL baseURL,293String serviceClass,294boolean expectToFind,295boolean expectbDotJar,296boolean expectcDotJar) throws IOException {297debug("----------------------------------");298debug("Running test with java.util.ServiceLoader looking for " + serviceClass);299URLClassLoader loader = getLoader(baseURL);300httpServer.reset();301302Class<?> messageServiceClass = null;303try {304messageServiceClass = loader.loadClass(serviceClass);305} catch (ClassNotFoundException cnfe) {306System.err.println(cnfe);307throw new RuntimeException("Error in test: " + cnfe);308}309310Iterator<?> iterator = (ServiceLoader.load(messageServiceClass, loader)).iterator();311if (expectToFind && !iterator.hasNext()) {312debug(messageServiceClass + " NOT found.");313return false;314}315316while (iterator.hasNext()) {317debug("found " + iterator.next() + " " + messageService);318}319320debug("HttpServer: " + httpServer);321322if (!expectbDotJar && httpServer.bDotJar > 0) {323debug("Unexpeced request sent to the httpserver for b.jar");324return false;325}326if (!expectcDotJar && httpServer.cDotJar > 0) {327debug("Unexpeced request sent to the httpserver for c.jar");328return false;329}330331return true;332}333334/* Tries to find a resource in a similar way to the font manager in javafx335* com.sun.javafx.scene.text.FontManager */336static boolean klassLoader(URL baseURL,337String resource,338boolean expectToFind,339boolean expectbDotJar,340boolean expectcDotJar) throws IOException {341debug("----------------------------------");342debug("Running test looking for " + resource);343URLClassLoader loader = getLoader(baseURL);344httpServer.reset();345346Class<?> ADotAKlass = null;347try {348ADotAKlass = loader.loadClass("a.A");349} catch (ClassNotFoundException cnfe) {350System.err.println(cnfe);351throw new RuntimeException("Error in test: " + cnfe);352}353354URL u = ADotAKlass.getResource(resource);355if (expectToFind && u == null) {356System.out.println("Expected to find " + resource + " but didn't");357return false;358}359360debug("HttpServer: " + httpServer);361362if (!expectbDotJar && httpServer.bDotJar > 0) {363debug("Unexpeced request sent to the httpserver for b.jar");364return false;365}366if (!expectcDotJar && httpServer.cDotJar > 0) {367debug("Unexpeced request sent to the httpserver for c.jar");368return false;369}370371return true;372}373374static URLClassLoader getLoader(URL baseURL) throws IOException {375ClassLoader loader = Basic.class.getClassLoader();376377while (loader.getParent() != null)378loader = loader.getParent();379380return new URLClassLoader( new URL[]{381new URL(baseURL, "a.jar"),382new URL(baseURL, "b.jar"),383new URL(baseURL, "c.jar")}, loader );384}385386/**387* HTTP Server to server the jar files.388*/389static class JarHttpServer implements HttpHandler {390final String docsDir;391final HttpServer httpServer;392int aDotJar, bDotJar, cDotJar;393394JarHttpServer(String docsDir) throws IOException {395this.docsDir = docsDir;396397httpServer = HttpServer.create(new InetSocketAddress(0), 0);398httpServer.createContext("/", this);399}400401void start() throws IOException {402httpServer.start();403}404405void stop(int delay) {406httpServer.stop(delay);407}408409InetSocketAddress getAddress() {410return httpServer.getAddress();411}412413void reset() {414aDotJar = bDotJar = cDotJar = 0;415}416417@Override418public String toString() {419return "aDotJar=" + aDotJar + ", bDotJar=" + bDotJar + ", cDotJar=" + cDotJar;420}421422public void handle(HttpExchange t) throws IOException {423InputStream is = t.getRequestBody();424Headers map = t.getRequestHeaders();425Headers rmap = t.getResponseHeaders();426URI uri = t.getRequestURI();427428debug("Server: received request for " + uri);429String path = uri.getPath();430if (path.endsWith("a.jar"))431aDotJar++;432else if (path.endsWith("b.jar"))433bDotJar++;434else if (path.endsWith("c.jar"))435cDotJar++;436else437System.out.println("Unexpected resource request" + path);438439while (is.read() != -1);440is.close();441442File file = new File(docsDir, path);443if (!file.exists())444throw new RuntimeException("Error: request for " + file);445long clen = file.length();446t.sendResponseHeaders (200, clen);447OutputStream os = t.getResponseBody();448FileInputStream fis = new FileInputStream(file);449try {450byte[] buf = new byte [16 * 1024];451int len;452while ((len=fis.read(buf)) != -1) {453os.write (buf, 0, len);454}455} catch (IOException e) {456e.printStackTrace();457}458fis.close();459os.close();460}461}462}463464465