6887710: Jar index should avoid putting META-INF in the INDEX.LIST
Reviewed-by: michaelm
--- a/jdk/src/share/classes/sun/misc/JarIndex.java Thu Feb 03 11:28:04 2011 +0000
+++ b/jdk/src/share/classes/sun/misc/JarIndex.java Thu Feb 03 11:56:56 2011 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,6 +67,14 @@
public static final String INDEX_NAME = "META-INF/INDEX.LIST";
/**
+ * true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true.
+ * If true, the names of the files in META-INF, and its subdirectories, will
+ * be added to the index. Otherwise, just the directory names are added.
+ */
+ private static final boolean metaInfFilenames =
+ "true".equals(System.getProperty("sun.misc.JarIndex.metaInfFilenames"));
+
+ /**
* Constructs a new, empty jar index.
*/
public JarIndex() {
@@ -187,6 +195,18 @@
}
/**
+ * Same as add(String,String) except that it doesn't strip off from the
+ * last index of '/'. It just adds the filename.
+ */
+ private void addExplicit(String fileName, String jarName) {
+ // add the mapping to indexMap
+ addToList(fileName, jarName, indexMap);
+
+ // add the mapping to jarMap
+ addToList(jarName, fileName, jarMap);
+ }
+
+ /**
* Go through all the jar files and construct the
* index table.
*/
@@ -204,15 +224,31 @@
Enumeration entries = zrf.entries();
while(entries.hasMoreElements()) {
- String fileName = ((ZipEntry)(entries.nextElement())).getName();
- // Index the META-INF directory, but not the index or manifest.
- if (!fileName.startsWith("META-INF/") ||
- !(fileName.equals("META-INF/") ||
- fileName.equals(INDEX_NAME) ||
- fileName.equals(JarFile.MANIFEST_NAME))) {
+ ZipEntry entry = (ZipEntry) entries.nextElement();
+ String fileName = entry.getName();
+
+ // Skip the META-INF directory, the index, and manifest.
+ // Any files in META-INF/ will be indexed explicitly
+ if (fileName.equals("META-INF/") ||
+ fileName.equals(INDEX_NAME) ||
+ fileName.equals(JarFile.MANIFEST_NAME))
+ continue;
+
+ if (!metaInfFilenames) {
add(fileName, currentJar);
+ } else {
+ if (!fileName.startsWith("META-INF/")) {
+ add(fileName, currentJar);
+ } else if (!entry.isDirectory()) {
+ // Add files under META-INF explicitly so that certain
+ // services, like ServiceLoader, etc, can be located
+ // with greater accuracy. Directories can be skipped
+ // since each file will be added explicitly.
+ addExplicit(fileName, currentJar);
+ }
}
}
+
zrf.close();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/Basic.java Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6887710
+ * @summary Verify the impact of sun.misc.JarIndex.metaInfFilenames on Service loaders
+ * @run main/othervm Basic
+ */
+
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import com.sun.net.httpserver.Headers;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+/**
+ * Verifies the impact of sun.misc.JarIndex.metaInfFilenames on service loaders
+ * (sun.misc.Service & java.util.ServiceLoader), as well as finding resources
+ * through Class.getResouce.
+ *
+ * 1) Compile the test sources:
+ * jarA:
+ * META-INF/services/my.happy.land
+ * com/message/spi/MessageService.java
+ * a/A.java
+ * jarB:
+ * META-INF/JAVA2.DS
+ * META-INF/services/no.name.service
+ * b/B.java
+ * jarC:
+ * META-INF/fonts.mf
+ * META-INF/fonts/Company-corporate.ttf
+ * META-INF/fonts/kidpr.ttf
+ * META-INF/services/com.message.spi.MessageService
+ * my/impl/StandardMessageService.java
+ *
+ * 2) Build three jar files a.jar, b.jar, c.jar
+ *
+ * 3) Create an index in a.jar (jar -i a.jar b.jar c.jar)
+ * with sun.misc.JarIndex.metaInfFilenames=true
+ *
+ * 4) Start a HTTP server serving out the three jars.
+ *
+ * The test then tries to locate services/resources within the jars using
+ * URLClassLoader. Each request to the HTTP server is recorded to ensure
+ * only the correct amount of requests are being made.
+ *
+ * Note: Needs jdk/lib/tools.jar in the classpath to compile and run.
+ */
+
+public class Basic {
+ static final String slash = File.separator;
+ static final String[] testSources = {
+ "jarA" + slash + "a" + slash + "A.java",
+ "jarA" + slash + "com" + slash + "message" + slash + "spi" + slash + "MessageService.java",
+ "jarB" + slash + "b" + slash + "B.java",
+ "jarC" + slash + "my" + slash + "impl" + slash + "StandardMessageService.java"};
+
+ static final String testSrc = System.getProperty("test.src");
+ static final String testSrcDir = testSrc != null ? testSrc : ".";
+ static final String testClasses = System.getProperty("test.classes");
+ static final String testClassesDir = testClasses != null ? testClasses : ".";
+
+ static JarHttpServer httpServer;
+
+ public static void main(String[] args) throws Exception {
+
+ // Set global url cache to false so that we can track every jar request.
+ (new URL("http://localhost/")).openConnection().setDefaultUseCaches(false);
+
+ buildTest();
+
+ try {
+ httpServer = new JarHttpServer(testClassesDir);
+ httpServer.start();
+
+ doTest(httpServer.getAddress());
+
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } finally {
+ if (httpServer != null) { httpServer.stop(2); }
+ }
+ }
+
+ static void buildTest() {
+ /* compile the source that will be used to generate the jars */
+ for (int i=0; i<testSources.length; i++)
+ testSources[i] = testSrcDir + slash + testSources[i];
+
+ compile("-d" , testClassesDir,
+ "-sourcepath", testSrcDir,
+ testSources[0], testSources[1], testSources[2], testSources[3]);
+
+ /* build the 3 jar files */
+ jar("-cf", testClassesDir + slash + "a.jar",
+ "-C", testClassesDir, "a",
+ "-C", testClassesDir, "com",
+ "-C", testSrcDir + slash + "jarA", "META-INF");
+ jar("-cf", testClassesDir + slash + "b.jar",
+ "-C", testClassesDir, "b",
+ "-C", testSrcDir + slash + "jarB", "META-INF");
+ jar("-cf", testClassesDir + slash + "c.jar",
+ "-C", testClassesDir, "my",
+ "-C", testSrcDir + slash + "jarC", "META-INF");
+
+ /* Create an index in a.jar for b.jar and c.jar */
+ createIndex(testClassesDir);
+ }
+
+ /* run jar <args> */
+ static void jar(String... args) {
+ debug("Running: jar " + Arrays.toString(args));
+ sun.tools.jar.Main jar = new sun.tools.jar.Main(System.out, System.err, "jar");
+ if (!jar.run(args)) {
+ throw new RuntimeException("jar failed: args=" + Arrays.toString(args));
+ }
+ }
+
+ /* run javac <args> */
+ static void compile(String... args) {
+ debug("Running: javac " + Arrays.toString(args));
+ com.sun.tools.javac.main.Main compiler = new com.sun.tools.javac.main.Main("javac");
+ if (compiler.compile(args) != 0) {
+ throw new RuntimeException("javac failed: args=" + Arrays.toString(args));
+ }
+ }
+
+ static String jar;
+ static {
+ String javaHome = System.getProperty("java.home");
+ if (javaHome.endsWith("jre")) {
+ int index = javaHome.lastIndexOf(slash);
+ if (index != -1)
+ javaHome = javaHome.substring(0, index);
+ }
+
+ jar = javaHome + slash+ "bin" + slash + "jar";
+ }
+
+ /* create the index */
+ static void createIndex(String workingDir) {
+ // ProcessBuilder is used so that the current directory can be set
+ // to the directory that directly contains the jars.
+ debug("Running jar to create the index");
+ ProcessBuilder pb = new ProcessBuilder(
+ jar, "-J-Dsun.misc.JarIndex.metaInfFilenames=true", "-i", "a.jar", "b.jar", "c.jar");
+ pb.directory(new File(workingDir));
+ //pd.inheritIO();
+ try {
+ Process p = pb.start();
+ if(p.waitFor() != 0)
+ throw new RuntimeException("jar indexing failed");
+
+ if(debug && p != null) {
+ String line = null;
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(p.getInputStream()));
+ while((line = reader.readLine()) != null)
+ debug(line);
+ reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
+ while((line = reader.readLine()) != null)
+ debug(line);
+ }
+ } catch(InterruptedException ie) { throw new RuntimeException(ie);
+ } catch(IOException e) { throw new RuntimeException(e); }
+ }
+
+ static final boolean debug = true;
+
+ static void debug(Object message) { if (debug) System.out.println(message); }
+
+ /* service define in c.jar */
+ static final String messageService = "com.message.spi.MessageService";
+
+ /* a service that is not defined in any of the jars */
+ static final String unknownService = "java.lang.Object";
+
+ static void doTest(InetSocketAddress serverAddress) throws IOException {
+ URL baseURL = new URL("http://localhost:" + serverAddress.getPort() + "/");
+
+ int failed = 0;
+
+ // Tests using sun.misc.Service
+ if (!sunMiscServiceTest(baseURL, messageService, true, false, true)) {
+ System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");
+ failed++;
+ }
+ if (!sunMiscServiceTest(baseURL, unknownService, false, false, false)) {
+ System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");
+ failed++;
+ }
+
+ // Tests using java.util.SerivceLoader
+ if (!javaUtilServiceLoaderTest(baseURL, messageService, true, false, true)) {
+ System.out.println("Test: sun.misc.Service looking for " + messageService + ", failed");
+ failed++;
+ }
+ if (!javaUtilServiceLoaderTest(baseURL, unknownService, false, false, false)) {
+ System.out.println("Test: sun.misc.Service looking for " + unknownService + " failed");
+ failed++;
+ }
+
+ // Tests using java.lang.Class (similar to the FontManager in javafx)
+ if (!klassLoader(baseURL, "/META-INF/fonts.mf", true, false, true)) {
+ System.out.println("Test: klassLoader looking for /META-INF/fonts.mf failed");
+ failed++;
+ }
+ if (!klassLoader(baseURL, "/META-INF/unknown.mf", false, false, false)) {
+ System.out.println("Test: klassLoader looking for /META-INF/unknown.mf failed");
+ failed++;
+ }
+
+ if (failed > 0)
+ throw new RuntimeException("Failed: " + failed + " tests");
+ }
+
+ static boolean sunMiscServiceTest(URL baseURL,
+ String serviceClass,
+ boolean expectToFind,
+ boolean expectbDotJar,
+ boolean expectcDotJar) throws IOException {
+ debug("----------------------------------");
+ debug("Running test with sun.misc.Service looking for " + serviceClass);
+ URLClassLoader loader = getLoader(baseURL);
+ httpServer.reset();
+
+ Class messageServiceClass = null;
+ try {
+ messageServiceClass = loader.loadClass(serviceClass);
+ } catch (ClassNotFoundException cnfe) {
+ System.err.println(cnfe);
+ throw new RuntimeException("Error in test: " + cnfe);
+ }
+
+ Iterator<Class<?>> iterator = sun.misc.Service.providers(messageServiceClass, loader);
+ if (expectToFind && !iterator.hasNext()) {
+ debug(messageServiceClass + " NOT found.");
+ return false;
+ }
+
+ while (iterator.hasNext()) {
+ debug("found " + iterator.next() + " " + messageService);
+ }
+
+ debug("HttpServer: " + httpServer);
+
+ if (!expectbDotJar && httpServer.bDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for b.jar");
+ return false;
+ }
+ if (!expectcDotJar && httpServer.cDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for c.jar");
+ return false;
+ }
+
+ return true;
+ }
+
+ static boolean javaUtilServiceLoaderTest(URL baseURL,
+ String serviceClass,
+ boolean expectToFind,
+ boolean expectbDotJar,
+ boolean expectcDotJar) throws IOException {
+ debug("----------------------------------");
+ debug("Running test with java.util.ServiceLoader looking for " + serviceClass);
+ URLClassLoader loader = getLoader(baseURL);
+ httpServer.reset();
+
+ Class messageServiceClass = null;
+ try {
+ messageServiceClass = loader.loadClass(serviceClass);
+ } catch (ClassNotFoundException cnfe) {
+ System.err.println(cnfe);
+ throw new RuntimeException("Error in test: " + cnfe);
+ }
+
+ Iterator<Class<?>> iterator = (ServiceLoader.load(messageServiceClass, loader)).iterator();
+ if (expectToFind && !iterator.hasNext()) {
+ debug(messageServiceClass + " NOT found.");
+ return false;
+ }
+
+ while (iterator.hasNext()) {
+ debug("found " + iterator.next() + " " + messageService);
+ }
+
+ debug("HttpServer: " + httpServer);
+
+ if (!expectbDotJar && httpServer.bDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for b.jar");
+ return false;
+ }
+ if (!expectcDotJar && httpServer.cDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for c.jar");
+ return false;
+ }
+
+ return true;
+ }
+
+ /* Tries to find a resource in a similar way to the font manager in javafx
+ * com.sun.javafx.scene.text.FontManager */
+ static boolean klassLoader(URL baseURL,
+ String resource,
+ boolean expectToFind,
+ boolean expectbDotJar,
+ boolean expectcDotJar) throws IOException {
+ debug("----------------------------------");
+ debug("Running test looking for " + resource);
+ URLClassLoader loader = getLoader(baseURL);
+ httpServer.reset();
+
+ Class ADotAKlass = null;
+ try {
+ ADotAKlass = loader.loadClass("a.A");
+ } catch (ClassNotFoundException cnfe) {
+ System.err.println(cnfe);
+ throw new RuntimeException("Error in test: " + cnfe);
+ }
+
+ URL u = ADotAKlass.getResource(resource);
+ if (expectToFind && u == null) {
+ System.out.println("Expected to find " + resource + " but didn't");
+ return false;
+ }
+
+ debug("HttpServer: " + httpServer);
+
+ if (!expectbDotJar && httpServer.bDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for b.jar");
+ return false;
+ }
+ if (!expectcDotJar && httpServer.cDotJar > 0) {
+ debug("Unexpeced request sent to the httpserver for c.jar");
+ return false;
+ }
+
+ return true;
+ }
+
+ static URLClassLoader getLoader(URL baseURL) throws IOException {
+ ClassLoader loader = Basic.class.getClassLoader();
+
+ while (loader.getParent() != null)
+ loader = loader.getParent();
+
+ return new URLClassLoader( new URL[]{
+ new URL(baseURL, "a.jar"),
+ new URL(baseURL, "b.jar"),
+ new URL(baseURL, "c.jar")}, loader );
+ }
+
+ /**
+ * HTTP Server to server the jar files.
+ */
+ static class JarHttpServer implements HttpHandler {
+ final String docsDir;
+ final HttpServer httpServer;
+ int aDotJar, bDotJar, cDotJar;
+
+ JarHttpServer(String docsDir) throws IOException {
+ this.docsDir = docsDir;
+
+ httpServer = HttpServer.create(new InetSocketAddress(0), 0);
+ httpServer.createContext("/", this);
+ }
+
+ void start() throws IOException {
+ httpServer.start();
+ }
+
+ void stop(int delay) {
+ httpServer.stop(delay);
+ }
+
+ InetSocketAddress getAddress() {
+ return httpServer.getAddress();
+ }
+
+ void reset() {
+ aDotJar = bDotJar = cDotJar = 0;
+ }
+
+ @Override
+ public String toString() {
+ return "aDotJar=" + aDotJar + ", bDotJar=" + bDotJar + ", cDotJar=" + cDotJar;
+ }
+
+ public void handle(HttpExchange t) throws IOException {
+ InputStream is = t.getRequestBody();
+ Headers map = t.getRequestHeaders();
+ Headers rmap = t.getResponseHeaders();
+ URI uri = t.getRequestURI();
+
+ debug("Server: received request for " + uri);
+ String path = uri.getPath();
+ if (path.endsWith("a.jar"))
+ aDotJar++;
+ else if (path.endsWith("b.jar"))
+ bDotJar++;
+ else if (path.endsWith("c.jar"))
+ cDotJar++;
+ else
+ System.out.println("Unexpected resource request" + path);
+
+ while (is.read() != -1);
+ is.close();
+
+ File file = new File(docsDir, path);
+ if (!file.exists())
+ throw new RuntimeException("Error: request for " + file);
+ long clen = file.length();
+ t.sendResponseHeaders (200, clen);
+ OutputStream os = t.getResponseBody();
+ FileInputStream fis = new FileInputStream(file);
+ try {
+ byte[] buf = new byte [16 * 1024];
+ int len;
+ while ((len=fis.read(buf)) != -1) {
+ os.write (buf, 0, len);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ fis.close();
+ os.close();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarA/META-INF/services/my.happy.land Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+# The contents of this file do not matter. It exists
+# simply to have a service defined in META-INF/services.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarA/a/A.java Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package a;
+
+public class A {
+ public static void hello() throws Exception {
+ System.out.println("Hello from a.A");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarA/com/message/spi/MessageService.java Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.message.spi;
+
+public interface MessageService {
+ String message();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarB/META-INF/JAVA2.DS Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+# The contents of this file do not matter. It exists
+# simply to have a file under META-INF.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarB/META-INF/services/no.name.service Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+# The contents of this file do not matter. It exists
+# simply to have a service defined in META-INF/services.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarB/b/B.java Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package b;
+
+public class B {
+ public static void hello() {
+ System.out.println("Hello from b.B");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/fonts.mf Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,23 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+corporate=/fonts/Company-corporate.ttf
+crazy-looking=/fonts/kidpr.ttf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/fonts/Company-corporate.ttf Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+This is not a real font.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/fonts/kidpr.ttf Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+This is not a real font.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/META-INF/services/com.message.spi.MessageService Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,22 @@
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+my.impl.StandardMessageService
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/jarC/my/impl/StandardMessageService.java Thu Feb 03 11:56:56 2011 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package my.impl;
+
+public class StandardMessageService implements com.message.spi.MessageService {
+ @Override
+ public String message() {
+ return "This is a message from the standard message service";
+ }
+}