2486N/A * Copyright (c) 2003,2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * Transforms a JAR file to or from a packed stream in Pack200 format. 0N/A * Please refer to Network Transfer Format JSR 200 Specification at 0N/A * Typically the packer engine is used by application developers 0N/A * to deploy or host JAR files on a website. 0N/A * The unpacker engine is used by deployment applications to 0N/A * transform the byte-stream back to JAR format. 0N/A * Here is an example using packer and unpacker:<p> 0N/A * import java.util.jar.Pack200; 0N/A * import java.util.jar.Pack200.*; 0N/A * // Create the Packer object 0N/A * Packer packer = Pack200.newPacker(); 0N/A * // Initialize the state by setting the desired properties 0N/A * // take more time choosing codings for better compression 0N/A * p.put(Packer.EFFORT, "7"); // default is "5" 0N/A * // use largest-possible archive segments (>10% better compression). 0N/A * p.put(Packer.SEGMENT_LIMIT, "-1"); 0N/A * // reorder files for better compression. 0N/A * p.put(Packer.KEEP_FILE_ORDER, Packer.FALSE); 0N/A * // smear modification times to a single value. 0N/A * p.put(Packer.MODIFICATION_TIME, Packer.LATEST); 0N/A * // ignore all JAR deflation requests, 0N/A * // transmitting a single request to use "store" mode. 0N/A * p.put(Packer.DEFLATE_HINT, Packer.FALSE); 0N/A * // discard debug attributes 0N/A * p.put(Packer.CODE_ATTRIBUTE_PFX+"LineNumberTable", Packer.STRIP); 0N/A * // throw an error if an attribute is unrecognized 0N/A * p.put(Packer.UNKNOWN_ATTRIBUTE, Packer.ERROR); 0N/A * // pass one class file uncompressed: 0N/A * // Call the packer 0N/A * packer.pack(jarFile, fos); 0N/A * JarOutputStream jostream = new JarOutputStream(fostream); 0N/A * Unpacker unpacker = Pack200.newUnpacker(); 0N/A * // Call the unpacker 0N/A * unpacker.unpack(f, jostream); 0N/A * // Must explicitly close the output. 0N/A * } catch (IOException ioe) { 0N/A * ioe.printStackTrace(); 0N/A * </pre></blockquote> 0N/A * A Pack200 file compressed with gzip can be hosted on HTTP/1.1 web servers. 0N/A * The deployment applications can use "Accept-Encoding=pack200-gzip". This 0N/A * indicates to the server that the client application desires a version of 0N/A * the file encoded with Pack200 and further compressed with gzip. Please 0N/A * Unless otherwise noted, passing a <tt>null</tt> argument to a constructor or 0N/A * method in this class will cause a {@link NullPointerException} to be thrown. 0N/A * @author Kumar Srinivasan 0N/A // Static methods of the Pack200 class. 0N/A * Obtain new instance of a class that implements Packer. 0N/A * <li><p>If the system property <tt>java.util.jar.Pack200.Packer</tt> 0N/A * is defined, then the value is taken to be the fully-qualified name 0N/A * of a concrete implementation class, which must implement Packer. 0N/A * This class is loaded and instantiated. If this process fails 0N/A * then an unspecified error is thrown.</p></li> 0N/A * <li><p>If an implementation has not been specified with the system 0N/A * property, then the system-default implementation class is instantiated, 0N/A * and the result is returned.</p></li> 0N/A * <p>Note: The returned object is not guaranteed to operate 0N/A * correctly if multiple threads use it at the same time. 0N/A * A multi-threaded application should either allocate multiple 0N/A * packer engines, or else serialize use of one engine with a lock. 0N/A * @return A newly allocated Packer engine. 0N/A * Obtain new instance of a class that implements Unpacker. 0N/A * <li><p>If the system property <tt>java.util.jar.Pack200.Unpacker</tt> 0N/A * is defined, then the value is taken to be the fully-qualified 0N/A * name of a concrete implementation class, which must implement Unpacker. 0N/A * The class is loaded and instantiated. If this process fails 0N/A * then an unspecified error is thrown.</p></li> 0N/A * <li><p>If an implementation has not been specified with the 0N/A * system property, then the system-default implementation class 0N/A * is instantiated, and the result is returned.</p></li> 0N/A * <p>Note: The returned object is not guaranteed to operate 0N/A * correctly if multiple threads use it at the same time. 0N/A * A multi-threaded application should either allocate multiple 0N/A * unpacker engines, or else serialize use of one engine with a lock. 0N/A * @return A newly allocated Unpacker engine. 0N/A * The packer engine applies various transformations to the input JAR file, 0N/A * making the pack stream highly compressible by a compressor such as 0N/A * gzip or zip. An instance of the engine can be obtained 0N/A * using {@link #newPacker}. 0N/A * The high degree of compression is achieved 0N/A * by using a number of techniques described in the JSR 200 specification. 0N/A * Some of the techniques are sorting, re-ordering and co-location of the 0N/A * The pack engine is initialized to an initial state as described 0N/A * by their properties below. 0N/A * The initial state can be manipulated by getting the 0N/A * engine properties (using {@link #properties}) and storing 0N/A * the modified properties on the map. 0N/A * The resource files will be passed through with no changes at all. 0N/A * The class files will not contain identical bytes, since the unpacker 0N/A * is free to change minor class file features such as constant pool order. 0N/A * However, the class files will be semantically identical, 4008N/A * <cite>The Java™ Virtual Machine Specification</cite>. 0N/A * By default, the packer does not change the order of JAR elements. 0N/A * Also, the modification time and deflation hint of each 0N/A * JAR element is passed unchanged. 0N/A * (Any other ZIP-archive information, such as extra attributes 0N/A * giving Unix file permissions, are lost.) 0N/A * Note that packing and unpacking a JAR will in general alter the 0N/A * bytewise contents of classfiles in the JAR. This means that packing 0N/A * and unpacking will in general invalidate any digital signatures 0N/A * which rely on bytewise images of JAR elements. In order both to sign 0N/A * and to pack a JAR, you must first pack and unpack the JAR to 0N/A * "normalize" it, then compute signatures on the unpacked JAR elements, 0N/A * and finally repack the signed JAR. 0N/A * Both packing steps should 0N/A * use precisely the same options, and the segment limit may also 0N/A * need to be set to "-1", to prevent accidental variation of segment 0N/A * boundaries as class file sizes change slightly. 0N/A * (Here's why this works: Any reordering the packer does 0N/A * of any classfile structures is idempotent, so the second packing 0N/A * does not change the orderings produced by the first packing. 0N/A * Also, the unpacker is guaranteed by the JSR 200 specification 0N/A * to produce a specific bytewise image for any given transmission 0N/A * ordering of archive elements.) 2498N/A * In order to maintain backward compatibility, the pack file's version is 2498N/A * set to accommodate the class files present in the input JAR file. In 2498N/A * other words, the pack file version will be the latest, if the class files 2498N/A * are the latest and conversely the pack file version will be the oldest 2498N/A * if the class file versions are also the oldest. For intermediate class 2498N/A * file versions the corresponding pack file version will be used. 2498N/A * If the input JAR-files are solely comprised of 1.5 (or lesser) 2498N/A * class files, a 1.5 compatible pack file is produced. This will also be 2498N/A * the case for archives that have no class files. 2498N/A * If the input JAR-files contains a 1.6 class file, then the pack file 2498N/A * version will be set to 1.6. 3042N/A * Note: Unless otherwise noted, passing a <tt>null</tt> argument to a 3042N/A * constructor or method in this class will cause a {@link NullPointerException} 0N/A * This property is a numeral giving the estimated target size N 0N/A * (in bytes) of each archive segment. 0N/A * If a single input file requires more than N bytes, 0N/A * it will be given its own archive segment. 0N/A * As a special case, a value of -1 will produce a single large 0N/A * segment with all input files, while a value of 0 will 0N/A * produce one segment for each class. 0N/A * Larger archive segments result in less fragmentation and 0N/A * better compression, but processing them requires more memory. 0N/A * The size of each segment is estimated by counting the size of each 0N/A * input file to be transmitted in the segment, along with the size 0N/A * of its name and other transmitted properties. 2486N/A * The default is -1, which means the packer will always create a single 2486N/A * segment output file. In cases where extremely large output files are 2486N/A * generated, users are strongly encouraged to use segmenting or break 2486N/A * up the input file into smaller JARs. 0N/A * A 10Mb JAR packed without this limit will 0N/A * typically pack about 10% smaller, but the packer may require 0N/A * a larger Java heap (about ten times the segment limit). 0N/A * If this property is set to {@link #TRUE}, the packer will transmit 0N/A * all elements in their original order within the source archive. 0N/A * If it is set to {@link #FALSE}, the packer may reorder elements, 0N/A * and also remove JAR directory entries, which carry no useful 0N/A * information for Java applications. 0N/A * (Typically this enables better compression.) 0N/A * The default is {@link #TRUE}, which preserves the input information, 0N/A * but may cause the transmitted archive to be larger than necessary. 0N/A * If this property is set to a single decimal digit, the packer will 0N/A * use the indicated amount of effort in compressing the archive. 0N/A * Level 1 may produce somewhat larger size and faster compression speed, 0N/A * while level 9 will take much longer but may produce better compression. 0N/A * The special value 0 instructs the packer to copy through the 0N/A * original JAR file directly, with no compression. The JSR 200 0N/A * standard requires any unpacker to understand this special case 0N/A * as a pass-through of the entire archive. 0N/A * The default is 5, investing a modest amount of time to 0N/A * produce reasonable compression. 0N/A * If this property is set to {@link #TRUE} or {@link #FALSE}, the packer 0N/A * will set the deflation hint accordingly in the output archive, and 0N/A * will not transmit the individual deflation hints of archive elements. 0N/A * If this property is set to the special string {@link #KEEP}, the packer 0N/A * will attempt to determine an independent deflation hint for each 0N/A * available element of the input archive, and transmit this hint separately. 0N/A * The default is {@link #KEEP}, which preserves the input information, 0N/A * but may cause the transmitted archive to be larger than necessary. 0N/A * It is up to the unpacker implementation 0N/A * to take action upon the hint to suitably compress the elements of 0N/A * the resulting unpacked jar. 0N/A * The deflation hint of a ZIP or JAR element indicates 0N/A * whether the element was deflated or stored directly. 0N/A * If this property is set to the special string {@link #LATEST}, 0N/A * the packer will attempt to determine the latest modification time, 0N/A * among all the available entries in the original archive or the latest 0N/A * modification time of all the available entries in each segment. 0N/A * This single value will be transmitted as part of the segment and applied 0N/A * to all the entries in each segment, {@link #SEGMENT_LIMIT}. 0N/A * This can marginally decrease the transmitted size of the 0N/A * archive, at the expense of setting all installed files to a single 0N/A * If this property is set to the special string {@link #KEEP}, 0N/A * the packer transmits a separate modification time for each input 0N/A * The default is {@link #KEEP}, which preserves the input information, 0N/A * but may cause the transmitted archive to be larger than necessary. 0N/A * It is up to the unpacker implementation to take action to suitably 0N/A * set the modification time of each element of its output file. 0N/A * @see #SEGMENT_LIMIT 0N/A * Indicates that a file should be passed through bytewise, with no 0N/A * compression. Multiple files may be specified by specifying 0N/A * additional properties with distinct strings appended, to 0N/A * make a family of properties with the common prefix. 0N/A * There is no pathname transformation, except 0N/A * that the system file separator is replaced by the JAR file 0N/A * The resulting file names must match exactly as strings with their 0N/A * occurrences in the JAR file. 0N/A * If a property value is a directory name, all files under that 0N/A * directory will be passed also. 0N/A * # Pass all files in an entire directory hierarchy: 0N/A * p.put(PASS_FILE_PFX+3, "police/"); 0N/A /// Attribute control. 0N/A * Indicates the action to take when a class-file containing an unknown 0N/A * attribute is encountered. Possible values are the strings {@link #ERROR}, 0N/A * {@link #STRIP}, and {@link #PASS}. 0N/A * The string {@link #ERROR} means that the pack operation 0N/A * as a whole will fail, with an exception of type <code>IOException</code>. 0N/A * {@link #STRIP} means that the attribute will be dropped. 0N/A * {@link #PASS} means that the whole class-file will be passed through 0N/A * (as if it were a resource file) without compression, with a suitable warning. 0N/A * This is the default value for this property. 0N/A * Map p = pack200.getProperties(); 0N/A * p.put(UNKNOWN_ATTRIBUTE, ERROR); 0N/A * p.put(UNKNOWN_ATTRIBUTE, STRIP); 0N/A * p.put(UNKNOWN_ATTRIBUTE, PASS); 0N/A * When concatenated with a class attribute name, 0N/A * indicates the format of that attribute, 0N/A * using the layout language specified in the JSR 200 specification. 0N/A * For example, the effect of this option is built in: 0N/A * <code>pack.class.attribute.SourceFile=RUH</code>. 0N/A * The special strings {@link #ERROR}, {@link #STRIP}, and {@link #PASS} are 0N/A * also allowed, with the same meaning as {@link #UNKNOWN_ATTRIBUTE}. 0N/A * This provides a way for users to request that specific attributes be 0N/A * refused, stripped, or passed bitwise (with no class compression). 0N/A * Code like this might be used to support attributes for JCOV: 0N/A * p.put(CODE_ATTRIBUTE_PFX+"CoverageTable", "NH[PHHII]"); 0N/A * p.put(CODE_ATTRIBUTE_PFX+"CharacterRangeTable", "NH[PHPOHIIH]"); 0N/A * p.put(CLASS_ATTRIBUTE_PFX+"SourceID", "RUH"); 0N/A * p.put(CLASS_ATTRIBUTE_PFX+"CompilationID", "RUH"); 0N/A * Code like this might be used to strip debugging attributes: 0N/A * p.put(CODE_ATTRIBUTE_PFX+"LineNumberTable", STRIP); 0N/A * p.put(CODE_ATTRIBUTE_PFX+"LocalVariableTable", STRIP); 0N/A * p.put(CLASS_ATTRIBUTE_PFX+"SourceFile", STRIP); 0N/A * When concatenated with a field attribute name, 0N/A * indicates the format of that attribute. 0N/A * For example, the effect of this option is built in: 0N/A * <code>pack.field.attribute.Deprecated=</code>. 0N/A * The special strings {@link #ERROR}, {@link #STRIP}, and 0N/A * {@link #PASS} are also allowed. 0N/A * @see #CLASS_ATTRIBUTE_PFX 0N/A * When concatenated with a method attribute name, 0N/A * indicates the format of that attribute. 0N/A * For example, the effect of this option is built in: 0N/A * <code>pack.method.attribute.Exceptions=NH[RCH]</code>. 0N/A * The special strings {@link #ERROR}, {@link #STRIP}, and {@link #PASS} 0N/A * @see #CLASS_ATTRIBUTE_PFX 0N/A * When concatenated with a code attribute name, 0N/A * indicates the format of that attribute. 0N/A * For example, the effect of this option is built in: 0N/A * <code>pack.code.attribute.LocalVariableTable=NH[PHOHRUHRSHH]</code>. 0N/A * The special strings {@link #ERROR}, {@link #STRIP}, and {@link #PASS} 0N/A * @see #CLASS_ATTRIBUTE_PFX 0N/A * The unpacker's progress as a percentage, as periodically 0N/A * updated by the unpacker. 0N/A * Values of 0 - 100 are normal, and -1 indicates a stall. 0N/A * Observe this property with a {@link PropertyChangeListener}. 0N/A * At a minimum, the unpacker must set progress to 0 0N/A * at the beginning of a packing operation, and to 100 0N/A * @see #addPropertyChangeListener 0N/A /** The string "keep", a possible value for certain properties. 0N/A * @see #DEFLATE_HINT 0N/A * @see #MODIFICATION_TIME 0N/A /** The string "pass", a possible value for certain properties. 0N/A * @see #UNKNOWN_ATTRIBUTE 0N/A * @see #CLASS_ATTRIBUTE_PFX 0N/A * @see #FIELD_ATTRIBUTE_PFX 0N/A * @see #METHOD_ATTRIBUTE_PFX 0N/A * @see #CODE_ATTRIBUTE_PFX 0N/A /** The string "strip", a possible value for certain properties. 0N/A * @see #UNKNOWN_ATTRIBUTE 0N/A * @see #CLASS_ATTRIBUTE_PFX 0N/A * @see #FIELD_ATTRIBUTE_PFX 0N/A * @see #METHOD_ATTRIBUTE_PFX 0N/A * @see #CODE_ATTRIBUTE_PFX 0N/A /** The string "error", a possible value for certain properties. 0N/A * @see #UNKNOWN_ATTRIBUTE 0N/A * @see #CLASS_ATTRIBUTE_PFX 0N/A * @see #FIELD_ATTRIBUTE_PFX 0N/A * @see #METHOD_ATTRIBUTE_PFX 0N/A * @see #CODE_ATTRIBUTE_PFX 0N/A /** The string "true", a possible value for certain properties. 0N/A * @see #KEEP_FILE_ORDER 0N/A * @see #DEFLATE_HINT 0N/A /** The string "false", a possible value for certain properties. 0N/A * @see #KEEP_FILE_ORDER 0N/A * @see #DEFLATE_HINT 0N/A /** The string "latest", a possible value for certain properties. 0N/A * @see #MODIFICATION_TIME 0N/A * Get the set of this engine's properties. 0N/A * This set is a "live view", so that changing its 0N/A * contents immediately affects the Packer engine, and 0N/A * changes from the engine (such as progress indications) 0N/A * are immediately visible in the map. 0N/A * <p>The property map may contain pre-defined implementation 0N/A * specific and default properties. Users are encouraged to 0N/A * read the information and fully understand the implications, 0N/A * before modifying pre-existing properties. 0N/A * Implementation specific properties are prefixed with a 0N/A * package name associated with the implementor, beginning 0N/A * with <tt>com.</tt> or a similar prefix. 0N/A * All property names beginning with <tt>pack.</tt> and 0N/A * <tt>unpack.</tt> are reserved for use by this API. 0N/A * Unknown properties may be ignored or rejected with an 0N/A * unspecified error, and invalid entries may cause an 0N/A * unspecified error to be thrown. 0N/A * The returned map implements all optional {@link SortedMap} operations 0N/A * @return A sorted association of property key strings to property 0N/A * Takes a JarFile and converts it into a Pack200 archive. 0N/A * Closes its input but not its output. (Pack200 archives are appendable.) 0N/A * @param in a JarFile 0N/A * @param out an OutputStream 0N/A * @exception IOException if an error is encountered. 0N/A * Takes a JarInputStream and converts it into a Pack200 archive. 0N/A * Closes its input but not its output. (Pack200 archives are appendable.) 0N/A * The modification time and deflation hint attributes are not available, 0N/A * for the JAR manifest file and its containing directory. 0N/A * @see #MODIFICATION_TIME 0N/A * @see #DEFLATE_HINT 0N/A * @param in a JarInputStream 0N/A * @param out an OutputStream 0N/A * @exception IOException if an error is encountered. 0N/A * Registers a listener for PropertyChange events on the properties map. 0N/A * This is typically used by applications to update a progress bar. 0N/A * @param listener An object to be invoked when a property is changed. 0N/A * Remove a listener for PropertyChange events, added by 0N/A * the {@link #addPropertyChangeListener}. 0N/A * @see #addPropertyChangeListener 0N/A * @param listener The PropertyChange listener to be removed. 0N/A * The unpacker engine converts the packed stream to a JAR file. 0N/A * An instance of the engine can be obtained 0N/A * using {@link #newUnpacker}. 0N/A * Every JAR file produced by this engine will include the string 0N/A * "<tt>PACK200</tt>" as a zip file comment. 0N/A * This allows a deployer to detect if a JAR archive was packed and unpacked. 3042N/A * Note: Unless otherwise noted, passing a <tt>null</tt> argument to a 3042N/A * constructor or method in this class will cause a {@link NullPointerException} 0N/A * This version of the unpacker is compatible with all previous versions. 0N/A /** The string "keep", a possible value for certain properties. 0N/A * @see #DEFLATE_HINT 0N/A /** The string "true", a possible value for certain properties. 0N/A * @see #DEFLATE_HINT 0N/A /** The string "false", a possible value for certain properties. 0N/A * @see #DEFLATE_HINT 0N/A * Property indicating that the unpacker should 0N/A * ignore all transmitted values for DEFLATE_HINT, 0N/A * replacing them by the given value, {@link #TRUE} or {@link #FALSE}. 0N/A * The default value is the special string {@link #KEEP}, 0N/A * which asks the unpacker to preserve all transmitted 0N/A * The unpacker's progress as a percentage, as periodically 0N/A * updated by the unpacker. 0N/A * Values of 0 - 100 are normal, and -1 indicates a stall. 0N/A * Observe this property with a {@link PropertyChangeListener}. 0N/A * At a minimum, the unpacker must set progress to 0 0N/A * at the beginning of a packing operation, and to 100 0N/A * @see #addPropertyChangeListener 0N/A * Get the set of this engine's properties. This set is 0N/A * a "live view", so that changing its 0N/A * contents immediately affects the Packer engine, and 0N/A * changes from the engine (such as progress indications) 0N/A * are immediately visible in the map. 0N/A * <p>The property map may contain pre-defined implementation 0N/A * specific and default properties. Users are encouraged to 0N/A * read the information and fully understand the implications, 0N/A * before modifying pre-existing properties. 0N/A * Implementation specific properties are prefixed with a 0N/A * package name associated with the implementor, beginning 0N/A * with <tt>com.</tt> or a similar prefix. 0N/A * All property names beginning with <tt>pack.</tt> and 0N/A * <tt>unpack.</tt> are reserved for use by this API. 0N/A * Unknown properties may be ignored or rejected with an 0N/A * unspecified error, and invalid entries may cause an 0N/A * unspecified error to be thrown. 0N/A * @return A sorted association of option key strings to option values. 0N/A * Read a Pack200 archive, and write the encoded JAR to 0N/A * a JarOutputStream. 0N/A * The entire contents of the input stream will be read. 0N/A * It may be more efficient to read the Pack200 archive 0N/A * to a file and pass the File object, using the alternate 0N/A * method described below. 0N/A * Closes its input but not its output. (The output can accumulate more elements.) 0N/A * @param in an InputStream. 0N/A * @param out a JarOutputStream. 0N/A * @exception IOException if an error is encountered. 0N/A * Read a Pack200 archive, and write the encoded JAR to 0N/A * a JarOutputStream. 0N/A * Does not close its output. (The output can accumulate more elements.) 0N/A * @param out a JarOutputStream. 0N/A * @exception IOException if an error is encountered. 0N/A * Registers a listener for PropertyChange events on the properties map. 0N/A * This is typically used by applications to update a progress bar. 0N/A * @param listener An object to be invoked when a property is changed. 0N/A * Remove a listener for PropertyChange events, added by 0N/A * the {@link #addPropertyChangeListener}. 0N/A * @see #addPropertyChangeListener 0N/A * @param listener The PropertyChange listener to be removed. 0N/A // Private stuff.... 0N/A // The first time, we must decide which class to use. 0N/A // We have a class. Now instantiate it. 0N/A " in your properties file.", e);
0N/A " in your properties file.", e);
0N/A " in your properties file.", e);