/* * (C) Copyright 2005, 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 org.nuxeo.runtime.osgi.util.jar.index; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; /** * 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/ * # management-agent.jar * ! 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); } PrintStream out = null; try { out = new PrintStream(new FileOutputStream(args[1])); } catch (FileNotFoundException fnfe) { System.err.println("FileNotFoundException occurred"); System.exit(2); } try { build(out, Arrays.copyOfRange(args, 2, args.length)); } finally { out.close(); } } public static void build(PrintStream out, String... args) throws IOException { 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 = 0; 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 (Iterator<String> iter = index.iterator(); iter.hasNext();) { out.println(iter.next()); } } out.flush(); } 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); } }