8068686: Remove meta-index support
authorchegar
Wed, 17 Feb 2016 11:45:46 +0000
changeset 36000 86257b272c96
parent 35999 b6bf26e04451
child 36001 5f0acf0668e0
8068686: Remove meta-index support Reviewed-by: alanb, erikj, mchung
jdk/make/Tools.gmk
jdk/make/src/classes/build/tools/buildmetaindex/BuildMetaIndex.java
jdk/src/java.base/share/classes/sun/misc/JarIndex.java
jdk/src/java.base/share/classes/sun/misc/Launcher.java
jdk/src/java.base/share/classes/sun/misc/MetaIndex.java
jdk/src/java.base/share/classes/sun/misc/URLClassPath.java
--- a/jdk/make/Tools.gmk	Wed Feb 17 11:23:48 2016 +0800
+++ b/jdk/make/Tools.gmk	Wed Feb 17 11:45:46 2016 +0000
@@ -41,10 +41,6 @@
 TOOL_ADDJSUM = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
     build.tools.addjsum.AddJsum
 
-# The buildmetaindex tool creates a meta-index to make core class loaders lazier.
-TOOL_BUILDMETAINDEX = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
-    build.tools.buildmetaindex.BuildMetaIndex
-
 TOOL_COMPILEFONTCONFIG = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
     build.tools.compilefontconfig.CompileFontConfig
 
--- a/jdk/make/src/classes/build/tools/buildmetaindex/BuildMetaIndex.java	Wed Feb 17 11:23:48 2016 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,398 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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 build.tools.buildmetaindex;
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-/** Constructs a meta-index of the specified jar files. The meta-index
-    contains prefixes of packages contained in these jars, indexed by
-    the jar file name. It is intended to be consumed by the JVM to
-    allow the boot class loader to be made lazier. For example, when
-    class data sharing is enabled, the presence of the meta-index
-    allows the JVM to skip opening rt.jar if all of the dependent
-    classes of the application are in the shared archive. A similar
-    mechanism could be useful at the application level as well, for
-    example to make the extension class loader lazier.
-
-    <p> The contents of the meta-index file for jre/lib look something
-    like this:
-
-    <PRE>
-% VERSION 2
-# charsets.jar
-sun/
-# jce.jar
-javax/
-! jsse.jar
-sun/
-com/sun/net/
-javax/
-com/sun/security/
-! rt.jar
-org/w3c/
-com/sun/image/
-com/sun/org/
-com/sun/imageio/
-com/sun/accessibility/
-javax/
-...
-    </PRE>
-
-    <p> It is a current invariant of the code in the JVM which
-    consumes the meta-index that the meta-index indexes only jars in
-    one directory. It is acceptable for jars in that directory to not
-    be mentioned in the meta-index. The meta-index is designed more to
-    be able to perform a quick rejection test of the presence of a
-    particular class in a particular jar file than to be a precise
-    index of the contents of the jar.  */
-
-public class BuildMetaIndex {
-    public static void main(String[] args) throws IOException {
-        /* The correct usage of this class is as following:
-         * java BuildMetaIndex -o <meta-index> <a list of jar files>
-         * So the argument length should be at least 3 and the first argument should
-         * be '-o'.
-         */
-        if (args.length < 3 ||
-            !args[0].equals("-o")) {
-            printUsage();
-            System.exit(1);
-        }
-
-        try {
-            PrintStream out = new PrintStream(new FileOutputStream(args[1]));
-            out.println("% VERSION 2");
-            out.println("% WARNING: this file is auto-generated; do not edit");
-            out.println("% UNSUPPORTED: this file and its format may change and/or");
-            out.println("%   may be removed in a future release");
-            for (int i = 2; i < args.length; i++) {
-                String filename = args[i];
-                JarMetaIndex jmi = new JarMetaIndex(filename);
-                HashSet<String> index = jmi.getMetaIndex();
-                if (index == null) {
-                    continue;
-                }
-                /*
-                 * meta-index file plays different role in JVM and JDK side.
-                 * On the JVM side, meta-index file is used to speed up locating the
-                 * class files only while on the JDK side, meta-index file is used to speed
-                 * up the resources file and class file.
-                 * To help the JVM and JDK code to better utilize the information in meta-index
-                 * file, we mark the jar file differently. Here is the current rule we use (See
-                 * JarFileKind.getMarkChar() method. )
-                 * For jar file containing only class file, we put '!' before the jar file name;
-                 * for jar file containing only resources file, we put '@' before the jar file name;
-                 * for jar file containing both resources and class file, we put '#' before the jar name.
-                 * Notice the fact that every jar file contains at least the manifest file, so when
-                 * we say "jar file containing only class file", we don't include that file.
-                 */
-
-                out.println(jmi.getJarFileKind().getMarkerChar() + " " + filename);
-                for (String entry : index) {
-                    out.println(entry);
-                }
-
-            }
-            out.flush();
-            out.close();
-        } catch (FileNotFoundException fnfe) {
-            System.err.println("FileNotFoundException occurred");
-            System.exit(2);
-        }
-    }
-
-    private static void printUsage() {
-        String usage =
-            "BuildMetaIndex is used to generate a meta index file for the jar files\n" +
-            "you specified. The following is its usage:\n" +
-            " java BuildMetaIndex -o <the output meta index file> <a list of jar files> \n" +
-            " You can specify *.jar to refer to all the jar files in the current directory";
-
-        System.err.println(usage);
-    }
-}
-
-enum JarFileKind {
-
-    CLASSONLY ('!'),
-    RESOURCEONLY ('@'),
-    MIXED ('#');
-
-    private char markerChar;
-
-    JarFileKind(char markerChar) {
-        this.markerChar = markerChar;
-    }
-
-    public char getMarkerChar() {
-        return markerChar;
-    }
-}
-
-/*
- * JarMetaIndex associates the jar file with a set of what so called
- * "meta-index" of the jar file. Essentially, the meta-index is a list
- * of class prefixes and the plain files contained in META-INF directory (
- * not include the manifest file itself). This will help sun.misc.URLClassPath
- * to quickly locate the resource file and hotspot VM to locate the class file.
- *
- */
-class JarMetaIndex {
-    private JarFile jar;
-    private volatile HashSet<String> indexSet;
-
-    /*
-     * A hashmap contains a mapping from the prefix string to
-     * a hashset which contains a set of the second level of prefix string.
-     */
-    private HashMap<String, HashSet<String>> knownPrefixMap = new HashMap<>();
-
-    /**
-     * Special value for the HashSet to indicate that there are classes in
-     * the top-level package.
-     */
-    private static final String TOP_LEVEL = "TOP";
-
-    /*
-     * A class for mapping package prefixes to the number of
-     * levels of package elements to include.
-     */
-    static class ExtraLevel {
-        public ExtraLevel(String prefix, int levels) {
-            this.prefix = prefix;
-            this.levels = levels;
-        }
-        String prefix;
-        int levels;
-    }
-
-    /*
-     * A list of the special-cased package names.
-     */
-    private static ArrayList<ExtraLevel> extraLevels = new ArrayList<>();
-
-    static {
-        // The order of these statements is significant,
-        // since we stop looking after the first match.
-
-        // Need more precise information to disambiguate
-        // (illegal) references from applications to
-        // obsolete backported collections classes in
-        // com/sun/java/util
-        extraLevels.add(new ExtraLevel("com/sun/java/util/", Integer.MAX_VALUE));
-        extraLevels.add(new ExtraLevel("com/sun/java/", 4));
-        // Need more information than just first two package
-        // name elements to determine that classes in
-        // deploy.jar are not in rt.jar
-        extraLevels.add(new ExtraLevel("com/sun/", 3));
-        // Need to make sure things in jfr.jar aren't
-        // confused with other com/oracle/** packages
-        extraLevels.add(new ExtraLevel("com/oracle/jrockit", 3));
-    }
-
-
-    /*
-     * We add maximum 5 second level entries to "sun", "jdk", "java" and
-     * "javax" entries. Tune this parameter to get a balance on the
-     * cold start and footprint.
-     */
-    private static final int MAX_PKGS_WITH_KNOWN_PREFIX = 5;
-
-    private JarFileKind jarFileKind;
-
-    JarMetaIndex(String fileName) throws IOException {
-        jar = new JarFile(fileName);
-        knownPrefixMap.put("sun", new HashSet<String>());
-        knownPrefixMap.put("jdk", new HashSet<String>());
-        knownPrefixMap.put("java", new HashSet<String>());
-        knownPrefixMap.put("javax", new HashSet<String>());
-    }
-
-    /* Returns a HashSet contains the meta index string. */
-    HashSet<String> getMetaIndex() {
-        if (indexSet == null) {
-            synchronized(this) {
-                if (indexSet == null) {
-                    indexSet = new HashSet<>();
-                    Enumeration<JarEntry> entries = jar.entries();
-                    boolean containsOnlyClass = true;
-                    boolean containsOnlyResource = true;
-                    while (entries.hasMoreElements()) {
-                        JarEntry entry = entries.nextElement();
-                        String name = entry.getName();
-                        /* We only look at the non-directory entry.
-                           MANIFEST file is also skipped. */
-                        if (entry.isDirectory()
-                            || name.equals("META-INF/MANIFEST.MF")) {
-                            continue;
-                        }
-
-                        /* Once containsOnlyResource or containsOnlyClass
-                           turns to false, no need to check the entry type.
-                        */
-                        if (containsOnlyResource || containsOnlyClass) {
-                            if (name.endsWith(".class")) {
-                                containsOnlyResource = false;
-                            } else {
-                                containsOnlyClass = false;
-                            }
-                        }
-
-                        /* Add the full-qualified name of plain files under
-                           META-INF directory to the indexSet.
-                         */
-                        if (name.startsWith("META-INF")) {
-                            indexSet.add(name);
-                            continue;
-                        }
-
-                        /* Add the prefix name to the knownPrefixMap if the
-                           name starts with any string in the knownPrefix list.
-                        */
-                        if (isPrefixKnown(name)) {
-                            continue;
-                        }
-
-                        String[] pkgElements = name.split("/");
-                        // Last one is the class name; definitely ignoring that
-                        if (pkgElements.length > 2) {
-                            String meta = "";
-
-                            // Default is 2 levels of package elements
-                            int levels = 2;
-
-                            // But for some packages we add more elements
-                            for(ExtraLevel el : extraLevels) {
-                                if (name.startsWith(el.prefix)) {
-                                    levels = el.levels;
-                                    break;
-                                }
-                            }
-                            for (int i = 0; i < levels && i < pkgElements.length - 1; i++) {
-                                meta += pkgElements[i] + "/";
-                            }
-
-                            if (!meta.equals("")) {
-                                indexSet.add(meta);
-                            }
-                        }
-
-                    } // end of "while" loop;
-
-                    // Add the second level package names to the indexSet for
-                    // the predefined names such as "sun", "java" and "javax".
-                    addKnownPrefix();
-
-                    /* Set "jarFileKind" attribute. */
-                    if (containsOnlyClass) {
-                        jarFileKind = JarFileKind.CLASSONLY;
-                    } else if (containsOnlyResource) {
-                        jarFileKind = JarFileKind.RESOURCEONLY;
-                    } else {
-                        jarFileKind = JarFileKind.MIXED;
-                    }
-                }
-            }
-        }
-        return indexSet;
-    }
-
-    /*
-     * Checks to see whether the name starts with a string which is in the predefined
-     * list. If it is among one of the predefined prefixes, add it to the knowPrefixMap
-     * and returns true, otherwise, returns false.
-     * Returns true if the name is in a predefined prefix list. Otherwise, returns false.
-     */
-    boolean isPrefixKnown(String name) {
-        int firstSlashIndex = name.indexOf("/");
-        if (firstSlashIndex == -1) {
-            return false;
-        }
-
-        String firstPkgElement = name.substring(0, firstSlashIndex);
-        HashSet<String> pkgSet = knownPrefixMap.get(firstPkgElement);
-
-        /* The name does not starts with "sun", "java" or "javax". */
-        if (pkgSet == null) {
-            return false;
-        }
-
-        /* Add the second level package name to the corresponding hashset. */
-        int secondSlashIndex = name.indexOf("/", firstSlashIndex+1);
-        if (secondSlashIndex == -1) {
-            pkgSet.add(TOP_LEVEL);
-        } else {
-            String secondPkgElement = name.substring(firstSlashIndex+1, secondSlashIndex);
-            pkgSet.add(secondPkgElement);
-        }
-
-        return true;
-    }
-
-    /*
-     * Adds all the second level package elements for "sun", "java" and "javax"
-     * if the corresponding jar file does not contain more than
-     * MAX_PKGS_WITH_KNOWN_PREFIX such entries.
-     */
-    void addKnownPrefix() {
-        if (indexSet == null) {
-            return;
-        }
-
-        /* Iterate through the hash map, add the second level package names
-         * to the indexSet if has any.
-         */
-        for (String key : knownPrefixMap.keySet()) {
-            HashSet<String> pkgSetStartsWithKey = knownPrefixMap.get(key);
-            int setSize = pkgSetStartsWithKey.size();
-
-            if (setSize == 0) {
-                continue;
-            }
-            if (setSize > JarMetaIndex.MAX_PKGS_WITH_KNOWN_PREFIX ||
-                pkgSetStartsWithKey.contains(TOP_LEVEL)) {
-                 indexSet.add(key + "/");
-            } else {
-                /* If the set contains less than MAX_PKGS_WITH_KNOWN_PREFIX, add
-                 * them to the indexSet of the MetaIndex object.
-                 */
-                for (String secondPkgElement : pkgSetStartsWithKey) {
-                    indexSet.add(key + "/" + secondPkgElement);
-                }
-            }
-        } // end the outer "for"
-    }
-
-    JarFileKind getJarFileKind() {
-        // Build meta index if it hasn't.
-        if (indexSet == null) {
-            indexSet = getMetaIndex();
-        }
-        return jarFileKind;
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/JarIndex.java	Wed Feb 17 11:23:48 2016 +0800
+++ b/jdk/src/java.base/share/classes/sun/misc/JarIndex.java	Wed Feb 17 11:45:46 2016 +0000
@@ -106,31 +106,11 @@
     /**
      * Returns the jar index, or <code>null</code> if none.
      *
-     * This single parameter version of the method is retained
-     * for binary compatibility with earlier releases.
-     *
      * @param jar the JAR file to get the index from.
      * @exception IOException if an I/O error has occurred.
      */
     public static JarIndex getJarIndex(JarFile jar) throws IOException {
-        return getJarIndex(jar, null);
-    }
-
-    /**
-     * Returns the jar index, or <code>null</code> if none.
-     *
-     * @param jar the JAR file to get the index from.
-     * @exception IOException if an I/O error has occurred.
-     */
-    public static JarIndex getJarIndex(JarFile jar, MetaIndex metaIndex) throws IOException {
         JarIndex index = null;
-        /* If metaIndex is not null, check the meta index to see
-           if META-INF/INDEX.LIST is contained in jar file or not.
-        */
-        if (metaIndex != null &&
-            !metaIndex.mayContain(INDEX_NAME)) {
-            return null;
-        }
         JarEntry e = jar.getJarEntry(INDEX_NAME);
         // if found, then load the index
         if (e != null) {
--- a/jdk/src/java.base/share/classes/sun/misc/Launcher.java	Wed Feb 17 11:23:48 2016 +0800
+++ b/jdk/src/java.base/share/classes/sun/misc/Launcher.java	Wed Feb 17 11:45:46 2016 +0000
@@ -319,21 +319,7 @@
                             if (bootClassPath == null)
                                 return new URL[0];
                             // Skip empty path in boot class path i.e. not default to use CWD
-                            File[] classPath = getClassPath(bootClassPath, false);
-                            int len = classPath.length;
-                            Set<File> seenDirs = new HashSet<File>();
-                            for (int i = 0; i < len; i++) {
-                                File curEntry = classPath[i];
-                                // Negative test used to properly handle
-                                // nonexistent jars on boot class path
-                                if (!curEntry.isDirectory()) {
-                                    curEntry = curEntry.getParentFile();
-                                }
-                                if (curEntry != null && seenDirs.add(curEntry)) {
-                                    MetaIndex.registerDirectory(curEntry);
-                                }
-                            }
-                            return pathToURLs(classPath);
+                            return pathToURLs(getClassPath(bootClassPath, false));
                         }
                     }
                 );
--- a/jdk/src/java.base/share/classes/sun/misc/MetaIndex.java	Wed Feb 17 11:23:48 2016 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +0,0 @@
-/*
- * Copyright (c) 2005, 2012, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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 sun.misc;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/*
- * MetaIndex is intended to decrease startup time (in particular cold
- * start, when files are not yet in the disk cache) by providing a
- * quick reject mechanism for probes into jar files. The on-disk
- * representation of the meta-index is a flat text file with per-jar
- * entries indicating (generally speaking) prefixes of package names
- * contained in the jar. As an example, here is an edited excerpt of
- * the meta-index generated for jre/lib in the current build:
- *
-<PRE>
-% VERSION 1
-# charsets.jar
-sun/
-# jce.jar
-javax/
-! jsse.jar
-sun/
-com/sun/net/
-javax/
-com/sun/security/
-@ resources.jar
-com/sun/xml/
-com/sun/rowset/
-com/sun/org/
-sun/
-com/sun/imageio/
-javax/
-com/sun/java/swing/
-META-INF/services/
-com/sun/java/util/jar/pack/
-com/sun/corba/
-com/sun/jndi/
-! rt.jar
-org/w3c/
-com/sun/imageio/
-javax/
-java/
-sun/
-...
-</PRE>
- * <p> A few notes about the design of the meta-index:
- *
- * <UL>
- *
- * <LI> It contains entries for multiple jar files. This is
- * intentional, to reduce the number of disk accesses that need to be
- * performed during startup.
- *
- * <LI> It is only intended to act as a fast reject mechanism to
- * prevent application and other classes from forcing all jar files on
- * the boot and extension class paths to be opened. It is not intended
- * as a precise index of the contents of the jar.
- *
- * <LI> It should be as small as possible to reduce the amount of time
- * required to parse it during startup. For example, adding on the
- * secondary package element to java/ and javax/ packages
- * ("javax/swing/", for example) causes the meta-index to grow
- * significantly. This is why substrings of the packages have been
- * chosen as the principal contents.
- *
- * <LI> It is versioned, and optional, to prevent strong dependencies
- * between the JVM and JDK. It is also potentially applicable to more
- * than just the boot and extension class paths.
- *
- * <LI> Precisely speaking, it plays different role in JVM and J2SE
- * side.  On the JVM side, meta-index file is used to speed up locating the
- * class files only while on the J2SE side, meta-index file is used to speed
- * up the resources file & class file.
- * To help the JVM and J2SE code to better utilize the information in meta-index
- * file, we mark the jar file differently. Here is the current rule we use.
- * For jar file containing only class file, we put '!' before the jar file name;
- * for jar file containing only resources file, we put '@' before the jar file name;
- * for jar file containing both resources and class file, we put '#' before the
- * jar name.
- * Notice the fact that every jar file contains at least the manifest file, so when
- * we say "jar file containing only class file", we don't include that file.
- *
- * </UL>
- *
- * <p> To avoid changing the behavior of the current application
- * loader and other loaders, the current MetaIndex implementation in
- * the JDK requires that the directory containing the meta-index be
- * registered with the MetaIndex class before construction of the
- * associated URLClassPath. This prevents the need for automatic
- * searching for the meta-index in the URLClassPath code and potential
- * changes in behavior for non-core ClassLoaders.
- *
- * This class depends on make/tools/MetaIndex/BuildMetaIndex.java and
- * is used principally by sun.misc.URLClassPath.
- */
-
-public class MetaIndex {
-    // Maps jar file names in registered directories to meta-indices
-    private static volatile Map<File, MetaIndex> jarMap;
-
-    // List of contents of this meta-index
-    private String[] contents;
-
-    // Indicate whether the coresponding jar file is a pure class jar file or not
-    private boolean isClassOnlyJar;
-
-    //----------------------------------------------------------------------
-    // Registration of directories (which can cause parsing of the
-    // meta-index file if it is present), and fetching of parsed
-    // meta-indices
-    // jarMap is not strictly thread-safe when the meta index mechanism
-    // is extended for user-provided jar files in future.
-
-    public static MetaIndex forJar(File jar) {
-        return getJarMap().get(jar);
-    }
-
-    // 'synchronized' is added to protect the jarMap from being modified
-    // by multiple threads.
-    public static synchronized void registerDirectory(File dir) {
-        // Note that this does not currently check to see whether the
-        // directory has previously been registered, since the meta-index
-        // in a particular directory creates multiple entries in the
-        // jarMap. If this mechanism is extended beyond the boot and
-        // extension class paths (for example, automatically searching for
-        // meta-index files in directories containing jars which have been
-        // explicitly opened) then this code should be generalized.
-        //
-        // This method must be called from a privileged context.
-        File indexFile = new File(dir, "meta-index");
-        if (indexFile.exists()) {
-            try {
-                BufferedReader reader = new BufferedReader(new FileReader(indexFile));
-                String line = null;
-                String curJarName = null;
-                boolean isCurJarContainClassOnly = false;
-                List<String> contents = new ArrayList<String>();
-                Map<File, MetaIndex> map = getJarMap();
-
-                /* Convert dir into canonical form. */
-                dir = dir.getCanonicalFile();
-                /* Note: The first line should contain the version of
-                 * the meta-index file. We have to match the right version
-                 * before trying to parse this file. */
-                line = reader.readLine();
-                if (line == null ||
-                    !line.equals("% VERSION 2")) {
-                    reader.close();
-                    return;
-                }
-                while ((line = reader.readLine()) != null) {
-                    switch (line.charAt(0)) {
-                    case '!':
-                    case '#':
-                    case '@': {
-                        // Store away current contents, if any
-                        if ((curJarName != null) && (contents.size() > 0)) {
-                            map.put(new File(dir, curJarName),
-                                    new MetaIndex(contents,
-                                                  isCurJarContainClassOnly));
-
-                            contents.clear();
-                        }
-                        // Fetch new current jar file name
-                        curJarName = line.substring(2);
-                        if (line.charAt(0) == '!') {
-                            isCurJarContainClassOnly = true;
-                        } else if (isCurJarContainClassOnly) {
-                            isCurJarContainClassOnly = false;
-                        }
-
-                        break;
-                    }
-                    case '%':
-                        break;
-                    default: {
-                        contents.add(line);
-                    }
-                    }
-                }
-                // Store away current contents, if any
-                if ((curJarName != null) && (contents.size() > 0)) {
-                    map.put(new File(dir, curJarName),
-                            new MetaIndex(contents, isCurJarContainClassOnly));
-                }
-
-                reader.close();
-
-            } catch (IOException e) {
-                // Silently fail for now (similar behavior to elsewhere in
-                // extension and core loaders)
-            }
-        }
-    }
-
-    //----------------------------------------------------------------------
-    // Public APIs
-    //
-
-    public boolean mayContain(String entry) {
-        // Ask non-class file from class only jar returns false
-        // This check is important to avoid some class only jar
-        // files such as rt.jar are opened for resource request.
-        if  (isClassOnlyJar && !entry.endsWith(".class")){
-            return false;
-        }
-
-        String[] conts = contents;
-        for (int i = 0; i < conts.length; i++) {
-            if (entry.startsWith(conts[i])) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    //----------------------------------------------------------------------
-    // Implementation only below this point
-    // @IllegalArgumentException if entries is null.
-    private MetaIndex(List<String> entries, boolean isClassOnlyJar)
-        throws IllegalArgumentException {
-        if (entries == null) {
-            throw new IllegalArgumentException();
-        }
-
-        contents = entries.toArray(new String[0]);
-        this.isClassOnlyJar = isClassOnlyJar;
-    }
-
-    private static Map<File, MetaIndex> getJarMap() {
-        if (jarMap == null) {
-            synchronized (MetaIndex.class) {
-                if (jarMap == null) {
-                    jarMap = new HashMap<File, MetaIndex>();
-                }
-            }
-        }
-        assert jarMap != null;
-        return jarMap;
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/URLClassPath.java	Wed Feb 17 11:23:48 2016 +0800
+++ b/jdk/src/java.base/share/classes/sun/misc/URLClassPath.java	Wed Feb 17 11:45:46 2016 +0000
@@ -620,7 +620,6 @@
         private JarFile jar;
         private URL csu;
         private JarIndex index;
-        private MetaIndex metaIndex;
         private URLStreamHandler handler;
         private HashMap<String, Loader> lmap;
         private boolean closed = false;
@@ -640,32 +639,7 @@
             handler = jarHandler;
             lmap = loaderMap;
 
-            if (!isOptimizable(url)) {
-                ensureOpen();
-            } else {
-                 String fileName = url.getFile();
-                if (fileName != null) {
-                    fileName = ParseUtil.decode(fileName);
-                    File f = new File(fileName);
-                    metaIndex = MetaIndex.forJar(f);
-                    // If the meta index is found but the file is not
-                    // installed, set metaIndex to null. A typical
-                    // senario is charsets.jar which won't be installed
-                    // when the user is running in certain locale environment.
-                    // The side effect of null metaIndex will cause
-                    // ensureOpen get called so that IOException is thrown.
-                    if (metaIndex != null && !f.exists()) {
-                        metaIndex = null;
-                    }
-                }
-
-                // metaIndex is null when either there is no such jar file
-                // entry recorded in meta-index file or such jar file is
-                // missing in JRE. See bug 6340399.
-                if (metaIndex == null) {
-                    ensureOpen();
-                }
-            }
+            ensureOpen();
         }
 
         @Override
@@ -699,7 +673,7 @@
                                 }
 
                                 jar = getJarFile(csu);
-                                index = JarIndex.getJarIndex(jar, metaIndex);
+                                index = JarIndex.getJarIndex(jar);
                                 if (index != null) {
                                     String[] jarfiles = index.getJarFiles();
                                 // Add all the dependent URLs to the lmap so that loaders
@@ -854,12 +828,6 @@
          * Returns the JAR Resource for the specified name.
          */
         Resource getResource(final String name, boolean check) {
-            if (metaIndex != null) {
-                if (!metaIndex.mayContain(name)) {
-                    return null;
-                }
-            }
-
             try {
                 ensureOpen();
             } catch (IOException e) {
@@ -1002,10 +970,6 @@
                 return null;
             }
 
-            if (metaIndex != null) {
-                return null;
-            }
-
             ensureOpen();
 
             if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary