com.sun.jini.tool
Class JarWrapper

java.lang.Object
  extended by com.sun.jini.tool.JarWrapper

public class JarWrapper
extends Object

A tool for generating "wrapper" JAR files. A wrapper JAR file contains a Class-Path manifest attribute listing a group of JAR files to be loaded from a common codebase. It may also, depending on applicability and selected options, contain a JAR index file, a preferred class list and/or a Main-Class manifest entry for the grouped JAR files.

The following items are discussed below:

Applicability

The JarWrapper tool is applicable in the following deployment situations, which may overlap:

Using the Tool

JarWrapper can be run directly from the command line or can be invoked programmatically using the wrap method.

To run the tool on UNIX platforms:

 java -jar install_dir/lib/jarwrapper.jar processing_options
 
To run the tool on Microsoft Windows platforms:
 java -jar install_dir\lib\jarwrapper.jar processing_options
 

A more specific example with options for running directly from a Unix command line might be:

 % java -jar install_dir/lib/jarwrapper.jar \
        -httpmd=SHA-1 wrapper.jar base_dir src1.jar src2.jar
 
where install_dir is the directory where the Apache River release is installed. This command line would result in the creation of a wrapper JAR file, wrapper.jar, in the current working directory, whose contents would be based on the source JAR files src1.jar and src2.jar (as well as any other JAR files referenced transitively through their Class-Path attributes or JAR indexes). The paths for src1.jar and src2.jar, as well as any transitively referenced JAR files, would be resolved relative to the base_dir directory. The Class-Path attribute of wrapper.jar would use HTTPMD URLs with SHA-1 digests. If any of the HTTPMD URLs encountered is found to be invalid and can not be resolved, the JarWrapper operation will fail.

The equivalent programmatic invocation of JarWrapper would be:

 JarWrapper.wrap("wrapper.jar", "base_dir", new String[]{ "src1.jar", "src2.jar" }, "SHA-1", true, "manifest.mf" );
 

Logging

JarWrapper uses the Logger named com.sun.jini.tool.JarWrapper to log information at the following logging levels:

com.sun.jini.tool.JarWrapper
Level Description
WARNING Generated JAR index entries that do not end in ".jar"
FINE Names of processed source JAR files and output wrapper JAR file
FINER Processing of Main-Class and Class-Path attributes, and presence of preferred lists and JAR indexes
FINEST Processing and compilation of preferred lists and JAR indexes

Since:
2.0
Author:
Sun Microsystems, Inc.

Nested Class Summary
private static class JarWrapper.JarIndexReader
          Parses JAR indexes.
private static class JarWrapper.JarIndexWriter
          Assembles and writes JAR indexes.
private static class JarWrapper.LocalizedIllegalArgumentException
          IllegalArgumentException with a localized detail message.
private static class JarWrapper.LocalizedIOException
          IOException with a localized detail message.
private static class JarWrapper.PreferredListReader
          Parses preferred lists.
private static class JarWrapper.PreferredListWriter
          Compiles and writes combined preferred lists.
private static class JarWrapper.SourceJarURL
          Represents URL to a source JAR file.
 
Field Summary
private  File baseDir
          Base directory, null in case the JAR files are specified as absolute files, the so called flatten classpath option.
private  StringBuffer classPath
           
private static String DEFAULT_HTTPMD_ALGORITHM
           
private  File destJar
           
private  MessageDigest digest
           
private  JarWrapper.JarIndexWriter indexWriter
           
private static Logger logger
           
private  String mainClass
           
private  Manifest manifest
           
private  JarWrapper.PreferredListWriter prefWriter
           
private static ResourceBundle resources
           
private static Object resourcesLock
           
private  Set seenJars
           
private  JarWrapper.SourceJarURL[] srcJars
           
 
Constructor Summary
private JarWrapper(String destJar, String baseDir, String[] srcJars, String httpmdAlg, boolean index, Manifest mf, List apiClasses)
          Initializes JarWrapper based on the given values.
 
Method Summary
private  void deleteWrapperJar()
          Attempts to delete wrapper JAR file.
private  List getClassPath(JarFile jar)
          Returns URLs contained in the Class-Path attribute (if any) of the given JAR file, as a list of SourceJarURL instances.
private static String getDigestString(MessageDigest digest, File file)
          Returns a string representation of the message digest of the given file.
private static String getMainClass(JarFile jar)
          Returns the value of the Main-Class attribute of the given JAR file, or null if none is present.
private static String getResourceString(String key)
          Returns localized format string, obtained from the resource bundle for JarWrapper, that corresponds to the given key, or null if the resource bundle does not contain a corresponding string.
(package private) static String localize(String key)
          Returns localized message text corresponding to the given key string.
(package private) static String localize(String key, Object val)
          Returns localized message text corresponding to the given key string, passing the provided value as an argument when formatting the message.
(package private) static String localize(String key, Object[] vals)
          Returns localized message text corresponding to the given key string, passing the provided values as an argument when formatting the message.
static void main(String[] args)
          Generates a wrapper JAR file for the specified JAR files.
private  void outputWrapperJar()
          Writes wrapper JAR file based on information from processed source JARs.
private  void process(JarWrapper.SourceJarURL url, JarWrapper.PreferredListReader prefReader)
          Processes source JAR file indicated by the given URL, determining preferred resources using the provided preferred list reader.
private static Manifest retrieveManifest(String fileName)
          Returns the Manifest object derived from a manifest file as specified on the command line.
private static void setLoggingLevel(Level level)
          Sets logging and console handler output level.
private  void wrap()
          Processes source JAR files and outputs wrapper JAR file.
static void wrap(String destJar, String[] srcJars, String httpmdAlg, boolean index, Manifest mf, List apiClasses)
          Generates a wrapper JAR file based on the provided values in the same manner as described in the documentation for main(java.lang.String[]).
static void wrap(String destJar, String baseDir, String[] srcJars, String httpmdAlg, boolean index)
          Invokes wrap with the provided values and a null manifest.
static void wrap(String destJar, String baseDir, String[] srcJars, String httpmdAlg, boolean index, Manifest mf)
          Generates a wrapper JAR file based on the provided values in the same manner as described in the documentation for main(java.lang.String[]).
static void wrap(String destJar, String baseDir, String[] srcJars, String httpmdAlg, boolean index, Manifest mf, List apiClasses)
          Generates a wrapper JAR file based on the provided values in the same manner as described in the documentation for main(java.lang.String[]).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

resources

private static ResourceBundle resources

resourcesLock

private static final Object resourcesLock

logger

private static final Logger logger

destJar

private final File destJar

baseDir

private final File baseDir
Base directory, null in case the JAR files are specified as absolute files, the so called flatten classpath option.


srcJars

private final JarWrapper.SourceJarURL[] srcJars

manifest

private final Manifest manifest

digest

private final MessageDigest digest

indexWriter

private final JarWrapper.JarIndexWriter indexWriter

prefWriter

private final JarWrapper.PreferredListWriter prefWriter

classPath

private final StringBuffer classPath

mainClass

private String mainClass

seenJars

private final Set seenJars

DEFAULT_HTTPMD_ALGORITHM

private static final String DEFAULT_HTTPMD_ALGORITHM
See Also:
Constant Field Values
Constructor Detail

JarWrapper

private JarWrapper(String destJar,
                   String baseDir,
                   String[] srcJars,
                   String httpmdAlg,
                   boolean index,
                   Manifest mf,
                   List apiClasses)
Initializes JarWrapper based on the given values.

Method Detail

main

public static void main(String[] args)
Generates a wrapper JAR file for the specified JAR files. The command line arguments are:
 [ options ] dest-jar base-dir src-jar [ src-jar ...]
 
The dest-jar argument specifies the name of the wrapper JAR file to generate. The base-dir argument specifies the base directory from which to locate source JAR files to wrap. The src-jar arguments are non-absolute URLs to "top-level" source JAR files relative to base-dir; they also constitute the basis of the Class-Path attribute included in the generated wrapper JAR file. JAR files not present in the command line but indirectly referenced via JAR index or Class-Path entries in source JAR files will themselves be used as source JAR files, and will appear alongside the top-level source JAR files in the Class-Path attribute of the wrapper JAR file in depth-first order, with JAR index references appearing before Class-Path references. This utility does not modify any source JAR files.

If any of the top-level source JAR files contain preferred resources (as indicated by a preferred list in the JAR file), then a preferred list describing resource preferences across all source JAR files will be included in the wrapper JAR file. The preferred list of a top-level source JAR file is interpreted as applying to that JAR file along with all JAR files transitively referenced by it through JAR index or Class-Path entries, excluding JAR files that have already been encountered in the processing of preceding top-level JAR files. If a given top-level source JAR file does not contain a preferred list, then all resources contained in it and its transitively referenced JAR files (again, excluding those previously encountered) are considered not preferred. Preferred lists are described further in the documentation for PreferredClassLoader.

If any of the top-level source JAR files declare a Main-Class manifest entry, then the wrapper JAR file will include a Main-Class manifest entry whose value is that of the first top-level source JAR file listed on the command line which defines a Main-Class entry.

Note that attribute values generated by this utility, such as those for the Class-Path and Main-Class attributes described above, do not take precedence over values for the same attributes contained in a manifest file explicitly specified using the -manifest option (described below).

Supported options for this tool include:

-verbose
Sets the level of the com.sun.jini.tool.JarWrapper logger to Level.FINER.

-httpmd[=algorithm]
Use (relative) HTTPMD URLs in the Class-Path attribute of the generated wrapper JAR file. The default is to use HTTP URLs. Digests for HTTPMD URLs are calculated using the given algorithm, or SHA-1 if none is specified.

-noindex
Do not include a JAR index in the generated wrapper JAR file. The default is to compile an index based on the contents of the source JAR files.

-manifest=file
Specifies a manifest file containing attribute values to include in the manifest file inside the generated wrapper JAR file. This allows enables users to add additional metadata or override JarWrapper's generated values to customize the resulting manifest. The values contained in this optional file take precedence over the generated content. This flag is conceptually similar to the jar utilities m flag. In the current version there are four possible attributes that can be overridden in the target Manifest. These are Name.MANIFEST_VERSION, Name("Created-By"), Name.CLASS_PATH and Name.MAIN_CLASS. Any additonal attributes beyond these four will be appended to the manifest attribute list and will appear in the resultant MANIFEST.MF file.


wrap

public static void wrap(String destJar,
                        String baseDir,
                        String[] srcJars,
                        String httpmdAlg,
                        boolean index)
                 throws IOException
Invokes wrap with the provided values and a null manifest.

Parameters:
destJar - name of the wrapper JAR file to generate
baseDir - base directory from which to locate source JAR files to wrap
srcJars - list of top-level source JAR files to process
httpmdAlg - name of algorithm to use for generating HTTPMD URLs, or null if plain HTTP URLs should be used
index - if true, generate a JAR index; if false, do not generate one
Throws:
IOException - if an I/O error occurs while processing source JAR files or generating the wrapper JAR file
JarWrapper.LocalizedIllegalArgumentException - if the provided values are invalid
NullPointerException - if destJar, baseDir, srcJars, or any element of srcJars is null

wrap

public static void wrap(String destJar,
                        String baseDir,
                        String[] srcJars,
                        String httpmdAlg,
                        boolean index,
                        Manifest mf)
                 throws IOException
Generates a wrapper JAR file based on the provided values in the same manner as described in the documentation for main(java.lang.String[]). The only difference between this method and main is that it receives its values as explicit arguments instead of in a command line, and indicates failure by throwing an exception.

Parameters:
destJar - name of the wrapper JAR file to generate
baseDir - base directory from which to locate source JAR files to wrap
srcJars - list of top-level source JAR files to process
httpmdAlg - name of algorithm to use for generating HTTPMD URLs, or null if plain HTTP URLs should be used
index - if true, generate a JAR index; if false, do not generate one
mf - manifest containing values to include in the manifest file of the generated wrapper JAR file
Throws:
IOException - if an I/O error occurs while processing source JAR files or generating the wrapper JAR file
JarWrapper.LocalizedIllegalArgumentException - if the provided values are invalid
NullPointerException - if destJar, baseDir, srcJars, or any element of srcJars is null
Since:
2.1

wrap

public static void wrap(String destJar,
                        String baseDir,
                        String[] srcJars,
                        String httpmdAlg,
                        boolean index,
                        Manifest mf,
                        List apiClasses)
                 throws IOException
Generates a wrapper JAR file based on the provided values in the same manner as described in the documentation for main(java.lang.String[]). The only difference between this method and main is that it receives its values as explicit arguments instead of in a command line, and indicates failure by throwing an exception.

Parameters:
destJar - name of the wrapper JAR file to generate
baseDir - base directory from which to locate source JAR files to wrap
srcJars - list of top-level source JAR files to process
httpmdAlg - name of algorithm to use for generating HTTPMD URLs, or null if plain HTTP URLs should be used
index - if true, generate a JAR index; if false, do not generate one
mf - manifest containing values to include in the manifest file of the generated wrapper JAR file
apiClasses - list of binary class names (type String) that must be considered API classes in case a preferences conflict arises during wrapping of the JAR files, or null in case no such list is available
Throws:
IOException - if an I/O error occurs while processing source JAR files or generating the wrapper JAR file
JarWrapper.LocalizedIllegalArgumentException - if the provided values are invalid
NullPointerException - if destJar, baseDir, srcJars, or any element of srcJars is null

wrap

public static void wrap(String destJar,
                        String[] srcJars,
                        String httpmdAlg,
                        boolean index,
                        Manifest mf,
                        List apiClasses)
                 throws IOException
Generates a wrapper JAR file based on the provided values in the same manner as described in the documentation for main(java.lang.String[]).

The difference between this method and the 6 and 7-arg wrap method is that the source JAR files must be specified by an absolute path and that for processing the classpath will be flattened, i.e. each source JAR file will be considered as relative to its parent directory (that will serve as a virtual base directory) for the assembly of the Class-Path entry.

Parameters:
destJar - name of the wrapper JAR file to generate
srcJars - list of top-level source JAR files to process, must be absolute paths
httpmdAlg - name of algorithm to use for generating HTTPMD URLs, or null if plain HTTP URLs should be used
index - if true, generate a JAR index; if false, do not generate one
mf - manifest containing values to include in the manifest file of the generated wrapper JAR file
apiClasses - list of binary class names (type String) that must be considered API classes in case a preferences conflict arises during wrapping of the JAR files, or null in case no such list is available
Throws:
IOException - if an I/O error occurs while processing source JAR files or generating the wrapper JAR file
JarWrapper.LocalizedIllegalArgumentException - if the provided values are invalid
NullPointerException - if destJar, srcJars, or any element of srcJars is null

wrap

private void wrap()
           throws IOException
Processes source JAR files and outputs wrapper JAR file.

Throws:
IOException

process

private void process(JarWrapper.SourceJarURL url,
                     JarWrapper.PreferredListReader prefReader)
              throws IOException
Processes source JAR file indicated by the given URL, determining preferred resources using the provided preferred list reader. If the preferred list reader is null, then the URL is for a top-level source JAR file, in which case the preferred list of the JAR file should be read, if the JAR file has not already been processed.

Throws:
IOException

getClassPath

private List getClassPath(JarFile jar)
                   throws IOException
Returns URLs contained in the Class-Path attribute (if any) of the given JAR file, as a list of SourceJarURL instances.

Throws:
IOException

outputWrapperJar

private void outputWrapperJar()
                       throws IOException
Writes wrapper JAR file based on information from processed source JARs.

Throws:
IOException

deleteWrapperJar

private void deleteWrapperJar()
Attempts to delete wrapper JAR file.


getMainClass

private static String getMainClass(JarFile jar)
                            throws IOException
Returns the value of the Main-Class attribute of the given JAR file, or null if none is present.

Throws:
IOException

getDigestString

private static String getDigestString(MessageDigest digest,
                                      File file)
                               throws IOException
Returns a string representation of the message digest of the given file.

Throws:
IOException

setLoggingLevel

private static void setLoggingLevel(Level level)
Sets logging and console handler output level.


localize

static String localize(String key)
Returns localized message text corresponding to the given key string.


localize

static String localize(String key,
                       Object val)
Returns localized message text corresponding to the given key string, passing the provided value as an argument when formatting the message.


localize

static String localize(String key,
                       Object[] vals)
Returns localized message text corresponding to the given key string, passing the provided values as an argument when formatting the message.


getResourceString

private static String getResourceString(String key)
Returns localized format string, obtained from the resource bundle for JarWrapper, that corresponds to the given key, or null if the resource bundle does not contain a corresponding string.


retrieveManifest

private static Manifest retrieveManifest(String fileName)
                                  throws IOException
Returns the Manifest object derived from a manifest file as specified on the command line.

Throws:
IOException


Copyright 2007-2010, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.