Java/File Input Output/Jar File

Материал из Java эксперт
Перейти к: навигация, поиск

Содержание

A class to find resources in the classpath by their mime-type specified in the MANIFEST.

   <source lang="java">
 

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

import java.io.IOException; import java.net.URL; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import java.util.jar.Attributes; import java.util.jar.Manifest; /**

* A class to find resources in the classpath by their mime-type specified in
* the MANIFEST.
*

* This class searches for content entries in all META-INF/MANIFEST.MF files. It * will find files with a given Content-Type: attribute. This allows to add * arbitrary resources by content-type just by creating a JAR wrapper and adding * them to the classpath. * <p> * Example:
* *

 * Name: test.txt
 * Content-Type: text/plain
 * 
*/

public final class ClasspathResource {

   /**
    * Actual Type: Map<String,List<URL>>.
    */
   private final Map contentMappings;
   private static final String MANIFEST_PATH = "META-INF/MANIFEST.MF";
   private static final String CONTENT_TYPE_KEY = "Content-Type";
   private static ClasspathResource classpathResource;
   private ClasspathResource() {
       contentMappings = new HashMap();
       loadManifests();
   }
   /**
    * Retrieve the singleton instance of this class.
    * 
    * @return the ClassPathResource instance.
    */
   public static synchronized ClasspathResource getInstance() {
       if (classpathResource == null) {
           classpathResource = new ClasspathResource();
       }
       return classpathResource;
   }
   /* Actual return type: Set<ClassLoader> */
   private Set getClassLoadersForResources() {
       Set v = new HashSet();
       try {
           ClassLoader l = ClassLoader.getSystemClassLoader();
           if (l != null) {
               v.add(l);
           }
       } catch (SecurityException e) {
           // Ignore
       }
       try {
           ClassLoader l = Thread.currentThread().getContextClassLoader();
           if (l != null) {
               v.add(l);
           }
       } catch (SecurityException e) {
           // Ignore
       }
       try {
           ClassLoader l = ClasspathResource.class.getClassLoader();
           if (l != null) {
               v.add(l);
           }
       } catch (SecurityException e) {
           // Ignore
       }
       return v;
   }
   private void loadManifests() {
       Enumeration e;
       try {
           Iterator it = getClassLoadersForResources().iterator();
           while (it.hasNext()) {
               ClassLoader classLoader = (ClassLoader) it.next();
               e = classLoader.getResources(MANIFEST_PATH);
               while (e.hasMoreElements()) {
                   final URL u = (URL) e.nextElement();
                   try {
                       final Manifest manifest = new Manifest(u.openStream());
                       final Map entries = manifest.getEntries();
                       final Iterator entrysetiterator = entries.entrySet()
                               .iterator();
                       while (entrysetiterator.hasNext()) {
                           final Map.Entry entry = (Map.Entry) entrysetiterator
                                   .next();
                           final String name = (String) entry.getKey();
                           final Attributes attributes = (Attributes) entry
                                   .getValue();
                           final String contentType = attributes
                                   .getValue(CONTENT_TYPE_KEY);
                           if (contentType != null) {
                               addToMapping(contentType, name, classLoader);
                           }
                       }
                   } catch (IOException io) {
                       // TODO: Log.
                   }
               }
           }
       } catch (IOException io) {
           // TODO: Log.
       }
   }
   private void addToMapping(final String contentType, final String name,
           final ClassLoader classLoader) {
       List existingFiles = (List) contentMappings.get(contentType);
       if (existingFiles == null) {
           existingFiles = new Vector();
           contentMappings.put(contentType, existingFiles);
       }
       final URL url = classLoader.getResource(name);
       if (url != null) {
           existingFiles.add(url);
       }
   }
   /**
    * Retrieve a list of resources known to have the given mime-type.
    * 
    * @param mimeType
    *            the mime-type to search for.
    * @return a List<URL>, guaranteed to be != null.
    */
   public List listResourcesOfMimeType(final String mimeType) {
       final List content = (List) contentMappings.get(mimeType);
       if (content == null) {
           return Collections.EMPTY_LIST;
       } else {
           return content;
       }
   }

} //////////////// /*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id: $ */ package org.apache.xmlgraphics.util; import java.net.URL; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; /**

* Test for the Service class.
*/

public class ClasspathResourceTest extends TestCase {

   /**
    * Tests whether the file /sample.txt with mime-type text/plain exists.
    * 
    * @throws Exception
    *             in case of an error
    */
   public void testSampleResource() throws Exception {
       final List list = ClasspathResource.getInstance()
               .listResourcesOfMimeType("text/plain");
       boolean found = false;
       final Iterator i = list.iterator();
       while (i.hasNext()) {
           final URL u = (URL) i.next();
           if (u.getPath().endsWith("sample.txt")) {
               found = true;
           }
       }
       assertTrue(found);
   }
   /**
    * Tests the mode where Service returns class names.
    * 
    * @throws Exception
    *             in case of an error
    */
   public void testNonexistingResource() throws Exception {
       final List list = ClasspathResource.getInstance()
               .listResourcesOfMimeType("nota/mime-type");
       assertTrue(list.isEmpty());
   }

}


 </source>
   
  
 
  



Add a jar entry to the deployment archive

   <source lang="java">

/*

* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; /**

* A collection of jar utilities
* 
* @author thomas.diesler@jboss.org
* @version $Revision: 81011 $
*/

public class JarUtils {

 /**
  * Add jar contents to the deployment archive under the given prefix
  */
 public static String[] addJar(JarOutputStream outputStream, String prefix, File jar)
     throws IOException {
   ArrayList tmp = new ArrayList();
   FileInputStream fis = new FileInputStream(jar);
   JarInputStream jis = new JarInputStream(fis);
   JarEntry entry = jis.getNextJarEntry();
   while (entry != null) {
     if (entry.isDirectory() == false) {
       String entryName = prefix + entry.getName();
       tmp.add(entryName);
       addJarEntry(outputStream, entryName, jis);
     }
     entry = jis.getNextJarEntry();
   }
   jis.close();
   String[] names = new String[tmp.size()];
   tmp.toArray(names);
   return names;
 }
 /**
  * Add a jar entry to the deployment archive
  */
 public static void addJarEntry(JarOutputStream outputStream, String entryName,
     InputStream inputStream) throws IOException {
   outputStream.putNextEntry(new JarEntry(entryName));
   copyStream(outputStream, inputStream);
 }
 /**
  * Copies the input stream to the output stream
  */
 public static void copyStream(OutputStream outputStream, InputStream inputStream)
     throws IOException {
   byte[] bytes = new byte[4096];
   int read = inputStream.read(bytes, 0, 4096);
   while (read > 0) {
     outputStream.write(bytes, 0, read);
     read = inputStream.read(bytes, 0, 4096);
   }
 }

}

 </source>
   
  
 
  



Add jar contents to the deployment archive under the given prefix

   <source lang="java">

/*

* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; /**

* A collection of jar utilities
* 
* @author thomas.diesler@jboss.org
* @version $Revision: 81011 $
*/

public class JarUtils {

 /**
  * Add jar contents to the deployment archive under the given prefix
  */
 public static String[] addJar(JarOutputStream outputStream, String prefix, File jar)
     throws IOException {
   ArrayList tmp = new ArrayList();
   FileInputStream fis = new FileInputStream(jar);
   JarInputStream jis = new JarInputStream(fis);
   JarEntry entry = jis.getNextJarEntry();
   while (entry != null) {
     if (entry.isDirectory() == false) {
       String entryName = prefix + entry.getName();
       tmp.add(entryName);
       addJarEntry(outputStream, entryName, jis);
     }
     entry = jis.getNextJarEntry();
   }
   jis.close();
   String[] names = new String[tmp.size()];
   tmp.toArray(names);
   return names;
 }
 /**
  * Add a jar entry to the deployment archive
  */
 public static void addJarEntry(JarOutputStream outputStream, String entryName,
     InputStream inputStream) throws IOException {
   outputStream.putNextEntry(new JarEntry(entryName));
   copyStream(outputStream, inputStream);
 }
 /**
  * Copies the input stream to the output stream
  */
 public static void copyStream(OutputStream outputStream, InputStream inputStream)
     throws IOException {
   byte[] bytes = new byte[4096];
   int read = inputStream.read(bytes, 0, 4096);
   while (read > 0) {
     outputStream.write(bytes, 0, read);
     read = inputStream.read(bytes, 0, 4096);
   }
 }

}

 </source>
   
  
 
  



class for exploding jar/zip files onto the file system

   <source lang="java">
 

/*******************************************************************************

* Copyright (c) 2004, 2008 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*  IBM Corporation - initial API and implementation
*******************************************************************************/

import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /**

* class for exploding jar/zip files onto the file system
* 
* @author Barry Feigenbaum
*/

public class ZipExploder {

 /**
  * create a zip exploder for unpacking .jar/.zip files
  */
 public ZipExploder() {
   this(false);
 }
 /**
  * create a zip exploder for unpacking .jar/.zip files onto the file system
  * 
  * @param verbose -
  *          set to true for verbose mode
  */
 public ZipExploder(boolean verbose) {
   setVerbose(verbose);
 }
 /**
  * create a zip exploder for unpacking .jar/.zip files onto the file system
  * 
  * @param verbose -
  *          set to true for verbose mode
  * @param sorted -
  *          set to true for sorted file mode
  */
 public ZipExploder(boolean verbose, boolean sorted) {
   this(verbose);
   setSortNames(sorted);
 }
 protected boolean verbose;
 /**
  * Get the verbose mode state.
  * 
  * @return verbosity
  */
 public boolean getVerbose() {
   return verbose;
 }
 /**
  * set the verbose mode state
  * 
  * @param f -
  *          verbosity
  */
 public void setVerbose(boolean f) {
   verbose = f;
 }
 protected boolean sortNames;
 /**
  * @return Returns the sortNames.
  */
 public boolean getSortNames() {
   return sortNames;
 }
 /**
  * @param sortNames
  *          The sortNames to set.
  */
 public void setSortNames(boolean sortNames) {
   this.sortNames = sortNames;
 }
 /**
  * Explode source JAR and/or ZIP files into a target directory
  * 
  * @param zipNames
  *          names of source files
  * @param jarNames
  *          names of source files
  * @param destDir
  *          target directory name (should already exist)
  * @exception IOException
  *              error creating a target file
  */
 public void process(String[] zipNames, String[] jarNames, String destDir) throws IOException {
   processZips(zipNames, destDir);
   processJars(jarNames, destDir);
 }
 /**
  * Explode source JAR files into a target directory
  * 
  * @param jarNames
  *          names of source files
  * @param destDir
  *          target directory name (should already exist)
  * @exception IOException
  *              error creating a target file
  */
 public void processJars(String[] jarNames, String destDir) throws IOException {
   for (int i = 0; i < jarNames.length; i++) {
     processFile(jarNames[i], destDir);
   }
 }
 /**
  * Explode source ZIP files into a target directory
  * 
  * @param zipNames
  *          names of source files
  * @param destDir
  *          target directory name (should already exist)
  * @exception IOException
  *              error creating a target file
  */
 public void processZips(String[] zipNames, String destDir) throws IOException {
   for (int i = 0; i < zipNames.length; i++) {
     processFile(zipNames[i], destDir);
   }
 }
 /**
  * Explode source ZIP or JAR file into a target directory
  * 
  * @param zipName
  *          names of source file
  * @param destDir
  *          target directory name (should already exist)
  * @exception IOException
  *              error creating a target file
  */
 public void processFile(String zipName, String destDir) throws IOException {
   String source = new File(zipName).getCanonicalPath();
   String dest = new File(destDir).getCanonicalPath();
   ZipFile f = null;
   try {
     f = new ZipFile(source);
     Map fEntries = getEntries(f);
     String[] names = (String[]) fEntries.keySet().toArray(new String[] {});
     if (sortNames) {
       Arrays.sort(names);
     }
     // copy all files
     for (int i = 0; i < names.length; i++) {
       String name = names[i];
       ZipEntry e = (ZipEntry) fEntries.get(name);
       copyFileEntry(dest, f, e);
     }
   } catch (IOException ioe) {
     String msg = ioe.getMessage();
     if (msg.indexOf(zipName) < 0) {
       msg += " - " + zipName;
     }
     throw new IOException(msg);
   } finally {
     if (f != null) {
       try {
         f.close();
       } catch (IOException ioe) {
       }
     }
   }
 }
 /** Get all the entries in a ZIP file. */
 protected Map getEntries(ZipFile zf) {
   Enumeration e = zf.entries();
   Map m = new HashMap();
   while (e.hasMoreElements()) {
     ZipEntry ze = (ZipEntry) e.nextElement();
     m.put(ze.getName(), ze);
   }
   return m;
 }
 /**
  * copy a single entry from the archive
  * 
  * @param destDir
  * @param zf
  * @param ze
  * @throws IOException
  */
 public void copyFileEntry(String destDir, ZipFile zf, ZipEntry ze) throws IOException {
   DataInputStream dis = new DataInputStream(new BufferedInputStream(zf.getInputStream(ze)));
   try {
     copyFileEntry(destDir, ze.isDirectory(), ze.getName(), dis);
   } finally {
     try {
       dis.close();
     } catch (IOException ioe) {
     }
   }
 }
 protected void copyFileEntry(String destDir, boolean destIsDir, String destFile,
     DataInputStream dis) throws IOException {
   byte[] bytes = readAllBytes(dis);
   File file = new File(destFile);
   String parent = file.getParent();
   if (parent != null && parent.length() > 0) {
     File dir = new File(destDir, parent);
     if (dir != null) {
       dir.mkdirs();
     }
   }
   File outFile = new File(destDir, destFile);
   if (destIsDir) {
     outFile.mkdir();
   } else {
     FileOutputStream fos = new FileOutputStream(outFile);
     try {
       fos.write(bytes, 0, bytes.length);
     } finally {
       try {
         fos.close();
       } catch (IOException ioe) {
       }
     }
   }
 }
 // *** below may be slow for large files ***
 /** Read all the bytes in a ZIPed file */
 protected byte[] readAllBytes(DataInputStream is) throws IOException {
   byte[] bytes = new byte[0];
   for (int len = is.available(); len > 0; len = is.available()) {
     byte[] xbytes = new byte[len];
     int count = is.read(xbytes);
     if (count > 0) {
       byte[] nbytes = new byte[bytes.length + count];
       System.arraycopy(bytes, 0, nbytes, 0, bytes.length);
       System.arraycopy(xbytes, 0, nbytes, bytes.length, count);
       bytes = nbytes;
     } else if (count < 0) {
       // accommodate apparent bug in IBM JVM where
       // available() always returns positive value on some files
       break;
     }
   }
   return bytes;
 }
 protected void print(String s) {
   System.out.print(s);
 }
 /** Print command help text. */
 protected static void printHelp() {
   System.out.println();
   System.out.println("Usage: java " + ZipExploder.class.getName()
       + " (-jar jarFilename... | -zip zipFilename...)... -dir destDir {-verbose}");
   System.out.println("Where:");
   System.out.println("  jarFilename path to source jar, may repeat");
   System.out.println("  zipFilename path to source zip, may repeat");
   System.out.println("  destDir    path to target directory; should exist");
   System.out.println("Note: one -jar or -zip is required; switch case or order is not important");
 }
 protected static void reportError(String msg) {
   System.err.println(msg);
   // printHelp();
   System.exit(1);
 }
 /**
  * Main command line entry point.
  * 
  * @param args
  */
 public static void main(final String[] args) {
   if (args.length == 0) {
     printHelp();
     System.exit(0);
   }
   List zipNames = new ArrayList();
   List jarNames = new ArrayList();
   String destDir = null;
   boolean jarActive = false, zipActive = false, destDirActive = false;
   boolean verbose = false;
   // process arguments
   for (int i = 0; i < args.length; i++) {
     String arg = args[i];
     if (arg.charAt(0) == "-") { // switch
       arg = arg.substring(1);
       if (arg.equalsIgnoreCase("jar")) {
         jarActive = true;
         zipActive = false;
         destDirActive = false;
       } else if (arg.equalsIgnoreCase("zip")) {
         zipActive = true;
         jarActive = false;
         destDirActive = false;
       } else if (arg.equalsIgnoreCase("dir")) {
         jarActive = false;
         zipActive = false;
         destDirActive = true;
       } else if (arg.equalsIgnoreCase("verbose")) {
         verbose = true;
       } else {
         reportError("Invalid switch - " + arg);
       }
     } else {
       if (jarActive) {
         jarNames.add(arg);
       } else if (zipActive) {
         zipNames.add(arg);
       } else if (destDirActive) {
         if (destDir != null) {
           reportError("duplicate argument - " + "-destDir");
         }
         destDir = arg;
       } else {
         reportError("Too many parameters - " + arg);
       }
     }
   }
   if (destDir == null || (zipNames.size() + jarNames.size()) == 0) {
     reportError("Missing parameters");
   }
   if (verbose) {
     System.out.println("Effective command: " + ZipExploder.class.getName() + " "
         + (jarNames.size() > 0 ? "-jars " + jarNames + " " : "")
         + (zipNames.size() > 0 ? "-zips " + zipNames + " " : "") + "-dir " + destDir);
   }
   try {
     ZipExploder ze = new ZipExploder(verbose);
     ze.process((String[]) zipNames.toArray(new String[zipNames.size()]), (String[]) jarNames
         .toArray(new String[jarNames.size()]), destDir);
   } catch (IOException ioe) {
     System.err.println("Exception - " + ioe.getMessage());
     ioe.printStackTrace(); // *** debug ***
     System.exit(2);
   }
 }

}


 </source>
   
  
 
  



Create a Jar archive containing the src file/directory

   <source lang="java">

   

/*

 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.JarURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import java.util.zip.ZipEntry; /** A utility class for dealing with Jar files. @author Scott.Stark@jboss.org @version $Revision: 2787 $

  • /

public final class JarUtils {

  /**
   * Hide the constructor
   */
  private JarUtils()
  {
  }
  
  /**
   * <P>This function will create a Jar archive containing the src
   * file/directory.  The archive will be written to the specified
* OutputStream.

   *
*

This is a shortcut for
* jar(out, new File[] { src }, null, null, null);

   *
   * @param out The output stream to which the generated Jar archive is
   *        written.
   * @param src The file or directory to jar up.  Directories will be
   *        processed recursively.
   * @throws IOException 
   */
  public static void jar(OutputStream out, File src) throws IOException
  {
     jar(out, new File[] { src }, null, null, null);
  }

  /**
*

This function will create a Jar archive containing the src * file/directory. The archive will be written to the specified * OutputStream.

   *
*

This is a shortcut for
* jar(out, src, null, null, null);

   *
   * @param out The output stream to which the generated Jar archive is
   *        written.
   * @param src The file or directory to jar up.  Directories will be
   *        processed recursively.
   * @throws IOException 
   */
  public static void jar(OutputStream out, File[] src) throws IOException
  {
     jar(out, src, null, null, null);
  }
  
  /**
*

This function will create a Jar archive containing the src * file/directory. The archive will be written to the specified * OutputStream. Directories are processed recursively, applying the * specified filter if it exists. * * <P>This is a shortcut for
* jar(out, src, filter, null, null);

   *
   * @param out The output stream to which the generated Jar archive is
   *        written.
   * @param src The file or directory to jar up.  Directories will be
   *        processed recursively.
   * @param filter The filter to use while processing directories.  Only
   *        those files matching will be included in the jar archive.  If
   *        null, then all files are included.
   * @throws IOException 
   */
  public static void jar(OutputStream out, File[] src, FileFilter filter)
     throws IOException
  {
     jar(out, src, filter, null, null);
  }
  
  /**
*

This function will create a Jar archive containing the src * file/directory. The archive will be written to the specified * OutputStream. Directories are processed recursively, applying the * specified filter if it exists. * * @param out The output stream to which the generated Jar archive is * written. * @param src The file or directory to jar up. Directories will be * processed recursively. * @param filter The filter to use while processing directories. Only * those files matching will be included in the jar archive. If * null, then all files are included. * @param prefix The name of an arbitrary directory that will precede all * entries in the jar archive. If null, then no prefix will be * used. * @param man The manifest to use for the Jar archive. If null, then no * manifest will be included. * @throws IOException */ public static void jar(OutputStream out, File[] src, FileFilter filter, String prefix, Manifest man) throws IOException { for (int i = 0; i < src.length; i++) { if (!src[i].exists()) { throw new FileNotFoundException(src.toString()); } } JarOutputStream jout; if (man == null) { jout = new JarOutputStream(out); } else { jout = new JarOutputStream(out, man); } if (prefix != null && prefix.length() > 0 && !prefix.equals("/")) { // strip leading "/" if (prefix.charAt(0) == "/") { prefix = prefix.substring(1); } // ensure trailing "/" if (prefix.charAt(prefix.length() - 1) != "/") { prefix = prefix + "/"; } } else { prefix = ""; } JarInfo info = new JarInfo(jout, filter); for (int i = 0; i < src.length; i++) { jar(src[i], prefix, info); } jout.close(); } /** * This simple convenience class is used by the jar method to reduce the * number of arguments needed. It holds all non-changing attributes * needed for the recursive jar method. */ private static class JarInfo { public JarOutputStream out; public FileFilter filter; public byte[] buffer; public JarInfo(JarOutputStream out, FileFilter filter) { this.out = out; this.filter = filter; buffer = new byte[1024]; } } /** * This recursive method writes all matching files and directories to * the jar output stream. */ private static void jar(File src, String prefix, JarInfo info) throws IOException { JarOutputStream jout = info.out; if (src.isDirectory()) { // create / init the zip entry prefix = prefix + src.getName() + "/"; ZipEntry entry = new ZipEntry(prefix); entry.setTime(src.lastModified()); entry.setMethod(JarOutputStream.STORED); entry.setSize(0L); entry.setCrc(0L); jout.putNextEntry(entry); jout.closeEntry(); // process the sub-directories File[] files = src.listFiles(info.filter); for (int i = 0; i < files.length; i++) { jar(files[i], prefix, info); } } else if (src.isFile()) { // get the required info objects byte[] buffer = info.buffer; // create / init the zip entry ZipEntry entry = new ZipEntry(prefix + src.getName()); entry.setTime(src.lastModified()); jout.putNextEntry(entry); // dump the file FileInputStream in = new FileInputStream(src); int len; while ((len = in.read(buffer, 0, buffer.length)) != -1) { jout.write(buffer, 0, len); } in.close(); jout.closeEntry(); } } public static void unjar(InputStream in, File dest) throws IOException { if (!dest.exists()) { dest.mkdirs(); } if (!dest.isDirectory()) { throw new IOException("Destination must be a directory."); } JarInputStream jin = new JarInputStream(in); byte[] buffer = new byte[1024]; ZipEntry entry = jin.getNextEntry(); while (entry != null) { String fileName = entry.getName(); if (fileName.charAt(fileName.length() - 1) == "/") { fileName = fileName.substring(0, fileName.length() - 1); } if (fileName.charAt(0) == "/") { fileName = fileName.substring(1); } if (File.separatorChar != "/") { fileName = fileName.replace("/", File.separatorChar); } File file = new File(dest, fileName); if (entry.isDirectory()) { // make sure the directory exists file.mkdirs(); jin.closeEntry(); } else { // make sure the directory exists File parent = file.getParentFile(); if (parent != null && !parent.exists()) { parent.mkdirs(); } // dump the file OutputStream out = new FileOutputStream(file); int len = 0; while ((len = jin.read(buffer, 0, buffer.length)) != -1) { out.write(buffer, 0, len); } out.flush(); out.close(); jin.closeEntry(); file.setLastModified(entry.getTime()); } entry = jin.getNextEntry(); } /* Explicity write out the META-INF/MANIFEST.MF so that any headers such as the Class-Path are see for the unpackaged jar */ Manifest mf = jin.getManifest(); if (mf != null) { File file = new File(dest, "META-INF/MANIFEST.MF"); File parent = file.getParentFile(); if( parent.exists() == false ) { parent.mkdirs(); } OutputStream out = new FileOutputStream(file); mf.write(out); out.flush(); out.close(); } jin.close(); } /** Given a URL check if its a jar url(jar:<url>!/archive) and if it is, extract the archive entry into the given dest directory and return a file URL to its location. If jarURL is not a jar url then it is simply returned as the URL for the jar. @param jarURL the URL to validate and extract the referenced entry if its a jar protocol URL @param dest the directory into which the nested jar will be extracted. @return the file: URL for the jar referenced by the jarURL parameter. * @throws IOException */ public static URL extractNestedJar(URL jarURL, File dest) throws IOException { // This may not be a jar URL so validate the protocol if( jarURL.getProtocol().equals("jar") == false ) return jarURL; String destPath = dest.getAbsolutePath(); URLConnection urlConn = jarURL.openConnection(); JarURLConnection jarConn = (JarURLConnection) urlConn; // Extract the archive to dest/jarName-contents/archive String parentArchiveName = jarConn.getJarFile().getName(); // Find the longest common prefix between destPath and parentArchiveName int length = Math.min(destPath.length(), parentArchiveName.length()); int n = 0; while( n < length ) { char a = destPath.charAt(n); char b = parentArchiveName.charAt(n); if( a != b ) break; n ++; } // Remove any common prefix from parentArchiveName parentArchiveName = parentArchiveName.substring(n); File archiveDir = new File(dest, parentArchiveName+"-contents"); if( archiveDir.exists() == false && archiveDir.mkdirs() == false ) throw new IOException("Failed to create contents directory for archive, path="+archiveDir.getAbsolutePath()); String archiveName = jarConn.getEntryName(); File archiveFile = new File(archiveDir, archiveName); File archiveParentDir = archiveFile.getParentFile(); if( archiveParentDir.exists() == false && archiveParentDir.mkdirs() == false ) throw new IOException("Failed to create parent directory for archive, path="+archiveParentDir.getAbsolutePath()); InputStream archiveIS = jarConn.getInputStream(); FileOutputStream fos = new FileOutputStream(archiveFile); BufferedOutputStream bos = new BufferedOutputStream(fos); byte[] buffer = new byte[4096]; int read; while( (read = archiveIS.read(buffer)) > 0 ) { bos.write(buffer, 0, read); } archiveIS.close(); bos.close(); // Return the file url to the extracted jar return archiveFile.toURL(); } public static void main(String[] args) throws Exception { if (args.length == 0) { System.out.println("usage: <x or c> <jar-archive> <files...>"); System.exit(0); } if (args[0].equals("x")) { BufferedInputStream in = new BufferedInputStream(new FileInputStream(args[1])); File dest = new File(args[2]); unjar(in, dest); } else if (args[0].equals("c")) { BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(args[1])); File[] src = new File[args.length - 2]; for (int i = 0; i < src.length; i++) { src[i] = new File(args[2 + i]); } jar(out, src); } else { System.out.println("Need x or c as first argument"); } } } </source>

Create a URL that refers to a jar file in the file system

   <source lang="java">
   

import java.net.URL; public class Main {

 public static void main(String[] argv) throws Exception {
   URL url = new URL("jar:file:/c://my.jar!/");
 }

}



 </source>
   
  
 
  



Create a URL that refers to an entry in the jar file

   <source lang="java">
   

import java.net.URL; public class Main {

 public static void main(String[] argv) throws Exception {
   URL url = new URL("jar:file:/c://my.jar!/com/mycompany/MyClass.class");
 }

}



 </source>
   
  
 
  



Create Jar file

   <source lang="java">
   

import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; public class CreateJarFile {

 public static int BUFFER_SIZE = 10240;
 protected void createJarArchive(File archiveFile, File[] tobeJared) {
   try {
     byte buffer[] = new byte[BUFFER_SIZE];
     // Open archive file
     FileOutputStream stream = new FileOutputStream(archiveFile);
     JarOutputStream out = new JarOutputStream(stream, new Manifest());
     for (int i = 0; i < tobeJared.length; i++) {
       if (tobeJared[i] == null || !tobeJared[i].exists()
           || tobeJared[i].isDirectory())
         continue; // Just in case...
       System.out.println("Adding " + tobeJared[i].getName());
       // Add archive entry
       JarEntry jarAdd = new JarEntry(tobeJared[i].getName());
       jarAdd.setTime(tobeJared[i].lastModified());
       out.putNextEntry(jarAdd);
       // Write file to archive
       FileInputStream in = new FileInputStream(tobeJared[i]);
       while (true) {
         int nRead = in.read(buffer, 0, buffer.length);
         if (nRead <= 0)
           break;
         out.write(buffer, 0, nRead);
       }
       in.close();
     }
     out.close();
     stream.close();
     System.out.println("Adding completed OK");
   } catch (Exception ex) {
     ex.printStackTrace();
     System.out.println("Error: " + ex.getMessage());
   }
 }

}



 </source>
   
  
 
  



Creating a JAR File

   <source lang="java">
   

// Create the jar file jar cf myjar.jar MyClass.class



 </source>
   
  
 
  



Determine whether a file is a JAR File.

   <source lang="java">

import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.zip.ZipFile; public class Main {

 /**
  * Determine whether a file is a JAR File.
  */
 public static boolean isJarFile(File file) throws IOException {
   if (!isZipFile(file)) {
     return false;
   }
   ZipFile zip = new ZipFile(file);
   boolean manifest = zip.getEntry("META-INF/MANIFEST.MF") != null;
   zip.close();
   return manifest;
 }
 /**
  * Determine whether a file is a ZIP File.
  */
 public static boolean isZipFile(File file) throws IOException {
     if(file.isDirectory()) {
         return false;
     }
     if(!file.canRead()) {
         throw new IOException("Cannot read file "+file.getAbsolutePath());
     }
     if(file.length() < 4) {
         return false;
     }
     DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
     int test = in.readInt();
     in.close();
     return test == 0x504b0304;
 }

}

 </source>
   
  
 
  



Get resource from Jar file

   <source lang="java">
 

/**

* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; public final class JarResource {

 public List<String> getJarContents(URL jarLocation) throws IOException {
   return getJarContents(jarLocation.openStream());
 }
 public List<String> getJarContents(InputStream is) throws IOException {
   return load(is);
 }
 public List<String> getJarContents(String jarLocation) throws IOException {
   return getJarContents(new File(jarLocation));
 }
 public List<String> getJarContents(File jarFile) throws IOException {
   return load(jarFile);
 }
 private List<String> load(File jarFile) throws IOException {
   List<String> jarContents = new ArrayList<String>();
   try {
     ZipFile zf = new ZipFile(jarFile);
     for (Enumeration e = zf.entries(); e.hasMoreElements();) {
       ZipEntry ze = (ZipEntry) e.nextElement();
       if (ze.isDirectory()) {
         continue;
       }
       jarContents.add(ze.getName());
     }
   } catch (NullPointerException e) {
     System.out.println("done.");
   } catch (ZipException ze) {
     ze.printStackTrace();
   }
   return jarContents;
 }
 private List<String> load(InputStream is) throws IOException {
   List<String> jarContents = new ArrayList<String>();
   try {
     ZipInputStream zis = new ZipInputStream(is);
     ZipEntry ze = zis.getNextEntry();
     while (ze != null) {
       if (ze.isDirectory()) {
         continue;
       }
       jarContents.add(ze.getName());
       ze = zis.getNextEntry();
     }
   } catch (NullPointerException e) {
     System.out.println("done.");
   }
   return jarContents;
 }

}


 </source>
   
  
 
  



Get the entry name; it should be the same as specified on URL

   <source lang="java">
   

import java.net.JarURLConnection; import java.net.URL; public class Main {

 public static void main(String[] argv) throws Exception {
   URL url = new URL("jar:file:/c://my.jar!/");
   JarURLConnection conn = (JarURLConnection) url.openConnection();
   String entryName = conn.getEntryName();
 }

}



 </source>
   
  
 
  



Get the jar entry

   <source lang="java">
   

import java.net.JarURLConnection; import java.net.URL; import java.util.jar.JarEntry; public class Main {

 public static void main(String[] argv) throws Exception {
   URL url = new URL("jar:file:/c://my.jar!/");
   JarURLConnection conn = (JarURLConnection) url.openConnection();
   JarEntry jarEntry = conn.getJarEntry();
 }

}



 </source>
   
  
 
  



Get the jar file

   <source lang="java">
   

import java.net.JarURLConnection; import java.net.URL; import java.util.jar.JarFile; public class Main {

 public static void main(String[] argv) throws Exception {
   URL url = new URL("jar:file:/c://my.jar!/");
   JarURLConnection conn = (JarURLConnection) url.openConnection();
   conn = (JarURLConnection) url.openConnection();
   JarFile jarfile = conn.getJarFile();
 }

}



 </source>
   
  
 
  



Get the jar file from a URL

   <source lang="java">
   

import java.net.JarURLConnection; import java.net.URL; import java.util.jar.JarFile; public class Main {

 public static void main(String[] argv) throws Exception {
   URL url = new URL("jar:file:/c://my.jar!/");
   JarURLConnection conn = (JarURLConnection) url.openConnection();
   JarFile jarfile = conn.getJarFile();
 }

}



 </source>
   
  
 
  



Getting a Jar File Using a URL

   <source lang="java">
   

import java.net.URL; public class Main {

 public static void main(String[] argv) throws Exception {
   // Create a URL that refers to a jar file on the net
   URL url = new URL("jar:http://hostname/my.jar!/");
 }

}



 </source>
   
  
 
  



Helper Class to manipulate Java Archive File

   <source lang="java">
  

/* -------------------------------------------------------------------------*

* PKUAS: Peking University Application Server
* Copyright (C) 2006 Peking University
*
* This software is free; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* either version 2.1 or any later version.
* 
* This software 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
* Lesser General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
* USA
* ------------------------------------------------------------------------*/

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.util.ArrayList; import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; /**

* This is the Helper Class to manipulate Java Archive File
* @author Lin Liang
*/

public class JarMaker {

   public JarMaker() {
   }
   public static boolean pack(String jarPath, String jarFileName) {
       try {
           String t_jarPathName = jarPath.replace("\\", File.separatorChar);
           String t_jarFileName = jarFileName.replace("\\", File.separatorChar);
           RealPackUtilityJar(t_jarPathName, t_jarFileName);
           return true;
       } catch (Exception ex) {
           return false;
       }
   }
   public static boolean utilityPack(String p_utilityFileName, String jarName) {
       try {
           // begin to pack the utility jar file.
           String t_utilityfilename = p_utilityFileName.replace("\\", File.separatorChar);
           String t_jarfilename = jarName.replace("\\", File.separatorChar) + ".jar";
           // File utilityFile = new File(p_utilityFileName);
           RealPackUtilityJar(t_utilityfilename, t_jarfilename);
           // delete the utility directory!
       } catch (Exception ex) {
           return false;
       }
       return true;
   }
   public static void RealPackUtilityJar(String s_src, String s_dest) throws IOException {
       URL _src, _dest;
       File f_src = new File(s_src);
       if (!f_src.isDirectory())
           throw new IOException(s_src + " is not a directory");
       _src = f_src.toURL();
       _dest = new File(s_dest).toURL();
       int path_l = s_dest.lastIndexOf("/");
       if (path_l > 0) {
           File dir = new File(s_dest.substring(0, path_l));
           if (!dir.exists())
               dir.mkdirs();
       }
       JarOutputStream jout = new JarOutputStream(new FileOutputStream(_dest.getFile()));
       // put all into the jar...
       add(jout, new File(_src.getFile()), "");
       jout.close();
   }
   /**
    * used by downloadAndPack
    * @param _jout
    * @param _dir
    * @param _prefix
    * @throws IOException
    */
   public static void add(JarOutputStream _jout, File _dir, String _prefix) throws IOException {
       File[] content = _dir.listFiles();
       if (_dir.isDirectory()) {
           for (int i = 0, l = content.length; i < l; ++i) {
               if (content[i].isDirectory()) {
                   _jout.putNextEntry(new ZipEntry(_prefix + (_prefix.equals("") ? "" : "/") + content[i].getName() + "/"));
                   add(_jout, content[i], _prefix + (_prefix.equals("") ? "" : "/") + content[i].getName());
               } else {
                   _jout.putNextEntry(new ZipEntry(_prefix + (_prefix.equals("") ? "" : "/") + content[i].getName()));
                   FileInputStream in = new FileInputStream(content[i]);
                   write(in, _jout);
                   in.close();
               }
           }
       } else {
           _jout.putNextEntry(new ZipEntry(_prefix + (_prefix.equals("") ? "" : "/") + _dir.getName()));
           FileInputStream in = new FileInputStream(_dir);
           write(in, _jout);
           in.close();
       }
   }
   /**
    * writes the content of the InputStream into the OutputStream
    * @param _in
    * @param _out
    * @throws IOException
    */
   private static synchronized void write(InputStream _in, OutputStream _out) throws IOException {
       byte[] buffer = new byte[1024 * 512];
       int read;
       while (true) {
           read = _in.read(buffer);
           if (read == -1)
               break;
           _out.write(buffer, 0, read);
       }
       _out.flush();
   }
   /**
    * Deletes all files and subdirectories under dir.
    * @param dir
    * @return true if all deletions were successful.If a deletion fails, the
    *         method stops attempting to delete and returns false.
    */
   public static boolean deleteDir(File dir) {
       if (dir.isDirectory()) {
           String[] children = dir.list();
           for (int i = 0; i < children.length; i++) {
               boolean success = deleteDir(new File(dir, children[i]));
               if (!success) {
                   return false;
               }
           }
       }
       // The directory is now empty so delete it
       return dir.delete();
   }
   /**
    * @param f_name : source zip file
    * @param dir_name : target dir file
    */
   public static void unpackJar(File f_name, File dir_name) throws IOException {
       unpackJar(f_name.getCanonicalPath(), dir_name.getCanonicalPath());
   }
   /**
    * @param f_name : source zip file path name
    * @param dir_name : target dir file path
    */
   public static void unpackJar(String f_name, String dir_name) throws IOException {
       BufferedInputStream bism = new BufferedInputStream(new FileInputStream(f_name));
       ZipInputStream zism = new ZipInputStream(bism);
       for (ZipEntry z = zism.getNextEntry(); z != null; z = zism.getNextEntry()) {
           File f = new File(dir_name, z.getName());
           if (z.isDirectory()) {
               f.mkdirs();
           } else {
               f.getParentFile().mkdirs();
               BufferedOutputStream bosm = new BufferedOutputStream(new FileOutputStream(f));
               int i;
               byte[] buffer = new byte[1024 * 512];
               try {
                   while ((i = zism.read(buffer, 0, buffer.length)) != -1)
                       bosm.write(buffer, 0, i);
               } catch (IOException ie) {
                   throw ie;
               }
               bosm.close();
           }
       }
       zism.close();
       bism.close();
   }
   /**
    * Unpack the jar file to a directory, till teaf files
    * @param file
    * @param file1
    * @throws IOException
    */
   public static void unpackAppJar(File file, File file1) throws IOException {
       unpackAppJar(file.getCanonicalPath(), file1.getCanonicalPath());
   }
   /**
    * Unpack the jar file to a directory, till teaf files
    * @param file The source file name
    * @param file1 The target directory
    * @author wangxp
    * @version 2003/11/07
    */
   public static void unpackAppJar(String file, String file1) throws IOException {
       // m_log.debug("unpackAppJar begin. file="+file+"|||file1="+file1);
       BufferedInputStream bufferedinputstream = new BufferedInputStream(new FileInputStream(file));
       ZipInputStream zipinputstream = new ZipInputStream(bufferedinputstream);
       byte abyte0[] = new byte[1024];
       for (ZipEntry zipentry = zipinputstream.getNextEntry(); zipentry != null; zipentry = zipinputstream.getNextEntry()) {
           File file2 = new File(file1, zipentry.getName());
           if (zipentry.isDirectory()) {
               if (!file2.exists() && !file2.mkdirs())
                   throw new IOException("Could not make directory " + file2.getPath());
           } else {
               File file3 = file2.getParentFile();
               if (file3 != null && !file3.exists() && !file3.mkdirs())
                   throw new IOException("Could not make directory " + file3.getPath());
               BufferedOutputStream bufferedoutputstream = new BufferedOutputStream(new FileOutputStream(file2));
               int i;
               try {
                   while ((i = zipinputstream.read(abyte0, 0, abyte0.length)) != -1)
                       bufferedoutputstream.write(abyte0, 0, i);
               } catch (IOException ie) {
                   ie.printStackTrace();
                   // m_logger.error(ie);
                   throw ie;
               }
               bufferedoutputstream.close();
           }
       }
       zipinputstream.close();
       bufferedinputstream.close();
       // m_log.debug("unpackAppJar end.");
   }
   /**
    * Combine several jar files and some given files into one jar file.
    * @param outJar The output jar file"s filename.
    * @param inJarsList The jar files to be combined
    * @param filter A filter that exclude some entries of input jars. User
    *        should implement the EntryFilter interface.
    * @param inFileList The files to be added into the jar file.
    * @param prefixs The prefixs of files to be added into the jar file.
    *        inFileList and prefixs should be paired.
    * @throws FileNotFoundException
    * @throws IOException
    */
   @SuppressWarnings("unchecked")
   public static void combineJars(String outJar, String[] inJarsList, EntryFilter filter, String[] inFileList, String[] prefixs)
           throws FileNotFoundException, IOException {
       JarOutputStream jout = new JarOutputStream(new FileOutputStream(outJar));
       ArrayList entryList = new ArrayList();
       for (int i = 0; i < inJarsList.length; i++) {
           BufferedInputStream bufferedinputstream = new BufferedInputStream(new FileInputStream(inJarsList[i]));
           ZipInputStream zipinputstream = new ZipInputStream(bufferedinputstream);
           byte abyte0[] = new byte[1024 * 4];
           for (ZipEntry zipentry = zipinputstream.getNextEntry(); zipentry != null; zipentry = zipinputstream.getNextEntry()) {
               if (filter.accept(zipentry)) {
                   if (!entryList.contains(zipentry.getName())) {
                       jout.putNextEntry(zipentry);
                       if (!zipentry.isDirectory()) {
                           int j;
                           try {
                               while ((j = zipinputstream.read(abyte0, 0, abyte0.length)) != -1)
                                   jout.write(abyte0, 0, j);
                           } catch (IOException ie) {
                               throw ie;
                           }
                       }
                       entryList.add(zipentry.getName());
                   }
               }
           }
           zipinputstream.close();
           bufferedinputstream.close();
       }
       for (int i = 0; i < inFileList.length; i++) {
           add(jout, new File(inFileList[i]), prefixs[i]);
       }
       jout.close();
   }
   /**
    * Test
    * @param args
    * @throws Exception
    */
   public static void main(String args[]) throws Exception {
       String[] in = new String[2];
       in[1] = "E:\\pkuas03\\pkuas_51\\repository\\deployed\\ecperf.ear\\corp.jar";
       in[0] = "E:\\pkuas03\\pkuas_51\\repository\\deployed\\ecperf.ear\\orders.jar";
       String[] fs = new String[1];
       fs[0] = "E:\\pkuas03\\pkuas_51\\repository\\deployed\\ecperf.ear\\META-INF\\application.xml";
       String[] pres = new String[1];
       pres[0] = "META-INF";
       combineJars("e:\\111.jar", in, new EntryFilter() {
           public boolean accept(ZipEntry entry) {
               if (entry.getName().endsWith("ejb-jar.xml"))
                   return false;
               return true;
           }
       }, fs, pres);
   }
   interface EntryFilter {
       public boolean accept(ZipEntry entry);
   }

}


 </source>
   
  
 
  



InstallJars - a utility to download and install files, Jars and Zips.

   <source lang="java">
 

/*******************************************************************************

* Copyright (c) 2004, 2008 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation                                       
*******************************************************************************/

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; import java.net.URLConnection; import java.util.Iterator; import java.util.Properties; import java.util.StringTokenizer; import java.util.zip.GZIPInputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; /*******************************************************************************

* * InstallJars - a utility to download and install files, Jars and Zips. * *
* 
* @author Barry Feigenbaum, Ph.D. *
******************************************************************************/

public class InstallJars {

 public static final int BLOCK_SIZE = 512;
 public static final int BLOCK_COUNT = 20;
 // *** must be a multiple of BLOCK_SIZE ***
 public static int bufferSize = 128 * (2 * BLOCK_SIZE);
 // *** need to NLS enable all user messages ***
 /**
  * Constructor. Expand, run and verbose output requested.
  */
 public InstallJars() {
   this(true, true, true, "InstallJars.properties", "cmd /c java");
 }
 /**
  * Contstructor.
  * 
  * @param expand
  *          true if the archive is t be expanded in the target
  * @param verbose
  *          true if messages are to be generated
  * @param run
  *          true if file is to be executed
  * @param propName
  *          properties file with items to install
  * @param javaParams
  *          java parameters
  */
 public InstallJars(boolean expand, boolean verbose, boolean run, String propName,
     String javaParams) {
   setExpand(expand);
   setVerbose(verbose);
   setRunMode(run);
   setPropFilename(propName);
   setJavaParams(javaParams);
 }
 protected boolean verbose;
 /**
  * Get the verbose mode state.
  * 
  * @return is in verbose mode
  */
 public boolean getVerbose() {
   return verbose;
 }
 /**
  * Set the verbose mode state.
  * 
  * @param f
  *          value
  */
 public void setVerbose(boolean f) {
   verbose = f;
 }
 protected boolean run;
 /**
  * Get the run mode state.
  * 
  * @return is in run mode
  */
 public boolean getRunMode() {
   return run;
 }
 /**
  * Set the run mode state.
  * 
  * @param f
  *          value
  */
 public void setRunMode(boolean f) {
   run = f;
 }
 protected boolean expand;
 /**
  * Get the expand mode state.
  * 
  * @return is expanded
  */
 public boolean getExpand() {
   return expand;
 }
 /**
  * Set the expand mode state.
  * 
  * @param f
  *          value
  */
 public void setExpand(boolean f) {
   expand = f;
 }
 protected String propFilename;
 /**
  * Get the propFilename mode state.
  * 
  * @return prooperty file name
  */
 public String getPropFilename() {
   return propFilename;
 }
 /**
  * Set the propFilename mode state.
  * 
  * @param name
  */
 public void setPropFilename(String name) {
   propFilename = name;
 }
 protected String javaParams = "cmd /c java";
 /**
  * Get the JavaParams mode state.
  * 
  * @return java parameters
  */
 public String getJavaParams() {
   return javaParams;
 }
 /**
  * Set the JavaParams mode state.
  * 
  * @param p
  *          value
  */
 public void setJavaParams(String p) {
   javaParams = p;
 }
 protected void print(String s) {
   if (verbose) {
     System.out.print(s);
   }
 }
 protected void println(String s) {
   if (verbose) {
     System.out.println(s);
   }
 }
 protected void println() {
   println("");
 }
 /**
  * Install based on a properties file
* * @return recommended classpath * @exception IOException * Thrown if a JAR file access error occurs */ public String install() throws IOException { StringBuffer classpath = new StringBuffer(); Properties prop = new Properties(); prop.load(new BufferedInputStream(new FileInputStream(propFilename))); for (Iterator i = prop.keySet().iterator(); i.hasNext();) { String key = (String) i.next(); String value = prop.getProperty(key); String xurl = null; String xdir = null; String xcp = null; boolean xexpand = expand, xrun = run; if (value != null) { value = value.trim(); if (value.length() > 0) { String delim = value.substring(0, 1); StringTokenizer st = new StringTokenizer(value.substring(1), delim); xurl = st.nextToken(); xdir = (st.hasMoreTokens() ? st.nextToken() : ".").trim(); if (xdir.length() == 0) { xdir = "."; } xcp = (st.hasMoreTokens() ? st.nextToken() : xdir).trim(); if (xcp.length() == 0) { xcp = xdir; } classpath.append(xcp); classpath.append(";"); while (st.hasMoreTokens()) { String xoption = st.nextToken().trim(); if (xoption.equalsIgnoreCase("expand")) { xexpand = true; } else if (xoption.equalsIgnoreCase("noexpand")) { xexpand = false; } else if (xoption.equalsIgnoreCase("run")) { xrun = true; } else if (xoption.equalsIgnoreCase("norun")) { xrun = false; } else { throw new IllegalArgumentException("invalid install property - " + key + "=" + value); } } } } if (xurl == null || xurl.length() == 0) { throw new IllegalArgumentException("missing install property - " + key + "=" + value); } System.out.print("\nInstalling " + key); if (verbose) { System.out.print(" using URL=" + xurl + "; target=" + xdir + "; classpath=" + xcp + "; " + (xexpand ? "expand" : "noexpand") + "; " + (xrun ? "run" : "norun")); } System.out.println("..."); installFile(xurl, xdir, xexpand, xrun); } return classpath.toString(); } /** * Install a Zip/Jar file. * * @param fileUrl * The file/zip/jar file * @param targetPath * root of directory or file to install into * @param doExpand * @param doRun * @exception IOException * Thrown if a JAR file access error occurs */ public void installFile(String fileUrl, String targetPath, boolean doExpand, boolean doRun) throws IOException { String targetFilename = new File(targetPath).getCanonicalPath().replace("\\", "/"); println("Installing in " + targetFilename); URL url = new URL(fileUrl); URLConnection conn = url.openConnection(); // System.out.println("Conn = " + conn); String ctype = conn.getContentType(); println("Content type is " + ctype); String extension = getExtension(fileUrl); if (extension.equals("class")) { installClass(conn, targetFilename, doExpand, doRun); // println("Installed class file " + fileUrl + "; please run"); } else if (extension.equalsIgnoreCase("zip")) { installZip(conn, targetFilename, doExpand, doRun); // println("Installed ZIP file " + fileUrl + "; ZIP expanded"); } else if (extension.equalsIgnoreCase("gz")) { installGZip(conn, targetFilename, doExpand, doRun); // println("Installed GZIP file " + fileUrl + "; ZIP expanded"); } else if (extension.equalsIgnoreCase("jar")) { installJar(conn, targetFilename, doExpand, doRun); // System.out.println("Installed JAR file " + fileUrl + "; please add to // CLASSPATH"); } else { throw new IllegalArgumentException("Unknown extension - " + extension); } } public void installClass(URLConnection conn, String target, boolean doExpand, boolean doRun) throws IOException { // doExpand not used on htis type print("Installing class file " + target + " from " + conn.getURL().toExternalForm()); copyStream(conn, target); println(); if (doRun) { runTarget(target, false); } } protected void runTarget(String target, boolean isJar) throws IOException { // *** add run code *** if (isJar) { System.out.println("runTarget(" + target + "," + isJar + ") not currently implemented"); } else { try { String name = removeExtension(getFile(target)); String cp = "-cp " + removeFile(target); String command = javaParams + " " + cp + " " + name + " >" + name + ".out 2>" + name + ".err"; // String command = javaParams + " " + cp + " " + name; System.out.println("Running " + command + "..."); Process p = Runtime.getRuntime().exec(command); int rc = p.waitFor(); System.out.println("Return code=" + rc); } catch (Exception e) { System.out.println("Exception - " + e.getMessage()); } } } public void installJar(URLConnection conn, String target, boolean doExpand, boolean doRun) throws IOException { if (doExpand) { println("Expanding JAR file " + target + " from " + conn.getURL().toExternalForm()); // *** may need to specialize for JAR format *** ZipInputStream zis = new ZipInputStream(new BufferedInputStream(conn.getInputStream(), BLOCK_SIZE * BLOCK_COUNT)); int count = 0; prepDirs(target, true); try { while (zis.available() > 0) { ZipEntry ze = zis.getNextEntry(); copyEntry(target, zis, ze); count++; } } finally { try { zis.close(); } catch (IOException ioe) { } } println("Installed " + count + " files/directories"); } else { print("Installing JAR file " + target + " from " + conn.getURL().toExternalForm()); copyStream(conn, target); println(); if (doRun) { runTarget(target, true); } } } public void installZip(URLConnection conn, String target, boolean doExpand, boolean doRun) throws IOException { // doRun not used on htis type if (doExpand) { String ctype = conn.getContentType(); if (!ctype.equals("application/zip")) { throw new IllegalArgumentException("Unkexpected content type - " + ctype); } println("Expanding ZIP file to " + target + " from " + conn.getURL().toExternalForm()); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(conn.getInputStream(), BLOCK_SIZE * BLOCK_COUNT)); int count = 0; prepDirs(target, true); try { for (ZipEntry ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry()) { copyEntry(target, zis, ze); // zis.closeEntry(); count++; } } finally { try { zis.close(); } catch (IOException ioe) { } } println("Installed " + count + " files/directories"); } else { print("Installing ZIP file " + target + " from " + conn.getURL().toExternalForm()); copyStream(conn, target); println(); } } public void installGZip(URLConnection conn, String target, boolean doExpand, boolean doRun) throws IOException { // doRun not used on htis type if (doExpand) { String ctype = conn.getContentType(); if (!ctype.equals("application/x-tar")) { throw new IllegalArgumentException("Unkexpected content type - " + ctype); } print("Expanding GZIP file to " + target + " from " + conn.getURL().toExternalForm()); prepDirs(target, false); GZIPInputStream zis = new GZIPInputStream(new BufferedInputStream(conn.getInputStream(), BLOCK_SIZE * BLOCK_COUNT)); try { // BufferedOutputStream os = new BufferedOutputStream(new // FileOutputStream(target), BLOCK_SIZE * BLOCK_COUNT); // try { // byte[] buf = new byte[bufferSize]; // for (int size = zis.read(buf, 0, buf.length), count = 0; // size >= 0; // size = zis.read(buf, 0, buf.length), count++) { // //if (count % 4 == 0) print("."); // os.write(buf, 0, size); // } // } // finally { // try { os.flush(); os.close(); } catch (IOException ioe) {} // } pumpGZip(target, zis); } finally { try { zis.close(); } catch (IOException ioe) { } } println(); } else { print("Installing GZIP file " + target + " from " + conn.getURL().toExternalForm()); copyStream(conn, target); println(); } } /** Copy a zip entry. */ protected void copyEntry(String target, ZipInputStream zis, ZipEntry ze) throws IOException { String name = ze.getName(); boolean isDir = false; if (name.endsWith("/")) { name = name.substring(0, name.length() - 1); isDir = true; } String path = target + File.separator + name; path = path.replace("\\", "/"); String mod = ze.getSize() > 0 ? ("[" + ze.getCompressedSize() + ":" + ze.getSize() + "]") : ""; print("Expanding " + ze + mod + " to " + path); prepDirs(path, isDir); if (!isDir) { BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(path), BLOCK_SIZE * BLOCK_COUNT); try { byte[] buf = new byte[bufferSize]; for (int size = zis.read(buf, 0, buf.length), count = 0; size >= 0; size = zis.read(buf, 0, buf.length), count++) { // if (count % 4 == 0) print("."); os.write(buf, 0, size); } } finally { try { os.flush(); os.close(); } catch (IOException ioe) { } } } println(); } public void copyStream(URLConnection conn, String target) throws IOException { prepDirs(target, false); BufferedInputStream is = new BufferedInputStream(conn.getInputStream(), BLOCK_SIZE * BLOCK_COUNT); BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(target), BLOCK_SIZE * BLOCK_COUNT); byte[] buf = new byte[bufferSize]; for (int size = is.read(buf), count = 0; size >= 0; size = is.read(buf), count++) { // if (count % 4 == 0) print("."); os.write(buf, 0, size); } os.flush(); os.close(); is.close(); } protected static final int OFFSET_NAME = 0; protected static final int OFFSET_MODE = OFFSET_NAME + 100; protected static final int OFFSET_UID = OFFSET_MODE + 8; protected static final int OFFSET_GID = OFFSET_UID + 8; protected static final int OFFSET_SIZE = OFFSET_GID + 8; protected static final int OFFSET_MTIME = OFFSET_SIZE + 12; protected static final int OFFSET_CHKSUM = OFFSET_MTIME + 12; protected static final int OFFSET_TYPE = OFFSET_CHKSUM + 8; protected static final int OFFSET_LINKNAME = OFFSET_TYPE + 1; protected static final int OFFSET_MAGIC = OFFSET_LINKNAME + 100; protected static final int OFFSET_VERSION = OFFSET_MAGIC + 6; protected static final int OFFSET_UNAME = OFFSET_VERSION + 2; protected static final int OFFSET_GNAME = OFFSET_UNAME + 32; protected static final int OFFSET_DEVMAJOR = OFFSET_GNAME + 32; protected static final int OFFSET_DEVMINOR = OFFSET_DEVMAJOR + 8; protected static final int OFFSET_PREFIX = OFFSET_DEVMINOR + 8; protected static final int OFFSET_END = OFFSET_PREFIX + 155; protected static final String MAGIC = "USTAR"; protected void pumpGZip(String target, GZIPInputStream zis) throws IOException { String curName = null; long curSize = 0, remainingSize = 0; char curType = 0; int curMajor = 0, curMinor = 0; boolean inFile = false; BufferedOutputStream curOs = null; int instFiles = 0, instDirs = 0; byte[] buf = new byte[bufferSize]; top: while (true) { int loaded = loadBytes(buf, zis); if (loaded < 0) { break; } // System.out.println("pumpGZip: loaded=" + loaded); // process each buffer of data for (int index = 0; index < loaded; index += BLOCK_SIZE) { // System.out.println("pumpGZip: infile=" + inFile + ", remaining=" + // remainingSize); if (inFile && remainingSize > 0) { // process body part int xsize = Math.min((int) remainingSize, BLOCK_SIZE); if (curOs != null) { curOs.write(buf, index, xsize); } remainingSize -= xsize; } else { // process header block if (inFile) { inFile = false; if (curOs != null) { try { curOs.flush(); curOs.close(); } catch (IOException ioe) { } println(); } } if (isEmptyBlock(buf, index)) { // check logical end of archive break top; } // System.out.println("pumpGZip: header=" + (new String(buf, 0, index, // 512))); curName = extractString(buf, index + OFFSET_NAME, 100); curType = extractChar(buf, index + OFFSET_TYPE); curSize = extractLong(buf, index + OFFSET_SIZE, 12); remainingSize = curSize; if (remainingSize > Integer.MAX_VALUE) { throw new IOException("entry size too large - " + remainingSize); } String mod = ""; String magic = extractString(buf, index + OFFSET_MAGIC, 6); if (magic.equals(MAGIC)) { curName = extractString(buf, index + OFFSET_PREFIX, 155) + curName; extractInt(buf, index + OFFSET_VERSION, 2); curMajor = extractInt(buf, index + OFFSET_DEVMAJOR, 8); curMinor = extractInt(buf, index + OFFSET_DEVMINOR, 8); if (curMajor > 0 || curMinor > 0) { mod = "[" + curMajor + "." + curMinor + "]"; } } // System.out.println("pumpGZip: " + // magic + "," + // curName + "," + // curType + "," + // curSize + "," + // curVersion + "," + // curMajor + "," + // curMinor); String path = target + File.separator + curName; path = path.replace("\\", "/"); curOs = null; if (curType == 0 || curType == "0") { // a file print("Copying " + curName + mod + " to " + path); prepDirs(path, false); curOs = new BufferedOutputStream(new FileOutputStream(path), BLOCK_SIZE * BLOCK_COUNT); inFile = true; instFiles++; } else if (curType == "1" || curType == "2") { // a link if (curSize > 0) { throw new IOException("link entries cannot have content - " + curSize); } println("Link ignored - " + curName + mod); } else if (curType == "5") { // a directory if (path.endsWith("/")) { path = path.substring(0, path.length() - 1); } println("Mkdir " + curName + mod + " to " + path); prepDirs(path, true); instDirs++; } else { if (curSize > 0) { // throw new IOException("entry type " + curType + " cannot have a // content - size=" + curSize); inFile = true; } print("Entry type " + curType + " ignored - " + curName + mod); } } } } println("Installed " + instFiles + " files and " + instDirs + " directories"); } protected int loadBytes(byte[] buf, GZIPInputStream zis) throws IOException { int loaded = -1; for (int size = zis.read(buf, 0, buf.length), count = 0; size > 0; size = zis.read(buf, loaded, buf.length - loaded), count++) { // if (count % 4 == 0) print("."); // System.out.println("loadBytes: loaded=" + loaded); if (loaded < 0) { loaded = 0; } loaded += size; } return loaded; } protected boolean isEmptyBlock(byte[] buf, int index) { boolean r = true; for (int i = 0; r && i < BLOCK_SIZE; i++) { r = buf[index++] == 0; } // System.out.println("isEmptyBlock: " + r); return r; } protected char extractChar(byte[] buf, int index) throws IOException { return (char) buf[index]; } protected int extractInt(byte[] buf, int index, int length) throws IOException { return (int) extractLong(buf, index, length); } protected long extractLong(byte[] buf, int index, int length) throws IOException { String xsize = extractString(buf, index, length); long v = 0; for (int i = 0; i < xsize.length(); i++) { char c = xsize.charAt(i); if (c != " ") { if (c < "0" || c > "7") { throw new IOException("non-octal digit found - " + c); } v = v * 8 + (c - "0"); } } return v; } protected String extractString(byte[] buf, int index, int length) throws IOException { StringBuffer sb = new StringBuffer(); for (int i = 0, xindex = index; i < length; i++, xindex++) { int c = buf[xindex]; if (c == 0) { break; } sb.append((char) c); } // System.out.println("extractString(" + index + "," + length + "): " + // sb.toString()); return sb.toString(); } protected String getFile(String name) { int posn = name.lastIndexOf("/"); return posn > 0 ? name.substring(posn + 1) : name; } protected String removeFile(String name) { int posn = name.lastIndexOf("/"); return posn > 0 ? name.substring(0, posn) : name; } protected String removeExtension(String name) { int posn1 = name.lastIndexOf("/"); int posn2 = name.lastIndexOf("."); return (posn2 > 0 && posn2 > posn1) ? name.substring(0, posn2) : name; } protected String extraceFile(String name) { int posn = name.lastIndexOf(File.separator); return posn >= 0 ? name.substring(posn + 1) : null; } protected String getExtension(String name) { int posn = name.lastIndexOf("."); return posn >= 0 ? name.substring(posn + 1) : ""; } protected void prepDirs(String name) { prepDirs(name, expand); } protected void prepDirs(String name, boolean includeLast) { File f = new File(includeLast ? name : removeFile(name)); // System.out.print("(Making " + f + ")"); f.mkdirs(); } protected void printUsage() { println("Effective command: " + getClass().getName() + " " + propFilename + (expand ? " -expand" : " -noexpand") + (run ? " -run" : " -norun") + " -java \"" + javaParams + "\"" + (verbose ? " -verbose" : " -quiet ")); } /** Print command help text. */ protected static void printHelp() { System.out.println(); System.out .println("Usage: java " + InstallJars.class.getName() + " {propFilename} {-expand | -noexpand} {-run | -norun} {-quiet | -verbose} {-java <params>}"); System.out.println("Where:"); System.out .println(" propFilename path to properties file (default=InstallJars.properties)"); System.out.println(" -expand expand any top level JAR/ZIP/GZIP (default)"); System.out.println(" -noexpand do not expand any top level JAR/ZIP/GZIP"); System.out.println(" -run run class or JAR files (default)"); System.out.println(" -norun do not run class or JAR files"); System.out.println(" -verbose output progress messages (default)"); System.out.println(" -quiet suppress most messages"); System.out.println(" -java sets java runtime paramters"); System.out.println(); System.out.println("Properties file entry format: name=!url{!target{!classpath{!option}...}}"); System.out.println("Where:"); System.out.println(" name name displayed while installing"); System.out.println(" url source of items to download and install"); System.out.println(" target root of install directory or file (default=.)"); System.out .println(" classpath class path entry to use for this directrory or file (default=target}"); System.out.println(" option one of the following options: expand, noexpand, run, norun"); System.out.println(" if omitted, the command line default is used"); System.out.println("! is a delimiter, the first non-whitespace character is used."); System.out.println("Options expand and run may not apply to all types of files."); } /** * Main command line entry point. * * @param args */ public static void main(final String[] args) { if (args.length == 0) { printHelp(); System.exit(0); } String propName = null; boolean expand = true; boolean verbose = true; boolean run = true; String params = "cmd /c java"; // process arguments for (int i = 0; i < args.length; i++) { String arg = args[i]; if (arg.charAt(0) == "-") { // switch arg = arg.substring(1); if (arg.equalsIgnoreCase("quiet")) { verbose = false; } else if (arg.equalsIgnoreCase("verbose")) { verbose = true; } else if (arg.equalsIgnoreCase("expand")) { expand = true; } else if (arg.equalsIgnoreCase("noexpand")) { expand = false; } else if (arg.equalsIgnoreCase("run")) { run = true; } else if (arg.equalsIgnoreCase("norun")) { run = false; } else if (arg.equalsIgnoreCase("java")) { run = false; if (i < args.length - 1) { params = args[++i]; } } else { System.err.println("Invalid switch - " + arg); System.exit(1); } } else { if (propName == null) { propName = arg; } else { System.err.println("Too many parameters - " + arg); System.exit(1); } } } if (propName == null) { propName = "InstallJars.properties"; } // do the install try { InstallJars ij = new InstallJars(expand, verbose, run, propName, params); ij.printUsage(); String cp = ij.install(); System.out.println("\nRecomended additions to your classpath - " + cp); } catch (Exception e) { System.err.println("\n" + e.getClass().getName() + ": " + e.getMessage()); if (verbose) { e.printStackTrace(); // *** debug *** } System.exit(2); } }

}


 </source>
   
  
 
  



JAR Archives: Jar Lister

   <source lang="java">
   

import java.io.IOException; import java.util.Date; import java.util.Enumeration; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; public class Main {

 public static void main(String[] args) throws IOException {
   JarFile jf = new JarFile("a.jar");
   Enumeration e = jf.entries();
   while (e.hasMoreElements()) {
     JarEntry je = (JarEntry) e.nextElement();
     System.out.println(je.getName());
     long uncompressedSize = je.getSize();
     long compressedSize = je.getCompressedSize();
     long crc = je.getCrc();
     int method = je.getMethod();
     String comment = je.getComment();
     System.out.println(new Date(je.getTime()));
     System.out.println("from  " + uncompressedSize + " bytes to "+ compressedSize);
     if (method == ZipEntry.STORED) {
       System.out.println("ZipEntry.STORED");
     }
     else if (method == ZipEntry.DEFLATED) {
       System.out.println(ZipEntry.DEFLATED);
     }
     System.out.println("Its CRC is " + crc);
     System.out.println(comment);
     System.out.println(je.isDirectory());
     
     Attributes a = je.getAttributes();
     if (a != null) {
       Object[] nameValuePairs = a.entrySet().toArray();
       for (int j = 0; j < nameValuePairs.length; j++) {
         System.out.println(nameValuePairs[j]);
       }
     }
     System.out.println();
   }
 }

}



 </source>
   
  
 
  



JAR Archives: Packer200

   <source lang="java">
   

import java.io.FileOutputStream; import java.io.OutputStream; import java.util.jar.JarFile; import java.util.jar.Pack200; public class Main {

 public static void main(String[] args) throws Exception {
   JarFile f = new JarFile("a.jar");
   Pack200.Packer packer = Pack200.newPacker();
   OutputStream out = new FileOutputStream("a.pack");
   packer.pack(f, out);
   out.close();
 }

}



 </source>
   
  
 
  



JAR Archives: Unpacker200

   <source lang="java">
   

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.util.jar.JarOutputStream; import java.util.jar.Pack200; import java.util.zip.GZIPInputStream; public class Main {

 public static void main(String[] args) throws Exception {
   String inName = "a.pack.gz";
   String outName = "a.unpacked";
   Pack200.Unpacker unpacker = Pack200.newUnpacker();
   JarOutputStream out = new JarOutputStream(new FileOutputStream(outName));
   InputStream in = new FileInputStream(inName);
   in = new GZIPInputStream(in);
   unpacker.unpack(in, out);
   out.close();
 }

}



 </source>
   
  
 
  



Jar builder

   <source lang="java">
  

/*BEGIN_COPYRIGHT_BLOCK

*
* Copyright (c) 2001-2008, JavaPLT group at Rice University (drjava@rice.edu)
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*    * Redistributions of source code must retain the above copyright
*      notice, this list of conditions and the following disclaimer.
*    * Redistributions in binary form must reproduce the above copyright
*      notice, this list of conditions and the following disclaimer in the
*      documentation and/or other materials provided with the distribution.
*    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
*      names of its contributors may be used to endorse or promote products
*      derived from this software without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software is Open Source Initiative approved Open Source Software.
* Open Source Initative Approved is a trademark of the Open Source Initiative.
* 
* This file is part of DrJava.  Download the current version of this project
* from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
* 
* END_COPYRIGHT_BLOCK*/

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; public class JarBuilder {

 private JarOutputStream _output;
 
 /** Creates a file file without a manifest
  *
  * @param file the file to write the jar to
  * @throws IOException thrown if the file cannot be opened for writing
  */
 public JarBuilder(File file) throws IOException {
   _output = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(file)), ManifestWriter.DEFAULT);
 }
 
 /** Creates an empty jar file with the given manifest
  *
  * @param jar      the file to write the jar to
  * @param manifest the file that is the manifest for the archive
  * @throws IOException thrown if either file cannot be opened for reading
  */
 public JarBuilder(File jar, File manifest) throws IOException {
   _output = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(jar)), new Manifest(new FileInputStream(manifest)));
 }
 
 /** Creates an empty jar file with the given manifest
  *
  * @param jar      the file to write the jar to
  * @param manifest the manifest file for the jar
  * @see ManifestWriter
  */
 public JarBuilder(File jar, Manifest manifest) {
   try {
     _output = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(jar)), manifest);
   }
   catch (IOException e) {
     e.printStackTrace();
   }
 }
 
 /** Takes a parent name and a field name and returns the concatenation of them correctly
  *
  * @param parent The parent directory
  * @param name   The name of the file or directory
  * @return the string concatenation of the parent and the name
  */
 private String makeName(String parent, String name) {
   String sep = "/"; // NOTE: This can be a "/" since it is a path in the jar file itself
   if( parent.equals("") )
     return name;
   if (parent.endsWith(sep))
     return parent + name;
   return parent + sep + name;
 }
 
 /** Adds the file to the given path and name
  *
  * @param file     the file to be added
  * @param parent   the directory to the path in which the file is to be added
  * @param fileName the name of the file in the archive
  */
 public void addFile(File file, String parent, String fileName) throws IOException {
   byte data[] = new byte[2048];
   
   FileInputStream fi = new FileInputStream(file.getAbsolutePath());
   BufferedInputStream origin = new BufferedInputStream(fi, 2048);
   
   JarEntry entry = new JarEntry(makeName(parent, fileName));
   _output.putNextEntry(entry);
   
   int count = origin.read(data, 0, 2048);
   while (count != -1) {
     _output.write(data, 0, count);
     count = origin.read(data, 0, 2048);
   }
   
   origin.close();
 }
 
 /** Add the directory into the directory specified by parent
   * @param dir the directory to add
   * @param parent the path inside the jar that the directory should be added to
   */
 public void addDirectoryRecursive(File dir, String parent) {
   addDirectoryRecursiveHelper(dir, parent, new byte[2048], new FileFilter() {
     public boolean accept(File pathname) { return true; }
   });
 }
 
 /** Add the directory into the directory specified by parent
   * @param dir the directory to add
   * @param parent the path inside the jar that the directory should be added to
   * @param filter the filter used to filter the files
   */
 public void addDirectoryRecursive(File dir, String parent, FileFilter filter) {
   addDirectoryRecursiveHelper(dir, parent, new byte[2048], filter);
 }
 
 /** Add the contents of a directory that match a filter to the archive
  * @param dir the directory to add
  * @param parent the directory to add into
  * @param buffer a buffer that is 2048 bytes
  * @param filter the FileFilter to filter the files by
  * @return true on success, false on failure
  */
 private boolean addDirectoryRecursiveHelper(File dir, String parent, byte[] buffer, FileFilter filter) {
   try {
     File[] files = dir.listFiles(filter);
     BufferedInputStream origin = null;
     
     if( files == null ) // listFiles may return null if there"s an IO error
       return true;
     for (int i = 0; i < files.length; i++) {
       if( files[i].isFile() ) {
         origin = new BufferedInputStream(new FileInputStream(files[i]), 2048);
         
         JarEntry entry = new JarEntry(makeName(parent, files[i].getName()));
         _output.putNextEntry(entry);
         
         int count;
         while((count = origin.read(buffer, 0, 2048)) != -1) {
           _output.write(buffer, 0, count);
         }
         origin.close();
       }
       else if( files[i].isDirectory() ) {
         addDirectoryRecursiveHelper(files[i], makeName(parent, files[i].getName()),buffer,filter);
       }
     }
   } catch(Exception e) {
     e.printStackTrace();
   }
   return true;
 }
 
 /** Makes a directory in the jar file
  *
  * @param parent  The name of the parent that the directory is to be created in
  * @param dirName The name of the directory to be created
  * @return Returns true on success, false on failure
  */
 public boolean makeDirectory(String parent, String dirName) {
   JarEntry entry = new JarEntry(makeName(parent, dirName));
   try {
     _output.putNextEntry(entry);
   }
   catch (IOException e) {
     return false;
   }
   return true;
 }
 
 /** Close writing on the jar file
  */
 public void close() throws IOException {
   _output.flush();
   _output.close();
 }

} class ManifestWriter {

 private List<String> _classPaths;
 private String _mainClass;
 private String _rawManifest;
 public static final Manifest DEFAULT = new ManifestWriter().getManifest();
 
 /** Create a new manifest file */
 public ManifestWriter() {
   _classPaths = new LinkedList<String>();
   _mainClass = null;
   _rawManifest = null;
 }
 
 /** Add a class path to the Manifest
   * @param path the path to be added
   */
 public void addClassPath(String path) {
   _classPaths.add(_classPaths.size(), path);
 }
 
 /** Set the main class of the Manifest
   * @param mainClass
   */
 public void setMainClass(String mainClass) {
   _mainClass = mainClass;
   _rawManifest = null;
 }
 
 public void setManifestContents(String rawManifest) {
   _rawManifest =  rawManifest;
   _mainClass = null;
 }
 
 /** Get an input stream to the contents of the manifest file
   * @return an InputStream whose contents are the contents of the Manifest file
   */
 protected InputStream getInputStream() {
   // NOTE: All significant lines in the manifest MUST end in the end of line character
   
   final StringBuilder sbuf = new StringBuilder();
   sbuf.append(Attributes.Name.MANIFEST_VERSION.toString());
   sbuf.append(": 1.0" + "\n");
   if( !_classPaths.isEmpty() ) {
     Iterator<String> iter = _classPaths.iterator();
     sbuf.append(Attributes.Name.CLASS_PATH.toString());
     sbuf.append(":");
     while (iter.hasNext()) {
       sbuf.append(" ");
       sbuf.append(iter.next());
     }
     sbuf.append("\n");
   }
   if( _mainClass != null ) {
     sbuf.append(Attributes.Name.MAIN_CLASS.toString());
     sbuf.append(": ");
     sbuf.append(_mainClass);
     sbuf.append("\n");
   }
   
   if(_rawManifest != null) {
     sbuf.append(_rawManifest); 
     
     if(!_rawManifest.endsWith("\n"))
       sbuf.append("\n");
   }
   
   try { return new ByteArrayInputStream(sbuf.toString().getBytes("UTF-8")); }
   catch (UnsupportedEncodingException e) { throw new RuntimeException(e); }
 }
 
 /** Get the Manifest object that this object created.
   * @return the Manifest that this builder created
   */
 public Manifest getManifest() {
   try {
     Manifest m = new Manifest();
     m.read(getInputStream());
     return m;
   }
   catch (IOException e) {
     e.printStackTrace();
     return null;
   }
 }

}


 </source>
   
  
 
  



Jar Entry OutputStream

   <source lang="java">
  

/*

* The contents of this file are subject to the Sapient Public License
* Version 1.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://carbon.sf.net/License.html.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The Original Code is The Carbon Component Framework.
*
* The Initial Developer of the Original Code is Sapient Corporation
*
* Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
*/

import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.StringTokenizer; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import java.util.zip.ZipEntry; import sun.rmi.runtime.Log; /**

* An output stream that is used by EnhancedJarFile to write entries to a jar.
* This implementation uses a ByteArrayOutputStream to buffer the output
* until the stream is closed.  When the stream is closed, the output is written
* to the jar.
*
* Copyright 2002 Sapient
* @since carbon 1.0
* @author Douglas Voet, April 2002
* @version $Revision: 1.9 $($Author: dvoet $ / $Date: 2003/05/05 21:21:23 $)
*/

public class JarEntryOutputStream extends ByteArrayOutputStream {

   private EnhancedJarFile jar;
   private String jarEntryName;
   /**
    * Constructor
    *
    * @param jar the EnhancedJarFile that this instance will write to
    * @param jarEntryName the name of the entry to be written
    */
   public JarEntryOutputStream(
       EnhancedJarFile jar,
       String jarEntryName) {
       super();
       this.jarEntryName = jarEntryName;
       this.jar = jar;
   }
   /**
    * Closes the stream and writes entry to the jar
    */
   public void close() throws IOException {
       writeToJar();
       super.close();
   }
   /**
    * Writes the entry to a the jar file.  This is done by creating a
    * temporary jar file, copying the contents of the existing jar to the
    * temp jar, skipping the entry named by this.jarEntryName if it exists.
    * Then, if the stream was written to, then contents are written as a
    * new entry.  Last, a callback is made to the EnhancedJarFile to
    * swap the temp jar in for the old jar.
    */
   private void writeToJar() throws IOException {
       File jarDir = new File(this.jar.getName()).getParentFile();
       // create new jar
       File newJarFile = File.createTempFile("config", ".jar", jarDir);
       newJarFile.deleteOnExit();
       JarOutputStream jarOutputStream =
           new JarOutputStream(new FileOutputStream(newJarFile));
       try {
           Enumeration entries = this.jar.entries();
           // copy all current entries into the new jar
           while (entries.hasMoreElements()) {
               JarEntry nextEntry = (JarEntry) entries.nextElement();
               // skip the entry named jarEntryName
               if (!this.jarEntryName.equals(nextEntry.getName())) {
                   // the next 3 lines of code are a work around for
                   // bug 4682202 in the java.sun.ru bug parade, see:
                   // http://developer.java.sun.ru/developer/bugParade/bugs/4682202.html
                   JarEntry entryCopy = new JarEntry(nextEntry);
                   entryCopy.setCompressedSize(-1);
                   jarOutputStream.putNextEntry(entryCopy);
                   InputStream intputStream =
                       this.jar.getInputStream(nextEntry);
                   // write the data
                   for (int data = intputStream.read();
                       data != -1;
                       data = intputStream.read()) {
                       jarOutputStream.write(data);
                   }
               }
           }
           // write the new or modified entry to the jar
           if (size() > 0) {
               jarOutputStream.putNextEntry(new JarEntry(this.jarEntryName));
               jarOutputStream.write(super.buf, 0, size());
               jarOutputStream.closeEntry();
           }
       } finally {
           // close close everything up
           try {
               if (jarOutputStream != null) {
                   jarOutputStream.close();
               }
           } catch (IOException ioe) {
               // eat it, just wanted to close stream
           }
       }
       // swap the jar
       this.jar.swapJars(newJarFile);
   }

} /*

* The contents of this file are subject to the Sapient Public License
* Version 1.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://carbon.sf.net/License.html.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The Original Code is The Carbon Component Framework.
*
* The Initial Developer of the Original Code is Sapient Corporation
*
* Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
*/

/**

* This class enhances functionality of java.util.jar.JarFile.
* Additional functionality includes jar entry removal, the ability to list
* the entries within a directory within the jar, and the ability to get
* an output stream for modifying extisting entries.
*
* @see java.util.jar.JarFile
*
* Copyright 2002 Sapient
* @since carbon 1.0
* @author Doug Voet, April 2002
* @version $Revision: 1.11 $ ($Author: dvoet $)
*/

class EnhancedJarFile {

   public static final String JAR_DELIMETER = "/";

   private JarFile jar;
   /**
    * @see java.util.jar.JarFile#JarFile(java.lang.String)
    */
   public EnhancedJarFile(String name) throws IOException {
       this.jar = new JarFile(name);
   }
   /**
    * @see java.util.jar.JarFile#JarFile(java.lang.String, boolean)
    */
   public EnhancedJarFile(String name, boolean verify) throws IOException {
       this.jar = new JarFile(name, verify);
   }
   /**
    * @see java.util.jar.JarFile#JarFile(java.io.File)
    */
   public EnhancedJarFile(File file) throws IOException {
       this.jar = new JarFile(file);
   }
   /**
    * @see java.util.jar.JarFile#JarFile(java.io.File, boolean)
    */
   public EnhancedJarFile(File file, boolean verify) throws IOException {
       this.jar = new JarFile(file, verify);
   }
   /**
    * @see java.util.jar.JarFile#JarFile(java.io.File, boolean, int)
    */
   public EnhancedJarFile(File file, boolean verify, int mode)
       throws IOException {
       this.jar = new JarFile(file, verify, mode);
   }
   /**
    * Returns a list of entries that are
    * immediately below the entry named by entryName in the jar"s directory
    * structure.
    *
    * @param entryName the name of the directory entry name
    * @return List a list of java.util.jar.JarEntry objects that are
    * immediately below the entry named by entryName in the jar"s directory
    * structure.
    */
   public List listSubEntries(String entryName) {
       Enumeration entries = jar.entries();
       List subEntries = new ArrayList();
       while(entries.hasMoreElements()) {
           JarEntry nextEntry = (JarEntry) entries.nextElement();
           if (nextEntry.getName().startsWith(entryName)) {
               // the next entry name starts with the entryName so it
               // is a potential sub entry
               // tokenize the rest of the next entry name to see how
               // many tokens exist
               StringTokenizer tokenizer = new StringTokenizer(
                   nextEntry.getName().substring(entryName.length()),
                   EnhancedJarFile.JAR_DELIMETER);
               if (tokenizer.countTokens() == 1) {
                   // only 1 token exists, so it is a sub-entry
                   subEntries.add(nextEntry);
               }
           }
       }
       return subEntries;
   }
   /**
    * Creates a new output entry stream within the jar.  The entry named
    * will be created if it does not exist within the jar already.
    *
    * @param entryName name of the entry for which to create an output
    * stream.
    * @return JarEntryOutputStream
    */
   public JarEntryOutputStream getEntryOutputStream(String entryName) {
       return new JarEntryOutputStream(this, entryName);
   }
   /**
    * Removes the given entry from the jar.  If the entry does not exist,
    * the method returns without doing anything.
    *
    * @param entry entry to be removed
    * @throws IOException if there is a problem writing the changes
    * to the jar
    */
   public void removeEntry(JarEntry entry) throws IOException {
       // opens an output stream and closes it without writing anything to it
       if (entry != null && getEntry(entry.getName()) != null) {
           JarEntryOutputStream outputStream =
               new JarEntryOutputStream(this, entry.getName());
           outputStream.close();
       }
   }
   /**
    * @see java.util.jar.JarFile#entries()
    */
   public Enumeration entries() {
       return this.jar.entries();
   }
   /**
    * @see java.util.jar.JarFile#getEntry(java.lang.String)
    */
   public ZipEntry getEntry(String arg0) {
       return this.jar.getEntry(arg0);
   }
   /**
    * @see java.util.jar.JarFile#getInputStream(java.util.zip.ZipEntry)
    */
   public InputStream getInputStream(ZipEntry arg0) throws IOException {
       return this.jar.getInputStream(arg0);
   }
   /**
    * @see java.util.jar.JarFile#getJarEntry(java.lang.String)
    */
   public JarEntry getJarEntry(String arg0) {
       return this.jar.getJarEntry(arg0);
   }
   /**
    * @see java.util.jar.JarFile#getManifest()
    */
   public Manifest getManifest() throws IOException {
       return this.jar.getManifest();
   }
   /**
    * @see java.util.zip.ZipFile#close()
    */
   public void close() throws IOException {
       this.jar.close();
   }
   /**
    * @see java.util.zip.ZipFile#getName()
    */
   public String getName() {
       return this.jar.getName();
   }
   /**
    * @see java.util.zip.ZipFile#size()
    */
   public int size() {
       return this.jar.size();
   }
   /**
    * Utility method used to swap the underlying jar file out for the new one.
    * This method closes the old jar file, deletes it, moves the new jar
    * file to the location where the old one used to be and opens it.
    * <p>
    * This is used when modifying the jar (removal, addition, or changes
    * of entries)
    *
    * @param newJarFile the file object pointing to the new jar file
    */
   void swapJars(File newJarFile) throws IOException {
       File oldJarFile = new File(getName());
       this.jar.close();
       oldJarFile.delete();
       if (newJarFile.renameTo(oldJarFile)) {
           this.jar = new JarFile(oldJarFile);
       } else {
           throw new IOException();
       }
   }

}


 </source>
   
  
 
  



Jar file helper to deployment

   <source lang="java">

/**

*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedList; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.security.cert.Certificate; /**

* @version $Rev: 726699 $ $Date: 2008-12-15 06:30:36 -0800 (Mon, 15 Dec 2008) $
*/

public class UnpackedJarFile extends JarFile {

   private final File baseDir;
   private boolean manifestLoaded = false;
   private Manifest manifest;
   public UnpackedJarFile(File baseDir) throws IOException {
       super(DeploymentUtil.DUMMY_JAR_FILE);
       this.baseDir = baseDir;
       if (!baseDir.isDirectory()) {
           throw new IOException("File must be a directory: file=" + baseDir.getAbsolutePath());
       }
   }
   public File getBaseDir() {
       return baseDir;
   }
   public Manifest getManifest() throws IOException {
       if (!manifestLoaded) {
           File manifestFile = getFile("META-INF/MANIFEST.MF");
           if (manifestFile != null && manifestFile.isFile()) {
               FileInputStream in = null;
               try {
                   in = new FileInputStream(manifestFile);
                   manifest = new Manifest(in);
               } finally {
                   if (in != null) {
                       try {
                           in.close();
                       } catch (IOException e) {
                           // ignore
                       }
                   }
               }
           }
           manifestLoaded = true;
       }
       return manifest;
   }
   public UnpackedJarEntry getUnpackedJarEntry(String name) {
       File file = getFile(name);
       if (file == null) {
           return null;
       }
       return new UnpackedJarEntry(name, file, getManifestSafe());
   }
   public JarEntry getJarEntry(String name) {
       return getUnpackedJarEntry(name);
   }
   public ZipEntry getEntry(String name) {
       return getUnpackedJarEntry(name);
   }
   public Enumeration entries() {
       Collection files = DeploymentUtil.listRecursiveFiles(baseDir);
       Manifest manifest = getManifestSafe();
       LinkedList entries = new LinkedList();
       URI baseURI = baseDir.getAbsoluteFile().toURI();
       for (Iterator iterator = files.iterator(); iterator.hasNext();) {
           File entryFile = ((File) iterator.next()).getAbsoluteFile();
           URI entryURI = entryFile.toURI();
           URI relativeURI = baseURI.relativize(entryURI);
           entries.add(new UnpackedJarEntry(relativeURI.getPath(), entryFile, manifest));
       }
       return Collections.enumeration(entries);
   }
   public InputStream getInputStream(ZipEntry zipEntry) throws IOException {
       File file;
       if (zipEntry instanceof UnpackedJarEntry) {
           file = ((UnpackedJarEntry)zipEntry).getFile();
       } else {
           file = getFile(zipEntry.getName());
       }
       if (file == null) {
           throw new IOException("Entry not found: name=" + zipEntry.getName());
       } else if (file.isDirectory()) {
           return new DeploymentUtil.EmptyInputStream();
       }
       return new FileInputStream(file);
   }
   public String getName() {
       return baseDir.getAbsolutePath();
   }
   /**
    * Always returns -1.
    * @return -1
    */
   public int size() {
       return -1;
   }
   public void close() throws IOException {
       try {
           super.close();
       } catch(IOException ignored) {
       }
   }
   protected void finalize() throws IOException {
   }
   public File getFile(String name) {
       File file = new File(baseDir, name);
       if (!file.exists()) {
           return null;
       }
       return file;
   }
   private Manifest getManifestSafe() {
       Manifest manifest = null;
       try {
           manifest = getManifest();
       } catch (IOException e) {
           // ignore
       }
       return manifest;
   }

} /**

*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

/**

* @version $Rev: 617659 $ $Date: 2008-02-01 13:29:25 -0800 (Fri, 01 Feb 2008) $
*/
final class DeploymentUtil {
   private DeploymentUtil() {
   }
   public static final File DUMMY_JAR_FILE;
   private static final boolean jarUrlRewrite;
   static {
       jarUrlRewrite = new Boolean(System.getProperty("org.apache.geronimo.deployment.util.DeploymentUtil.jarUrlRewrite", "false"));
       try {
           DUMMY_JAR_FILE = DeploymentUtil.createTempFile();
           new JarOutputStream(new FileOutputStream(DeploymentUtil.DUMMY_JAR_FILE), new Manifest()).close();
       } catch (IOException e) {
           throw new ExceptionInInitializerError(e);
       }
   }
   // be careful to clean up the temp directory
   public static File createTempDir() throws IOException {
       File tempDir = File.createTempFile("geronimo-deploymentUtil", ".tmpdir");
       tempDir.delete();
       tempDir.mkdirs();
       return tempDir;
   }
   // be careful to clean up the temp file... we tell the vm to delete this on exit
   // but VMs can"t be trusted to acutally delete the file
   public static File createTempFile() throws IOException {
       File tempFile = File.createTempFile("geronimo-deploymentUtil", ".tmpdir");
       tempFile.deleteOnExit();
       return tempFile;
   }
   
   // be careful to clean up the temp file... we tell the vm to delete this on exit
   // but VMs can"t be trusted to acutally delete the file
   private static File createTempFile(String extension) throws IOException {
       File tempFile = File.createTempFile("geronimo-deploymentUtil", extension == null? ".tmpdir": extension);
       tempFile.deleteOnExit();
       return tempFile;
   }
   public static void copyFile(File source, File destination) throws IOException {
       File destinationDir = destination.getParentFile();
       if (!destinationDir.exists() && !destinationDir.mkdirs()) {
           throw new java.io.IOException("Cannot create directory : " + destinationDir);
       }
       
       InputStream in = null;
       OutputStream out = null;
       try {
           in = new FileInputStream(source);
           out = new FileOutputStream(destination);
           writeAll(in, out);
       } finally {
           close(in);
           close(out);
       }
   }
   private static void writeAll(InputStream in, OutputStream out) throws IOException {
       byte[] buffer = new byte[4096];
       int count;
       while ((count = in.read(buffer)) > 0) {
           out.write(buffer, 0, count);
       }
       out.flush();
   }
   public static File toTempFile(JarFile jarFile, String path) throws IOException {
       return toTempFile(createJarURL(jarFile, path));
   }
   public static File toTempFile(URL url) throws IOException {
       InputStream in = null;
       OutputStream out = null;
       JarFile jarFile = null;
       try {
           if(url.getProtocol().equalsIgnoreCase("jar")) {
               // url.openStream() locks the jar file and does not release the lock even after the stream is closed.
               // This problem is avoided by using JarFile APIs.
               File file = new File(url.getFile().substring(5, url.getFile().indexOf("!/")));
               String path = url.getFile().substring(url.getFile().indexOf("!/")+2);
               jarFile = new JarFile(file);
               JarEntry jarEntry = jarFile.getJarEntry(path);
               if(jarEntry != null) {
                   in = jarFile.getInputStream(jarEntry);
               } else {
                   throw new FileNotFoundException("JarEntry "+path+" not found in "+file);
               }
           } else {
               in = url.openStream();
           }
           int index = url.getPath().lastIndexOf(".");
           String extension = null;
           if (index > 0) {
               extension = url.getPath().substring(index);
           }
           File tempFile = createTempFile(extension);
           out = new FileOutputStream(tempFile);
           writeAll(in, out);
           return tempFile;
       } finally {
           close(out);
           close(in);
           close(jarFile);
       }
   }
   public static String readAll(URL url) throws IOException {
       Reader reader = null;
       JarFile jarFile = null;
       try {
           if(url.getProtocol().equalsIgnoreCase("jar")) {
               // url.openStream() locks the jar file and does not release the lock even after the stream is closed.
               // This problem is avoided by using JarFile APIs.
               File file = new File(url.getFile().substring(5, url.getFile().indexOf("!/")));
               String path = url.getFile().substring(url.getFile().indexOf("!/")+2);
               jarFile = new JarFile(file);
               JarEntry jarEntry = jarFile.getJarEntry(path);
               if(jarEntry != null) {
                   reader = new InputStreamReader(jarFile.getInputStream(jarEntry));
               } else {
                   throw new FileNotFoundException("JarEntry "+path+" not found in "+file);
               }
           } else {
               reader = new InputStreamReader(url.openStream());
           }
           char[] buffer = new char[4000];
           StringBuffer out = new StringBuffer();
           for(int count = reader.read(buffer); count >= 0; count = reader.read(buffer)) {
               out.append(buffer, 0, count);
           }
           return out.toString();
       } finally {
           close(reader);
           close(jarFile);
       }
   }
   public static File toFile(JarFile jarFile) throws IOException {
       if (jarFile instanceof UnpackedJarFile) {
           return ((UnpackedJarFile) jarFile).getBaseDir();
       } else {
         throw new IOException("jarFile is not a directory");
       }
   }
   // be careful with this method as it can leave a temp lying around
   public static File toFile(JarFile jarFile, String path) throws IOException {
       if (jarFile instanceof UnpackedJarFile) {
           File baseDir = ((UnpackedJarFile) jarFile).getBaseDir();
           File file = new File(baseDir, path);
           if (!file.isFile()) {
               throw new IOException("No such file: " + file.getAbsolutePath());
           }
           return file;
       } else {
           String urlString = "jar:" + new File(jarFile.getName()).toURL() + "!/" + path;
           return toTempFile(new URL(urlString));
       }
   }
   public static URL createJarURL(JarFile jarFile, String path) throws MalformedURLException {
       if (jarFile instanceof NestedJarFile) {
           NestedJarFile nestedJar = (NestedJarFile) jarFile;
           if (nestedJar.isUnpacked()) {
               JarFile baseJar = nestedJar.getBaseJar();
               String basePath = nestedJar.getBasePath();
               if (baseJar instanceof UnpackedJarFile) {
                   File baseDir = ((UnpackedJarFile) baseJar).getBaseDir();
                   baseDir = new File(baseDir, basePath);
                   return new File(baseDir, path).toURL();
               }
           }
       }
       
       if (jarFile instanceof UnpackedJarFile) {
           File baseDir = ((UnpackedJarFile) jarFile).getBaseDir();
           return new File(baseDir, path).toURL();
       } else {
           String urlString = "jar:" + new File(jarFile.getName()).toURL() + "!/" + path;
           if(jarUrlRewrite) {
               // To prevent the lockout of archive, instead of returning a jar url, write the content to a
               // temp file and return the url of that file.
               File tempFile = null;
               try {
                   tempFile = toTempFile(new URL(urlString));
               } catch (IOException e) {
                   // The JarEntry does not exist!
                   // Return url of a file that does not exist.
                   try {
                       tempFile = createTempFile();
                       tempFile.delete();
                   } catch (IOException ignored) {
                   }
                }
               return tempFile.toURL();
           } else {
               return new URL(urlString);
           }
       }
   }
   public static JarFile createJarFile(File jarFile) throws IOException {
       if (jarFile.isDirectory()) {
           return new UnpackedJarFile(jarFile);
       } else {
           return new JarFile(jarFile);
       }
   }
   public static void copyToPackedJar(JarFile inputJar, File outputFile) throws IOException {
       if (inputJar.getClass() == JarFile.class) {
           // this is a plain old jar... nothign special
           copyFile(new File(inputJar.getName()), outputFile);
       } else if (inputJar instanceof NestedJarFile && ((NestedJarFile)inputJar).isPacked()) {
           NestedJarFile nestedJarFile = (NestedJarFile)inputJar;
           JarFile baseJar = nestedJarFile.getBaseJar();
           String basePath = nestedJarFile.getBasePath();
           if (baseJar instanceof UnpackedJarFile) {
               // our target jar is just a file in upacked jar (a plain old directory)... now
               // we just need to find where it is and copy it to the outptu
               copyFile(((UnpackedJarFile)baseJar).getFile(basePath), outputFile);
           } else {
               // out target is just a plain old jar file directly accessabel from the file system
               copyFile(new File(baseJar.getName()), outputFile);
           }
       } else {
           // copy out the module contents to a standalone jar file (entry by entry)
           JarOutputStream out = null;
           try {
               out = new JarOutputStream(new FileOutputStream(outputFile));
               byte[] buffer = new byte[4096];
               Enumeration entries = inputJar.entries();
               while (entries.hasMoreElements()) {
                   ZipEntry entry = (ZipEntry) entries.nextElement();
                   InputStream in = inputJar.getInputStream(entry);
                   try {
                       out.putNextEntry(new ZipEntry(entry.getName()));
                       try {
                           int count;
                           while ((count = in.read(buffer)) > 0) {
                               out.write(buffer, 0, count);
                           }
                       } finally {
                           out.closeEntry();
                       }
                   } finally {
                       close(in);
                   }
               }
           } finally {
               close(out);
           }
       }
   }
   public static void jarDirectory(File sourceDirecotry, File destinationFile) throws IOException {
       JarFile inputJar = new UnpackedJarFile(sourceDirecotry);
       try {
           copyToPackedJar(inputJar, destinationFile);
       } finally {
           close(inputJar);
       }
   }
   private static void createDirectory(File dir) throws IOException {
       if (dir != null && !dir.exists()) {
           boolean success = dir.mkdirs();
           if (!success) {
               throw new IOException("Cannot create directory " + dir.getAbsolutePath());
           }
       }
   }
   public static void unzipToDirectory(ZipFile zipFile, File destDir) throws IOException {
       Enumeration entries = zipFile.entries();
       try {
           while (entries.hasMoreElements()) {
               ZipEntry entry = (ZipEntry) entries.nextElement();
               if (entry.isDirectory()) {
                   File dir = new File(destDir, entry.getName());
                   createDirectory(dir);
               } else {
                   File file = new File(destDir, entry.getName());
                   createDirectory(file.getParentFile());
                   OutputStream out = null;
                   InputStream in = null;
                   try {
                       out = new BufferedOutputStream(new FileOutputStream(file));
                       in = zipFile.getInputStream(entry);
                       writeAll(in, out);
                   } finally {
                       if (null != out) {
                           out.close();
                       }
                       if (null != in) {
                           in.close();
                       }
                   }
               }
           }
       } finally {
           zipFile.close();
       }
   }
   
   
   public static boolean recursiveDelete(File root, Collection<String> unableToDeleteCollection) {
       if (root == null) {
           return true;
       }
       if (root.isDirectory()) {
           File[] files = root.listFiles();
           if (files != null) {
               for (int i = 0; i < files.length; i++) {
                   File file = files[i];
                   if (file.isDirectory()) {
                       recursiveDelete(file, unableToDeleteCollection);
                   } else {
                       if (!file.delete() && unableToDeleteCollection != null) {
                           unableToDeleteCollection.add(file.getAbsolutePath());    
                       }
                   }
                   // help out the GC of file handles by nulling the references
                   files[i] = null;
               }
           }
       }
       boolean rootDeleteStatus;
       if (!(rootDeleteStatus = root.delete()) && unableToDeleteCollection != null) 
         unableToDeleteCollection.add(root.getAbsolutePath());
       
       return rootDeleteStatus;
   }
   
   public static boolean recursiveDelete(File root) {
       return recursiveDelete(root, null);
   }
   public static Collection<File> listRecursiveFiles(File file) {
       Collection<File> list = new ArrayList<File>();
       listRecursiveFiles(file, list);
       return Collections.unmodifiableCollection(list);
   }
   public static void listRecursiveFiles(File file, Collection<File> collection) {
       File[] files = file.listFiles();
       if ( null == files ) {
           return;
       }
       for (File file1 : files) {
           collection.add(file1);
           if (file1.isDirectory()) {
               listRecursiveFiles(file1, collection);
           }
       }
   }
   public static void flush(OutputStream thing) {
       if (thing != null) {
           try {
               thing.flush();
           } catch(Exception ignored) {
           }
       }
   }
   public static void flush(Writer thing) {
       if (thing != null) {
           try {
               thing.flush();
           } catch(Exception ignored) {
           }
       }
   }
   public static void close(JarFile thing) {
       if (thing != null) {
           try {
               thing.close();
           } catch(Exception ignored) {
           }
       }
   }
   public static void close(InputStream thing) {
       if (thing != null) {
           try {
               thing.close();
           } catch(Exception ignored) {
           }
       }
   }
   public static void close(OutputStream thing) {
       if (thing != null) {
           try {
               thing.close();
           } catch(Exception ignored) {
           }
       }
   }
   public static void close(Reader thing) {
       if (thing != null) {
           try {
               thing.close();
           } catch(Exception ignored) {
           }
       }
   }
   public static void close(Writer thing) {
       if (thing != null) {
           try {
               thing.close();
           } catch(Exception ignored) {
           }
       }
   }
   public static final class EmptyInputStream extends InputStream {
       public int read() {
           return -1;
       }
       public int read(byte b[])  {
           return -1;
       }
       public int read(byte b[], int off, int len) {
           return -1;
       }
       public long skip(long n) {
           return 0;
       }
       public int available() {
           return 0;
       }
       public void close() {
       }
       public synchronized void mark(int readlimit) {
       }
       public synchronized void reset() {
       }
       public boolean markSupported() {
           return false;
       }
   }

}

/**
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
/**
 * @version $Rev: 726699 $ $Date: 2008-12-15 06:30:36 -0800 (Mon, 15 Dec 2008) $
 */
class NestedJarFile extends JarFile {
    private JarFile baseJar;
    private String basePath;
    private boolean isClosed = false;
    private boolean manifestLoaded = false;
    private Manifest manifest;
    private File tempFile;
    public NestedJarFile(JarFile jarFile, String path) throws IOException {
        super(DeploymentUtil.DUMMY_JAR_FILE);
        // verify that the jar actually contains that path
        JarEntry targetEntry = jarFile.getJarEntry(path + "/");
        if (targetEntry == null) {
            targetEntry = jarFile.getJarEntry(path);
            if (targetEntry == null) {
                throw new IOException("Jar entry does not exist: jarFile=" + jarFile.getName() + ", path=" + path);
            }
        }
        if (targetEntry.isDirectory()) {
         if(targetEntry instanceof UnpackedJarEntry) {
           //unpacked nested module inside unpacked ear
           File targetFile = ((UnpackedJarEntry) targetEntry).getFile();
           baseJar = new UnpackedJarFile(targetFile);
                basePath = "";
         } else {
           baseJar = jarFile;
           if (!path.endsWith("/")) {
                    path += "/";
                }
                basePath = path;
         }
        } else {
            if (targetEntry instanceof UnpackedJarEntry) {
                // for unpacked jars we don"t need to copy the jar file
                // out to a temp directory, since it is already available
                // as a raw file
                File targetFile = ((UnpackedJarEntry) targetEntry).getFile();
                baseJar = new JarFile(targetFile);
                basePath = "";
            } else {
                tempFile = DeploymentUtil.toFile(jarFile, targetEntry.getName());
                baseJar = new JarFile(tempFile);
                basePath = "";
            }
        }
    }
    public boolean isUnpacked() {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        return ( basePath.length() > 0 ) ||
               ( ( baseJar != null ) && ( baseJar instanceof UnpackedJarFile ) );
    }
    public boolean isPacked() {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        return ( basePath.length() == 0 ) &&
               ( ( baseJar == null ) || !( baseJar instanceof UnpackedJarFile ) );
    }
    public JarFile getBaseJar() {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        return baseJar;
    }
    public String getBasePath() {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        return basePath;
    }
    public Manifest getManifest() throws IOException {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        if (!manifestLoaded) {
            JarEntry manifestEntry = getBaseEntry("META-INF/MANIFEST.MF");
            if (manifestEntry != null && !manifestEntry.isDirectory()) {
                InputStream in = null;
                try {
                    in = baseJar.getInputStream(manifestEntry);
                    manifest = new Manifest(in);
                } finally {
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                            // ignore
                        }
                    }
                }
            }
            manifestLoaded = true;
        }
        return manifest;
    }
    public NestedJarEntry getNestedJarEntry(String name) {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        JarEntry baseEntry = getBaseEntry(name);
        if (baseEntry == null) {
            return null;
        }
        return new NestedJarEntry(name, baseEntry, getManifestSafe());
    }
    public JarEntry getJarEntry(String name) {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        return getNestedJarEntry(name);
    }
    public ZipEntry getEntry(String name) {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        return getNestedJarEntry(name);
    }
    public Enumeration entries() {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        Collection baseEntries = Collections.list(baseJar.entries());
        Collection entries = new LinkedList();
        for (Iterator iterator = baseEntries.iterator(); iterator.hasNext();) {
            JarEntry baseEntry = (JarEntry) iterator.next();
            String path = baseEntry.getName();
            if (path.startsWith(basePath)) {
                entries.add(new NestedJarEntry(path.substring(basePath.length()), baseEntry, getManifestSafe()));
            }
        }
        return Collections.enumeration(entries);
    }
    public InputStream getInputStream(ZipEntry zipEntry) throws IOException {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        JarEntry baseEntry;
        if (zipEntry instanceof NestedJarEntry) {
            baseEntry = ((NestedJarEntry)zipEntry).getBaseEntry();
        } else {
            baseEntry = getBaseEntry(zipEntry.getName());
        }
        if (baseEntry == null) {
            throw new IOException("Entry not found: name=" + zipEntry.getName());
        } else if (baseEntry.isDirectory()) {
            return new DeploymentUtil.EmptyInputStream();
        }
        return baseJar.getInputStream(baseEntry);
    }
    public String getName() {
        return baseJar.getName();
    }
    /**
     * Always returns -1.
     * @return -1
     */
    public int size() {
        if (isClosed) {
            throw new IllegalStateException("NestedJarFile is closed");
        }
        return -1;
    }
    public void close() throws IOException {
        if (isClosed) {
            return;
        }
        try {
            try {
                super.close();
            } catch(IOException ignored) {
            }
            if (baseJar != null && basePath.length() == 0) {
                // baseJar is created by us.  We should be closing it too.
                baseJar.close();
            }
        } finally {
            isClosed = true;
            baseJar = null;
            basePath = null;
            manifestLoaded = false;
            manifest = null;
            if (tempFile != null) {
                tempFile.delete();
                tempFile = null;
            }
        }
    }
    protected void finalize() throws IOException {
        close();
    }
    private JarEntry getBaseEntry(String name) {
        return baseJar.getJarEntry(basePath + name);
    }
    private Manifest getManifestSafe() {
        Manifest manifest = null;
        try {
            manifest = getManifest();
        } catch (IOException e) {
            // ignore
        }
        return manifest;
    }
}
/**
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
/**
 * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
 */
 class NestedJarEntry extends JarEntry {
    private final JarEntry baseEntry;
    private final Manifest manifest;
    public NestedJarEntry(String name, JarEntry baseEntry, Manifest manifest) {
        super(name);
        this.baseEntry = baseEntry;
        this.manifest = manifest;
    }
    public JarEntry getBaseEntry() {
        return baseEntry;
    }
    public Attributes getAttributes() throws IOException {
        if (manifest == null) {
            return null;
        }
        return manifest.getAttributes(getName());
    }

    public long getTime() {
        return baseEntry.getTime();
    }
    public void setTime(long time) {
        baseEntry.setTime(time);
    }
    public long getSize() {
        return baseEntry.getSize();
    }
    public void setSize(long size) {
        baseEntry.setSize(size);
    }
    public long getCompressedSize() {
        return baseEntry.getCompressedSize();
    }
    public void setCompressedSize(long csize) {
        baseEntry.setCompressedSize(csize);
    }
    public long getCrc() {
        return baseEntry.getCrc();
    }
    public void setCrc(long crc) {
        baseEntry.setCrc(crc);
    }
    public int getMethod() {
        return baseEntry.getMethod();
    }
    public void setMethod(int method) {
        baseEntry.setMethod(method);
    }
    public byte[] getExtra() {
        return baseEntry.getExtra();
    }
    public void setExtra(byte[] extra) {
        baseEntry.setExtra(extra);
    }
    public String getComment() {
        return baseEntry.getComment();
    }
    public void setComment(String comment) {
        baseEntry.setComment(comment);
    }
    public boolean isDirectory() {
        return baseEntry.isDirectory();
    }
    public String toString() {
        return baseEntry.toString();
    }
    public int hashCode() {
        return baseEntry.hashCode();
    }
    public Object clone() {
        return new NestedJarEntry(getName(), baseEntry, manifest);
    }
}
 /**
  *  Licensed to the Apache Software Foundation (ASF) under one or more
  *  contributor license agreements.  See the NOTICE file distributed with
  *  this work for additional information regarding copyright ownership.
  *  The ASF licenses this file to You under the Apache License, Version 2.0
  *  (the "License"); you may not use this file except in compliance with
  *  the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software
  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
 /**
  * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
  */
 class UnpackedJarEntry extends JarEntry {
     private final File file;
     private final Manifest manifest;
     public UnpackedJarEntry(String name, File file, Manifest manifest) {
         super(name);
         this.file = file;
         this.manifest = manifest;
     }
     public File getFile() {
         return file;
     }
     public Attributes getAttributes() throws IOException {
         if (manifest == null) {
             return null;
         }
         return manifest.getAttributes(getName());
     }
     /**
      * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
      * @param time ignored
      * @throws UnsupportedOperationException always
      */
     public void setTime(long time) throws UnsupportedOperationException {
         throw new UnsupportedOperationException("Can not change the time of unpacked jar entry");
     }
     public long getTime() {
         return file.lastModified();
     }
     /**
      * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
      * @param size ignored
      * @throws UnsupportedOperationException always
      */
     public void setSize(long size) throws UnsupportedOperationException {
         throw new UnsupportedOperationException("Can not change the size of unpacked jar entry");
     }
     public long getSize() {
         if (file.isDirectory()) {
             return -1;
         } else {
             return file.length();
         }
     }
     /**
      * An unpacked jar is not compressed, so this method returns getSize().
      * @return getSize()
      */
     public long getCompressedSize() {
         return getSize();
     }
     /**
      * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
      * @param compressedSize ignored
      * @throws UnsupportedOperationException always
      */
     public void setCompressedSize(long compressedSize) {
         throw new UnsupportedOperationException("Can not change the compressed size of unpacked jar entry");
     }
     public long getCrc() {
         return super.getCrc();    //To change body of overridden methods use File | Settings | File Templates.
     }
     /**
      * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
      * @param crc ignored
      * @throws UnsupportedOperationException always
      */
     public void setCrc(long crc) {
         throw new UnsupportedOperationException("Can not change the crc of unpacked jar entry");
     }
     public int getMethod() {
         return ZipEntry.STORED;
     }
     /**
      * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
      * @param method ignored
      * @throws UnsupportedOperationException always
      */
     public void setMethod(int method) {
         throw new UnsupportedOperationException("Can not change the method of unpacked jar entry");
     }
     /**
      * Always returns null.
      * @return null
      */
     public byte[] getExtra() {
         return null;
     }
     /**
      * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
      * @param extra ignored
      * @throws UnsupportedOperationException always
      */
     public void setExtra(byte[] extra) {
         throw new UnsupportedOperationException("Can not change the extra data of unpacked jar entry");
     }
     /**
      * Always returns null.
      * @return null
      */
     public String getComment() {
         return null;
     }
     /**
      * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
      * @param comment ignored
      * @throws UnsupportedOperationException always
      */
     public void setComment(String comment) {
         throw new UnsupportedOperationException("Can not change the comment of unpacked jar entry");
     }
     public boolean isDirectory() {
         return file.isDirectory();
     }
     public Object clone() {
         return new UnpackedJarEntry(getName(), file, manifest);
     }
 }
  
 </source>
   
  
 
  



Jarring and unjarring files and directories.

   <source lang="java">

/* Copyright 2004 The Apache Software Foundation

*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*  limitations under the License.
*/

import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; /**

* Provides utility services for jarring and unjarring files and directories.
* Note that a given instance of JarHelper is not threadsafe with respect to
* multiple jar operations.
* 
* @author Patrick Calahan <pcal@bea.ru>
*/

public class JarHelper {

 // Constants
 private static final int BUFFER_SIZE = 2156;
 // Variables
 private byte[] mBuffer = new byte[BUFFER_SIZE];
 private int mByteCount = 0;
 private boolean mVerbose = false;
 private String mDestJarName = "";
 // Constructor
 /**
  * Instantiates a new JarHelper.
  */
 public JarHelper() {
 }
 // Public methods
 /**
  * Jars a given directory or single file into a JarOutputStream.
  */
 public void jarDir(File dirOrFile2Jar, File destJar) throws IOException {
   if (dirOrFile2Jar == null || destJar == null)
     throw new IllegalArgumentException();
   mDestJarName = destJar.getCanonicalPath();
   FileOutputStream fout = new FileOutputStream(destJar);
   JarOutputStream jout = new JarOutputStream(fout);
   // jout.setLevel(0);
   try {
     jarDir(dirOrFile2Jar, jout, null);
   } catch (IOException ioe) {
     throw ioe;
   } finally {
     jout.close();
     fout.close();
   }
 }
 /**
  * Unjars a given jar file into a given directory.
  */
 public void unjarDir(File jarFile, File destDir) throws IOException {
   BufferedOutputStream dest = null;
   FileInputStream fis = new FileInputStream(jarFile);
   unjar(fis, destDir);
 }
 /**
  * Given an InputStream on a jar file, unjars the contents into the given
  * directory.
  */
 public void unjar(InputStream in, File destDir) throws IOException {
   BufferedOutputStream dest = null;
   JarInputStream jis = new JarInputStream(in);
   JarEntry entry;
   while ((entry = jis.getNextJarEntry()) != null) {
     if (entry.isDirectory()) {
       File dir = new File(destDir, entry.getName());
       dir.mkdir();
       if (entry.getTime() != -1)
         dir.setLastModified(entry.getTime());
       continue;
     }
     int count;
     byte data[] = new byte[BUFFER_SIZE];
     File destFile = new File(destDir, entry.getName());
     if (mVerbose)
       System.out.println("unjarring " + destFile + " from " + entry.getName());
     FileOutputStream fos = new FileOutputStream(destFile);
     dest = new BufferedOutputStream(fos, BUFFER_SIZE);
     while ((count = jis.read(data, 0, BUFFER_SIZE)) != -1) {
       dest.write(data, 0, count);
     }
     dest.flush();
     dest.close();
     if (entry.getTime() != -1)
       destFile.setLastModified(entry.getTime());
   }
   jis.close();
 }
 public void setVerbose(boolean b) {
   mVerbose = b;
 }
 // Private methods
 private static final char SEP = "/";
 /**
  * Recursively jars up the given path under the given directory.
  */
 private void jarDir(File dirOrFile2jar, JarOutputStream jos, String path) throws IOException {
   if (mVerbose)
     System.out.println("checking " + dirOrFile2jar);
   if (dirOrFile2jar.isDirectory()) {
     String[] dirList = dirOrFile2jar.list();
     String subPath = (path == null) ? "" : (path + dirOrFile2jar.getName() + SEP);
     if (path != null) {
       JarEntry je = new JarEntry(subPath);
       je.setTime(dirOrFile2jar.lastModified());
       jos.putNextEntry(je);
       jos.flush();
       jos.closeEntry();
     }
     for (int i = 0; i < dirList.length; i++) {
       File f = new File(dirOrFile2jar, dirList[i]);
       jarDir(f, jos, subPath);
     }
   } else {
     if (dirOrFile2jar.getCanonicalPath().equals(mDestJarName)) {
       if (mVerbose)
         System.out.println("skipping " + dirOrFile2jar.getPath());
       return;
     }
     if (mVerbose)
       System.out.println("adding " + dirOrFile2jar.getPath());
     FileInputStream fis = new FileInputStream(dirOrFile2jar);
     try {
       JarEntry entry = new JarEntry(path + dirOrFile2jar.getName());
       entry.setTime(dirOrFile2jar.lastModified());
       jos.putNextEntry(entry);
       while ((mByteCount = fis.read(mBuffer)) != -1) {
         jos.write(mBuffer, 0, mByteCount);
         if (mVerbose)
           System.out.println("wrote " + mByteCount + " bytes");
       }
       jos.flush();
       jos.closeEntry();
     } catch (IOException ioe) {
       throw ioe;
     } finally {
       fis.close();
     }
   }
 }
 // for debugging
 public static void main(String[] args) throws IOException {
   if (args.length < 2) {
     System.err.println("Usage: JarHelper jarname.jar directory");
     return;
   }
   JarHelper jarHelper = new JarHelper();
   jarHelper.mVerbose = true;
   File destJar = new File(args[0]);
   File dirOrFile2Jar = new File(args[1]);
   jarHelper.jarDir(dirOrFile2Jar, destJar);
 }

}

 </source>
   
  
 
  



List files in a jar file

   <source lang="java">
   
  import java.io.*;
  import java.util.*;
  import java.util.jar.*;
  public class JarDir {
    public static void main (String args[]) 
        throws IOException {
      JarFile jarFile = new JarFile("yourJarFileName.jar");
      Enumeration enum = jarFile.entries();
      while (enum.hasMoreElements()) {
        process(enum.nextElement());
      }
    }
    private static void process(Object obj) {
      JarEntry entry = (JarEntry)obj;
      String name = entry.getName();
      long size = entry.getSize();
      long compressedSize = entry.getCompressedSize();
      System.out.println(
          name + "\t" + size + "\t" + compressedSize);
    }
  }
          
        
   
   
   
 </source>
   
  
 
  



Listing the Entries of a JAR File Manifest

   <source lang="java">
   

import java.util.Iterator; import java.util.Map; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; public class Main {

 public static void main(String[] argv) throws Exception {
   JarFile jarfile = new JarFile("filename.jar");
   Manifest manifest = jarfile.getManifest();
   Map map = manifest.getEntries();
   for (Iterator it = map.keySet().iterator(); it.hasNext();) {
     String entryName = (String) it.next();
     Attributes attrs = (Attributes) map.get(entryName);
     for (Iterator it2 = attrs.keySet().iterator(); it2.hasNext();) {
       Attributes.Name attrName = (Attributes.Name) it2.next();
       String attrValue = attrs.getValue(attrName);
     }
   }
 }

}



 </source>
   
  
 
  



Listing the Main Attributes in a JAR File Manifest

   <source lang="java">
   

import java.util.Iterator; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; public class Main {

 public static void main(String[] argv) throws Exception {
   JarFile jarfile = new JarFile("filename.jar");
   Manifest manifest = jarfile.getManifest();
   Attributes attrs = (Attributes) manifest.getMainAttributes();
   for (Iterator it = attrs.keySet().iterator(); it.hasNext();) {
     Attributes.Name attrName = (Attributes.Name) it.next();
     String attrValue = attrs.getValue(attrName);
   }
 }

}



 </source>
   
  
 
  



Load an Icon from a jar

   <source lang="java">
   

import javax.swing.Icon; import javax.swing.UIManager; public class Main {

 public static void main(String[] argv) throws Exception {
 }
 public static Icon getIconForType(int iconType) {
   switch (iconType) {
   case 0:
     return UIManager.getIcon("OptionPane.errorIcon");
   case 1:
     return UIManager.getIcon("OptionPane.informationIcon");
   case 2:
     return UIManager.getIcon("OptionPane.warningIcon");
   case 3:
     return UIManager.getIcon("OptionPane.questionIcon");
   }
   return null;
 }

}



 </source>
   
  
 
  



Load an Image from a JAR file

   <source lang="java">
   

import java.awt.Image; import java.awt.Toolkit; import java.net.URL; public class Main {

 public static void main(String[] argv) throws Exception {
   String imgName = "image.jpg";
   URL imgURL = Main.class.getResource(imgName);
   Toolkit tk = Toolkit.getDefaultToolkit();
   Image img = tk.getImage(imgURL);
 }

}



 </source>
   
  
 
  



Load resource from Jar file

   <source lang="java">
  

import java.io.BufferedInputStream; import java.io.FileInputStream; import java.util.Enumeration; import java.util.Hashtable; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream;

public final class JarResources {

 Hashtable htSizes = new Hashtable();
 Hashtable htJarContents = new Hashtable();
 private String jarFileName;
 public JarResources(String jarFileName) throws Exception {
   this.jarFileName = jarFileName;
   ZipFile zf = new ZipFile(jarFileName);
   Enumeration e = zf.entries();
   while (e.hasMoreElements()) {
     ZipEntry ze = (ZipEntry) e.nextElement();
     htSizes.put(ze.getName(), new Integer((int) ze.getSize()));
   }
   zf.close();
   // extract resources and put them into the hashtable.
   FileInputStream fis = new FileInputStream(jarFileName);
   BufferedInputStream bis = new BufferedInputStream(fis);
   ZipInputStream zis = new ZipInputStream(bis);
   ZipEntry ze = null;
   while ((ze = zis.getNextEntry()) != null) {
     if (ze.isDirectory()) {
       continue;
     }
     int size = (int) ze.getSize();
     // -1 means unknown size.
     if (size == -1) {
       size = ((Integer) htSizes.get(ze.getName())).intValue();
     }
     byte[] b = new byte[(int) size];
     int rb = 0;
     int chunk = 0;
     while (((int) size - rb) > 0) {
       chunk = zis.read(b, rb, (int) size - rb);
       if (chunk == -1) {
         break;
       }
       rb += chunk;
     }
     htJarContents.put(ze.getName(), b);
   }
 }
 public byte[] getResource(String name) {
   return (byte[]) htJarContents.get(name);
 }
 private String dumpZipEntry(ZipEntry ze) {
   StringBuffer sb = new StringBuffer();
   if (ze.isDirectory()) {
     sb.append("d ");
   } else {
     sb.append("f ");
   }
   if (ze.getMethod() == ZipEntry.STORED) {
     sb.append("stored   ");
   } else {
     sb.append("defalted ");
   }
   sb.append(ze.getName());
   sb.append("\t");
   sb.append("" + ze.getSize());
   if (ze.getMethod() == ZipEntry.DEFLATED) {
     sb.append("/" + ze.getCompressedSize());
   }
   return (sb.toString());
 }
 public static void main(String[] args) throws Exception {
   JarResources jr = new JarResources("a.jar");
   byte[] buff = jr.getResource("b.gif");
 }

}


 </source>
   
  
 
  



Make Temp Jar

   <source lang="java">

/*

* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License.  When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/

import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class Main {

 static File makeTempJar(File moduleFile) throws IOException {
   String prefix = moduleFile.getName();
   if (prefix.endsWith(".jar") || prefix.endsWith(".JAR")) { // NOI18N
       prefix = prefix.substring(0, prefix.length() - 4);
   }
   if (prefix.length() < 3) prefix += ".";
   if (prefix.length() < 3) prefix += ".";
   if (prefix.length() < 3) prefix += ".";
   String suffix = "-test.jar"; // NOI18N
   File physicalModuleFile = File.createTempFile(prefix, suffix);
   physicalModuleFile.deleteOnExit();
   InputStream is = new FileInputStream(moduleFile);
   try {
       OutputStream os = new FileOutputStream(physicalModuleFile);
       try {
           byte[] buf = new byte[4096];
           int i;
           while ((i = is.read(buf)) != -1) {
               os.write(buf, 0, i);
           }
       } finally {
           os.close();
       }
   } finally {
       is.close();
   }
   return physicalModuleFile;

}

}

 </source>
   
  
 
  



Manifest Writer

   <source lang="java">
  

/*BEGIN_COPYRIGHT_BLOCK

*
* Copyright (c) 2001-2008, JavaPLT group at Rice University (drjava@rice.edu)
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*    * Redistributions of source code must retain the above copyright
*      notice, this list of conditions and the following disclaimer.
*    * Redistributions in binary form must reproduce the above copyright
*      notice, this list of conditions and the following disclaimer in the
*      documentation and/or other materials provided with the distribution.
*    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
*      names of its contributors may be used to endorse or promote products
*      derived from this software without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software is Open Source Initiative approved Open Source Software.
* Open Source Initative Approved is a trademark of the Open Source Initiative.
* 
* This file is part of DrJava.  Download the current version of this project
* from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
* 
* END_COPYRIGHT_BLOCK*/

import java.util.jar.Manifest; import java.util.jar.Attributes; import java.util.LinkedList; import java.util.List; import java.util.Iterator; import java.io.*; /** Writes manifest objects. Useful for creating Manifest files without writing them to files. */ public class ManifestWriter {

 private List<String> _classPaths;
 private String _mainClass;
 private String _rawManifest;
 public static final Manifest DEFAULT = new ManifestWriter().getManifest();
 
 /** Create a new manifest file */
 public ManifestWriter() {
   _classPaths = new LinkedList<String>();
   _mainClass = null;
   _rawManifest = null;
 }
 
 /** Add a class path to the Manifest
   * @param path the path to be added
   */
 public void addClassPath(String path) {
   _classPaths.add(_classPaths.size(), path);
 }
 
 /** Set the main class of the Manifest
   * @param mainClass
   */
 public void setMainClass(String mainClass) {
   _mainClass = mainClass;
   _rawManifest = null;
 }
 
 public void setManifestContents(String rawManifest) {
   _rawManifest =  rawManifest;
   _mainClass = null;
 }
 
 /** Get an input stream to the contents of the manifest file
   * @return an InputStream whose contents are the contents of the Manifest file
   */
 protected InputStream getInputStream() {
   // NOTE: All significant lines in the manifest MUST end in the end of line character
   
   final StringBuilder sbuf = new StringBuilder();
   sbuf.append(Attributes.Name.MANIFEST_VERSION.toString());
   sbuf.append(": 1.0" + "\n");
   if( !_classPaths.isEmpty() ) {
     Iterator<String> iter = _classPaths.iterator();
     sbuf.append(Attributes.Name.CLASS_PATH.toString());
     sbuf.append(":");
     while (iter.hasNext()) {
       sbuf.append(" ");
       sbuf.append(iter.next());
     }
     sbuf.append("\n");
   }
   if( _mainClass != null ) {
     sbuf.append(Attributes.Name.MAIN_CLASS.toString());
     sbuf.append(": ");
     sbuf.append(_mainClass);
     sbuf.append("\n");
   }
   
   if(_rawManifest != null) {
     sbuf.append(_rawManifest); 
     
     if(!_rawManifest.endsWith("\n"))
       sbuf.append("\n");
   }
   
   try { return new ByteArrayInputStream(sbuf.toString().getBytes("UTF-8")); }
   catch (UnsupportedEncodingException e) { throw new RuntimeException(e); }
 }
 
 /** Get the Manifest object that this object created.
   * @return the Manifest that this builder created
   */
 public Manifest getManifest() {
   try {
     Manifest m = new Manifest();
     m.read(getInputStream());
     return m;
   }
   catch (IOException e) {
     e.printStackTrace();
     return null;
   }
 }

}


 </source>
   
  
 
  



Reading a text file from a jar file without unzipping

   <source lang="java">
   
  import java.io.*;
  import java.util.jar.*;
  public class JarRead {
    public static void main (String args[]) 
        throws IOException {
      if (args.length != 2) {
        System.out.println(
          "Please provide a JAR filename and file to read");
        System.exit(-1);
      }
      JarFile jarFile = new JarFile(args[0]);
      JarEntry entry = jarFile.getJarEntry(args[1]);
      InputStream input = jarFile.getInputStream(entry);
      process(input);
      jarFile.close();
    }
    private static void process(InputStream input) 
        throws IOException {
      InputStreamReader isr = 
     new InputStreamReader(input);
      BufferedReader reader = new BufferedReader(isr);
      String line;
      while ((line = reader.readLine()) != null) {
        System.out.println(line);
      }
      reader.close();
    }
  }
          
        
   
   
   
 </source>
   
  
 
  



Retreive Binary File From Jar

   <source lang="java">
  

/*

* Copyright 2006 - 2008 Georges Stephan
* 
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.util.logging.*; import java.io.*; /**

* 
* @author Georges Stephan
*/

public class Util {

 private static Logger logger = Logger.getLogger(Util.class.getName());
   
 public static String validateString(String aString) {
   if(aString==null) return("");
   
   aString=aString.replace("\"", " ");
   aString=aString.trim();
   return(aString);
 }
   
 public static String removeNonDigits(String aString) {
   StringBuffer newString = new StringBuffer();
   for(int x=0;x<aString.length();x++) {
     if(Character.isDigit(aString.charAt(x))) newString.append(aString.charAt(x));
   }
   return(newString.toString());
 }
   
 public static void createHome() throws Exception {
   File ch = new File(System.getProperty("user.home")+File.separator+".dataform");
   if(!ch.exists()) {
     if(!ch.mkdir()) throw new Exception("Failed to create the dataform configuration directory");
   }
 }
   
 public static String getHomeDir() {
   return(System.getProperty("user.home")+File.separator+".dataform"+File.separator);
 } 
   
 public static boolean retreiveTextFileFromJar(String resourceName,String targetDirectory) throws Exception {
   boolean found=false;
   if(resourceName!=null) {
     InputStream is = Util.class.getResourceAsStream(resourceName);
     if(is==null) logger.log(Level.WARNING,"The resource ""+resourceName+"" was not found.");
     BufferedReader br = new BufferedReader(new InputStreamReader(is));
     String line;
     String lineSep = System.getProperty("line.separator");
     StringBuffer sb = new StringBuffer();
     while ((line = br.readLine()) != null) {
       sb.append(line);
       sb.append(lineSep);
     }
     is.close();
     if(sb!=null) {
       if(sb.length()>0) {
         FileWriter temp = new FileWriter(targetDirectory+File.separator+resourceName);
         temp.write(sb.toString());
         temp.close();
         found=true;
       }
     }
   }
   return(found);    
 }
 
 public static boolean retreiveBinaryFileFromJar(String resourceName,String targetDirectory,Object resource) throws Exception {
   boolean found=false;
   if(resourceName!=null) {
     InputStream is = resource.getClass().getResourceAsStream(resourceName);
     if(is==null) throw new Exception ("Resource "+resourceName+" was not found.");
     BufferedReader br = new BufferedReader(new InputStreamReader(is));
     FileOutputStream fos = new FileOutputStream(targetDirectory+File.separator+resourceName.substring(resourceName.lastIndexOf("/"),resourceName.length()));
     byte[] buffer = new byte[1024];
           int bytesRead;
           
           while ((bytesRead = is.read(buffer)) != -1) {
               fos.write(buffer, 0, bytesRead);
           }
           fos.flush();
           br.close();
           is.close();
     found=true;
   } else {
     found=false;
   }
   return found;
 }

}


 </source>
   
  
 
  



Retreive Text File From Jar

   <source lang="java">
  

/*

* Copyright 2006 - 2008 Georges Stephan
* 
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.util.logging.*; import java.io.*; /**

* 
* @author Georges Stephan
*/

public class Util {

 private static Logger logger = Logger.getLogger(Util.class.getName());
   
 public static String validateString(String aString) {
   if(aString==null) return("");
   
   aString=aString.replace("\"", " ");
   aString=aString.trim();
   return(aString);
 }
   
 public static String removeNonDigits(String aString) {
   StringBuffer newString = new StringBuffer();
   for(int x=0;x<aString.length();x++) {
     if(Character.isDigit(aString.charAt(x))) newString.append(aString.charAt(x));
   }
   return(newString.toString());
 }
   
 public static void createHome() throws Exception {
   File ch = new File(System.getProperty("user.home")+File.separator+".dataform");
   if(!ch.exists()) {
     if(!ch.mkdir()) throw new Exception("Failed to create the dataform configuration directory");
   }
 }
   
 public static String getHomeDir() {
   return(System.getProperty("user.home")+File.separator+".dataform"+File.separator);
 } 
   
 public static boolean retreiveTextFileFromJar(String resourceName,String targetDirectory) throws Exception {
   boolean found=false;
   if(resourceName!=null) {
     InputStream is = Util.class.getResourceAsStream(resourceName);
     if(is==null) logger.log(Level.WARNING,"The resource ""+resourceName+"" was not found.");
     BufferedReader br = new BufferedReader(new InputStreamReader(is));
     String line;
     String lineSep = System.getProperty("line.separator");
     StringBuffer sb = new StringBuffer();
     while ((line = br.readLine()) != null) {
       sb.append(line);
       sb.append(lineSep);
     }
     is.close();
     if(sb!=null) {
       if(sb.length()>0) {
         FileWriter temp = new FileWriter(targetDirectory+File.separator+resourceName);
         temp.write(sb.toString());
         temp.close();
         found=true;
       }
     }
   }
   return(found);    
 }
 
 public static boolean retreiveBinaryFileFromJar(String resourceName,String targetDirectory,Object resource) throws Exception {
   boolean found=false;
   if(resourceName!=null) {
     InputStream is = resource.getClass().getResourceAsStream(resourceName);
     if(is==null) throw new Exception ("Resource "+resourceName+" was not found.");
     BufferedReader br = new BufferedReader(new InputStreamReader(is));
     FileOutputStream fos = new FileOutputStream(targetDirectory+File.separator+resourceName.substring(resourceName.lastIndexOf("/"),resourceName.length()));
     byte[] buffer = new byte[1024];
           int bytesRead;
           
           while ((bytesRead = is.read(buffer)) != -1) {
               fos.write(buffer, 0, bytesRead);
           }
           fos.flush();
           br.close();
           is.close();
     found=true;
   } else {
     found=false;
   }
   return found;
 }

}


 </source>
   
  
 
  



Retrieves the manifest from a JAR file and writes the manifest contents to a file.

   <source lang="java">
   

import java.io.FileOutputStream; import java.io.OutputStream; import java.util.jar.JarFile; import java.util.jar.Manifest; public class Main {

 public static void main(String[] argv) throws Exception {
   JarFile jarfile = new JarFile("filename.jar");
   Manifest manifest = jarfile.getManifest();
   OutputStream fos = new FileOutputStream("manifest");
   jarfile.getManifest().write(fos);
   fos.close();
 }

}



 </source>
   
  
 
  



Search all jar and zip files in the current directory for a given class file

   <source lang="java">
  

/*

* The QueryForm License, Version 1.1
*
* Copyright (c) 1998 - 2003 David F. Glasser.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:
*       "This product includes software developed by 
*        David F. Glasser."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "QueryForm" and "David F. Glasser" must
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written
*    permission, please contact dglasser@pobox.ru.
*
* 5. Products derived from this software may not be called "QueryForm",
*    nor may "QueryForm" appear in their name, without prior written
*    permission of David F. Glasser.
*
* THIS SOFTWARE IS PROVIDED ``AS IS"" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL DAVID F. GLASSER, THE APACHE SOFTWARE 
* FOUNDATION OR ITS CONTRIBUTORS, OR ANY AUTHORS OR DISTRIBUTORS
* OF THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* 
*
* This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/).
*
* 
*
* $Source: /cvsroot/qform/qform/src/org/glasser/util/JarSearcher.java,v $
* $Revision: 1.1 $
* $Author: dglasser $
* $Date: 2003/01/25 23:17:02 $
* 
* --------------------------------------------------------------------
*/

import java.io.*; import java.util.*; import java.util.zip.*; import java.io.*; /**

* This program will search all jar and zip files in the current directory for
* a given class file.
* 
* @author Dave Glasser
*/

public class JarSearcher {

   /**
    * Returns true if the jar or zip file at jarFilePath contains (with the internal
    * path) the file named by classFilePath. 
    */
   public static boolean searchJarFile(String jarFilePath, String classFilePath) {
       return searchJarFile( new File(jarFilePath), classFilePath);
   }
   public static boolean searchJarFile(File file, String classFilePath) {
       try {
           if(!file.exists()) return false;
   
           ZipFile jarFile = new ZipFile(file);
           if(jarFile.getEntry(classFilePath) != null) {
               jarFile.close();
               return true;
           }
           else {
               jarFile.close();
               return false;
           }
       }
       catch(IOException ex) {
           System.out.println(ex.toString());
           return false;
       }
   }


 static class ArchiveFilter implements FileFilter {
   public boolean accept(File pathName) {
     String upcase = pathName.getName().toUpperCase();
     if(upcase.endsWith(".ZIP") || upcase.endsWith(".JAR")) return true;
     return false;
   }
 }
   public static void main (String[] args)  {
       if(args.length == 0) {
           System.out.println("usage: java ClassFinder <class name>\n\n"
                              + "example: java ClassFinder java.lang.String\n");
           System.exit(0);
       }
       File cwd = new File(".");
       File[] archives = cwd.listFiles(new ArchiveFilter());
   
       String classFileName = args[0].replace(".", "/");
       if(classFileName.endsWith(".class") == false) {
           classFileName += ".class";
       }
   
       System.out.println("Searching for " + classFileName + " ...");
       for(int j=0; j<archives.length; j++) {
   //      System.out.println("Searching " + archives[j].getName());
         if(searchJarFile(archives[j], classFileName)) {
           System.out.println("FOUND IN " + archives[j].getName());
         }
       }
   }

}


 </source>
   
  
 
  



Search class in class path and Jar files

   <source lang="java">

/*

* $Id: ClassSearchUtils.java,v 1.1 2009/03/01 12:01:11 rah003 Exp $
*
* Copyright 2009 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* 
* This library 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
* Lesser General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*
*/

import java.awt.HeadlessException; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.StringTokenizer; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Logger; public class ClassSearchUtils {

   private static final Logger log = Logger.getAnonymousLogger();
   /**
    * Classloader to be used to obtain resources from file system.
    */
   private ClassLoader classloader;
   /**
    * List of the resource found in the classpath.
    */
   private ArrayList list;
   /**
    * Extension of the resource to be found in the classpath.
    */
   private String extension;
   private String prefix;
   /**
    * Search for the resource with the extension in the classpath. Method
    * self-instantiate factory for every call to ensure thread safety.
    * @param extension Mandatory extension of the resource. If all resources
    * are required extension should be empty string. Null extension is not
    * allowed and will cause method to fail.
    * @return List of all resources with specified extension.
    */
   public static List<Class<?>> searchClassPath(String prefix) {
       return searchClassPath(prefix, ".class");
   }
   /**
    * Search for the resource with the extension in the classpath. Method
    * self-instantiate factory for every call to ensure thread safety.
    * @param extension Mandatory extension of the resource. If all resources
    * are required extension should be empty string. Null extension is not
    * allowed and will cause method to fail.
    * @return List of all resources with specified extension.
    */
   public static List searchClassPath(String prefix, String extension) {
       ClassSearchUtils factory = new ClassSearchUtils();
       factory.prefix = prefix;
       return factory.find(extension);
   }
   /**
    * Search for the resource with the extension in the classpath.
    * @param extension Mandatory extension of the resource. If all resources
    * are required extension should be empty string. Null extension is not
    * allowed and will cause method to fail.
    * @return List of all resources with specified extension.
    */
   private List<Class<?>> find(String extension) {
       this.extension = extension;
       this.list = new ArrayList();
       this.classloader = this.getClass().getClassLoader();
       String classpath = System.getProperty("java.class.path");
       try {
           Method method =
               this.classloader.getClass().getMethod("getClassPath", (Class<?>) null);
           if (method != null) {
               classpath = (String) method.invoke(this.classloader, (Object) null);
           }
       } catch (Exception e) {
           // ignore
       }
       if (classpath == null) {
           classpath = System.getProperty("java.class.path");
       }
       StringTokenizer tokenizer =
           new StringTokenizer(classpath, File.pathSeparator);
       String token;
       File dir;
       String name;
       while (tokenizer.hasMoreTokens()) {
           token = tokenizer.nextToken();
           dir = new File(token);
           if (dir.isDirectory()) {
               lookInDirectory("", dir);
           }
           if (dir.isFile()) {
               name = dir.getName().toLowerCase();
               if (name.endsWith(".zip") || name.endsWith(".jar")) {
                   this.lookInArchive(dir);
               }
           }
       }
       return this.list;
   }
   /**
    * @param name Name of to parent directories in java class notation (dot
    * separator)
    * @param dir Directory to be searched for classes.
    */
   private void lookInDirectory(String name, File dir) {
       log.fine( "Looking in directory [" + dir.getName() + "].");
       File[] files = dir.listFiles();
       File file;
       String fileName;
       final int size = files.length;
       for (int i = 0; i < size; i++) {
           file = files[i];
           fileName = file.getName();
           if (file.isFile()
               && fileName.toLowerCase().endsWith(this.extension)) {
               try {
                   if (this.extension.equalsIgnoreCase(".class")) {
                       fileName = fileName.substring(0, fileName.length() - 6);
                       // filter ignored resources
                       if (!(name + fileName).startsWith(this.prefix)) {
                           continue;
                       }
                       log.fine(
                           "Found class: [" + name + fileName + "].");
                       this.list.add(Class.forName(name + fileName));
                   } else {
                       this.list.add(
                           this.classloader.getResource(
                               name.replace(".", File.separatorChar)
                                   + fileName));
                   }
               } catch (ClassNotFoundException e) {
                   // ignore
               } catch (NoClassDefFoundError e) {
                       //ignore too
               } catch (ExceptionInInitializerError e) {
                   if (e.getCause() instanceof HeadlessException) {
                       // running in headless env ... ignore 
                   } else {
                       throw e;
                   }
               }
           }
           // search recursively.
           // I don"t like that but we will see how it will work.
           if (file.isDirectory()) {
               lookInDirectory(name + fileName + ".", file);
           }
       }
   }
   /**
    * Search archive files for required resource.
    * @param archive Jar or zip to be searched for classes or other resources.
    */
   private void lookInArchive(File archive) {
       log.fine(
           "Looking in archive ["
               + archive.getName()
               + "] for extension ["
               + this.extension
               + "].");
       JarFile jarFile = null;
       try {
           jarFile = new JarFile(archive);
       } catch (IOException e) {
           log.warning(
               "Non fatal error. Unable to read jar item.");
           return;
       }
       Enumeration entries = jarFile.entries();
       JarEntry entry;
       String entryName;
       while (entries.hasMoreElements()) {
           entry = (JarEntry) entries.nextElement();
           entryName = entry.getName();
           if (entryName.toLowerCase().endsWith(this.extension)) {
               try {
                   if (this.extension.equalsIgnoreCase(".class")) {
                       // convert name into java classloader notation
                       entryName =
                           entryName.substring(0, entryName.length() - 6);
                       entryName = entryName.replace("/", ".");
                       // filter ignored resources
                       if (!entryName.startsWith(this.prefix)) {
                           continue;
                       }
                       log.fine(
                           "Found class: [" + entryName + "]. ");
                       this.list.add(Class.forName(entryName));
                   } else {
                       this.list.add(this.classloader.getResource(entryName));
                       log.fine(
                           "Found appropriate resource with name ["
                               + entryName
                               + "]. Resource instance:"
                               + this.classloader.getResource(entryName));
                   }
               } catch (Throwable e) {
                   // ignore
                   log.warning(
                       "Unable to load resource ["
                           + entryName
                           + "] form file ["
                           + archive.getAbsolutePath()
                           + "].");
               }
           }
       }
   }

}

 </source>
   
  
 
  



Sign jar with the certificate named alias in the keystore

   <source lang="java">
   

jarsigner -keystore .keystore -storepass password myjar.jar alias



 </source>
   
  
 
  



Some utility classes for manipulating JAR files

   <source lang="java">
  

/*

* 
* 
* Copyright 2005 Vincent Massol.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* 
*   http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 
* 
*/

import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; /**

* Some utility classes for manipulating JAR files.
* 
* @version $Id $
*/

public final class JarUtils {

   /**
    * Create a jar file from a particular directory.
    * 
    * @param root in the root directory
    * @param directory in the directory we are adding
    * @param jarStream the jar stream to be added to
    * @throws IOException on IOException
    */
   protected void createJarFromDirectory(File root,
                                         File directory,
                                         JarOutputStream jarStream)
       throws IOException
   {
       byte[] buffer = new byte[40960];
       int bytesRead;
       File[] filesToAdd = directory.listFiles();
       for (int i = 0; i < filesToAdd.length; i++)
       {
           File fileToAdd = filesToAdd[i];
           if (fileToAdd.isDirectory())
           {
               createJarFromDirectory(root, fileToAdd, jarStream);
           }
           else
           {
               FileInputStream addFile = new FileInputStream(fileToAdd);
               try
               {
                   // Create a jar entry and add it to the temp jar.
                   String entryName = fileToAdd.getPath().substring(root.getPath().length() + 1);
                   
                   // If we leave these entries as "\"s, then the resulting zip file won"t be
                   // expandable on Unix operating systems like OSX, because it is possible to 
                   // have filenames with \s in them - so it"s impossible to determine that this 
                   // is actually a directory.
                   entryName = entryName.replace("\\", "/");
                   JarEntry entry = new JarEntry(entryName);
                   jarStream.putNextEntry(entry);
                   // Read the file and write it to the jar.
                   while ((bytesRead = addFile.read(buffer)) != -1)
                   {
                       jarStream.write(buffer, 0, bytesRead);
                   }
                   jarStream.closeEntry();
               }
               finally
               {
                   addFile.close();
               }
           }
       }
   }
   /**
    * Create a JAR file from a directory, recursing through children.
    * 
    * @param directory in directory source
    * @param outputJar in file to output the jar data to
    * @return out File that was generated
    * @throws IOException when there is an I/O exception
    */
   public File createJarFromDirectory(String directory, File outputJar)
       throws IOException
   {
       JarOutputStream jarStream = null;
       try
       {
           if (!outputJar.getParentFile().exists())
           {
               outputJar.getParentFile().mkdirs();
           }
           jarStream = new JarOutputStream(new FileOutputStream(outputJar));
           File dir = new File(directory);
           createJarFromDirectory(dir, dir, jarStream);
       }
       finally
       {
           if (jarStream != null)
           {
               jarStream.close();
           }
       }
       return outputJar;
   }

}


 </source>
   
  
 
  



Unjar a file

   <source lang="java">

/*

 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.JarURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import java.util.zip.ZipEntry; /** A utility class for dealing with Jar files. @author Scott.Stark@jboss.org @version $Revision: 2787 $

  • /

public final class JarUtils {

  /**
   * Hide the constructor
   */
  private JarUtils()
  {
  }
  
  /**
   * <P>This function will create a Jar archive containing the src
   * file/directory.  The archive will be written to the specified
* OutputStream.

   *
*

This is a shortcut for
* jar(out, new File[] { src }, null, null, null);

   *
   * @param out The output stream to which the generated Jar archive is
   *        written.
   * @param src The file or directory to jar up.  Directories will be
   *        processed recursively.
   * @throws IOException 
   */
  public static void jar(OutputStream out, File src) throws IOException
  {
     jar(out, new File[] { src }, null, null, null);
  }

  /**
*

This function will create a Jar archive containing the src * file/directory. The archive will be written to the specified * OutputStream.

   *
*

This is a shortcut for
* jar(out, src, null, null, null);

   *
   * @param out The output stream to which the generated Jar archive is
   *        written.
   * @param src The file or directory to jar up.  Directories will be
   *        processed recursively.
   * @throws IOException 
   */
  public static void jar(OutputStream out, File[] src) throws IOException
  {
     jar(out, src, null, null, null);
  }
  
  /**
*

This function will create a Jar archive containing the src * file/directory. The archive will be written to the specified * OutputStream. Directories are processed recursively, applying the * specified filter if it exists. * * <P>This is a shortcut for
* jar(out, src, filter, null, null);

   *
   * @param out The output stream to which the generated Jar archive is
   *        written.
   * @param src The file or directory to jar up.  Directories will be
   *        processed recursively.
   * @param filter The filter to use while processing directories.  Only
   *        those files matching will be included in the jar archive.  If
   *        null, then all files are included.
   * @throws IOException 
   */
  public static void jar(OutputStream out, File[] src, FileFilter filter)
     throws IOException
  {
     jar(out, src, filter, null, null);
  }
  
  /**
*

This function will create a Jar archive containing the src * file/directory. The archive will be written to the specified * OutputStream. Directories are processed recursively, applying the * specified filter if it exists. * * @param out The output stream to which the generated Jar archive is * written. * @param src The file or directory to jar up. Directories will be * processed recursively. * @param filter The filter to use while processing directories. Only * those files matching will be included in the jar archive. If * null, then all files are included. * @param prefix The name of an arbitrary directory that will precede all * entries in the jar archive. If null, then no prefix will be * used. * @param man The manifest to use for the Jar archive. If null, then no * manifest will be included. * @throws IOException */ public static void jar(OutputStream out, File[] src, FileFilter filter, String prefix, Manifest man) throws IOException { for (int i = 0; i < src.length; i++) { if (!src[i].exists()) { throw new FileNotFoundException(src.toString()); } } JarOutputStream jout; if (man == null) { jout = new JarOutputStream(out); } else { jout = new JarOutputStream(out, man); } if (prefix != null && prefix.length() > 0 && !prefix.equals("/")) { // strip leading "/" if (prefix.charAt(0) == "/") { prefix = prefix.substring(1); } // ensure trailing "/" if (prefix.charAt(prefix.length() - 1) != "/") { prefix = prefix + "/"; } } else { prefix = ""; } JarInfo info = new JarInfo(jout, filter); for (int i = 0; i < src.length; i++) { jar(src[i], prefix, info); } jout.close(); } /** * This simple convenience class is used by the jar method to reduce the * number of arguments needed. It holds all non-changing attributes * needed for the recursive jar method. */ private static class JarInfo { public JarOutputStream out; public FileFilter filter; public byte[] buffer; public JarInfo(JarOutputStream out, FileFilter filter) { this.out = out; this.filter = filter; buffer = new byte[1024]; } } /** * This recursive method writes all matching files and directories to * the jar output stream. */ private static void jar(File src, String prefix, JarInfo info) throws IOException { JarOutputStream jout = info.out; if (src.isDirectory()) { // create / init the zip entry prefix = prefix + src.getName() + "/"; ZipEntry entry = new ZipEntry(prefix); entry.setTime(src.lastModified()); entry.setMethod(JarOutputStream.STORED); entry.setSize(0L); entry.setCrc(0L); jout.putNextEntry(entry); jout.closeEntry(); // process the sub-directories File[] files = src.listFiles(info.filter); for (int i = 0; i < files.length; i++) { jar(files[i], prefix, info); } } else if (src.isFile()) { // get the required info objects byte[] buffer = info.buffer; // create / init the zip entry ZipEntry entry = new ZipEntry(prefix + src.getName()); entry.setTime(src.lastModified()); jout.putNextEntry(entry); // dump the file FileInputStream in = new FileInputStream(src); int len; while ((len = in.read(buffer, 0, buffer.length)) != -1) { jout.write(buffer, 0, len); } in.close(); jout.closeEntry(); } } public static void unjar(InputStream in, File dest) throws IOException { if (!dest.exists()) { dest.mkdirs(); } if (!dest.isDirectory()) { throw new IOException("Destination must be a directory."); } JarInputStream jin = new JarInputStream(in); byte[] buffer = new byte[1024]; ZipEntry entry = jin.getNextEntry(); while (entry != null) { String fileName = entry.getName(); if (fileName.charAt(fileName.length() - 1) == "/") { fileName = fileName.substring(0, fileName.length() - 1); } if (fileName.charAt(0) == "/") { fileName = fileName.substring(1); } if (File.separatorChar != "/") { fileName = fileName.replace("/", File.separatorChar); } File file = new File(dest, fileName); if (entry.isDirectory()) { // make sure the directory exists file.mkdirs(); jin.closeEntry(); } else { // make sure the directory exists File parent = file.getParentFile(); if (parent != null && !parent.exists()) { parent.mkdirs(); } // dump the file OutputStream out = new FileOutputStream(file); int len = 0; while ((len = jin.read(buffer, 0, buffer.length)) != -1) { out.write(buffer, 0, len); } out.flush(); out.close(); jin.closeEntry(); file.setLastModified(entry.getTime()); } entry = jin.getNextEntry(); } /* Explicity write out the META-INF/MANIFEST.MF so that any headers such as the Class-Path are see for the unpackaged jar */ Manifest mf = jin.getManifest(); if (mf != null) { File file = new File(dest, "META-INF/MANIFEST.MF"); File parent = file.getParentFile(); if( parent.exists() == false ) { parent.mkdirs(); } OutputStream out = new FileOutputStream(file); mf.write(out); out.flush(); out.close(); } jin.close(); } /** Given a URL check if its a jar url(jar:<url>!/archive) and if it is, extract the archive entry into the given dest directory and return a file URL to its location. If jarURL is not a jar url then it is simply returned as the URL for the jar. @param jarURL the URL to validate and extract the referenced entry if its a jar protocol URL @param dest the directory into which the nested jar will be extracted. @return the file: URL for the jar referenced by the jarURL parameter. * @throws IOException */ public static URL extractNestedJar(URL jarURL, File dest) throws IOException { // This may not be a jar URL so validate the protocol if( jarURL.getProtocol().equals("jar") == false ) return jarURL; String destPath = dest.getAbsolutePath(); URLConnection urlConn = jarURL.openConnection(); JarURLConnection jarConn = (JarURLConnection) urlConn; // Extract the archive to dest/jarName-contents/archive String parentArchiveName = jarConn.getJarFile().getName(); // Find the longest common prefix between destPath and parentArchiveName int length = Math.min(destPath.length(), parentArchiveName.length()); int n = 0; while( n < length ) { char a = destPath.charAt(n); char b = parentArchiveName.charAt(n); if( a != b ) break; n ++; } // Remove any common prefix from parentArchiveName parentArchiveName = parentArchiveName.substring(n); File archiveDir = new File(dest, parentArchiveName+"-contents"); if( archiveDir.exists() == false && archiveDir.mkdirs() == false ) throw new IOException("Failed to create contents directory for archive, path="+archiveDir.getAbsolutePath()); String archiveName = jarConn.getEntryName(); File archiveFile = new File(archiveDir, archiveName); File archiveParentDir = archiveFile.getParentFile(); if( archiveParentDir.exists() == false && archiveParentDir.mkdirs() == false ) throw new IOException("Failed to create parent directory for archive, path="+archiveParentDir.getAbsolutePath()); InputStream archiveIS = jarConn.getInputStream(); FileOutputStream fos = new FileOutputStream(archiveFile); BufferedOutputStream bos = new BufferedOutputStream(fos); byte[] buffer = new byte[4096]; int read; while( (read = archiveIS.read(buffer)) > 0 ) { bos.write(buffer, 0, read); } archiveIS.close(); bos.close(); // Return the file url to the extracted jar return archiveFile.toURL(); } public static void main(String[] args) throws Exception { if (args.length == 0) { System.out.println("usage: <x or c> <jar-archive> <files...>"); System.exit(0); } if (args[0].equals("x")) { BufferedInputStream in = new BufferedInputStream(new FileInputStream(args[1])); File dest = new File(args[2]); unjar(in, dest); } else if (args[0].equals("c")) { BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(args[1])); File[] src = new File[args.length - 2]; for (int i = 0; i < src.length; i++) { src[i] = new File(args[2 + i]); } jar(out, src); } else { System.out.println("Need x or c as first argument"); } } } </source>

When no entry is specified on the URL, the entry name is null

   <source lang="java">
   

import java.net.JarURLConnection; import java.net.URL; public class Main {

 public static void main(String[] argv) throws Exception {
   URL url = new URL("jar:file:/c://my.jar!/");
   JarURLConnection conn = (JarURLConnection) url.openConnection();
   String entryName = conn.getEntryName(); // null
 }

}



 </source>
   
  
 
  



Zip jar Imploder

   <source lang="java">
 

/*******************************************************************************

* Copyright (c) 2004, 2008 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /**

* @author Barry Feigenbaum
*/

public class ZipImploder {

 protected int dirCount, fileCount;
 /**
  * @return Returns the dirCount.
  */
 public int getDirCount() {
   return dirCount;
 }
 /**
  * @return Returns the fileCount.
  */
 public int getFileCount() {
   return fileCount;
 }
 /**
  * create a new imploder with no verbosity
  * 
  */
 public ZipImploder() {
   this(false);
 }
 /**
  * create a new imploder with the specified verbosity state
  * 
  * @param verbose -
  *          verbosity state
  */
 public ZipImploder(boolean verbose) {
   setVerbose(verbose);
 }
 protected boolean verbose;
 /**
  * get the verbose mode
  * 
  * @return verbosity mode
  */
 public boolean getVerbose() {
   return verbose;
 }
 /**
  * set the verbosity mode
  * 
  * @param f
  *          verbosity state
  */
 public void setVerbose(boolean f) {
   verbose = f;
 }
 protected String baseDir;
 /**
  * @return Returns the baseDir.
  */
 public String getBaseDir() {
   return baseDir;
 }
 /**
  * @param baseDir
  *          The baseDir to set.
  * @throws IOException
  */
 public void setBaseDir(String baseDir) throws IOException {
   if (baseDir != null) {
     baseDir = new File(baseDir).getCanonicalPath();
     baseDir = baseDir.replace("\\", "/");
   }
   this.baseDir = baseDir;
 }
 protected Manifest manifest;
 /**
  * @return Returns the manifest
  */
 public Manifest getManifest() {
   return manifest;
 }
 /**
  * @param manifest
  *          The manifest to set.
  */
 public void setManifest(Manifest manifest) {
   this.manifest = manifest;
 }
 protected boolean includeDirs;
 /**
  * returns whether or not path information is included in .zip
  * 
  * @return true if path information is included,
  *         false otherwise
  */
 public boolean getIncludeDirs() {
   return includeDirs;
 }
 /**
  * set whether or not path information is included in .zip files
  * 
  * @param includeDirs
  *          include path inforamtion in .zip file
  */
 public void setIncludeDirs(boolean includeDirs) {
   this.includeDirs = includeDirs;
 }
 /**
  * implode source directory into .jar/.zip file
  * 
  * @param zipName
  *          name of target file
  * @param jarName
  *          name of target file
  * @param sourceDir
  *          source directory name
  * @exception IOException
  *              error creating a target file
  */
 public void process(String zipName, String jarName, String sourceDir) throws IOException {
   dirCount = 0;
   fileCount = 0;
   if (zipName != null) {
     processZip(zipName, sourceDir);
   }
   if (jarName != null) {
     processJar(jarName, sourceDir);
   }
 }
 /**
  * Implode target JAR file from a source directory
  * 
  * @param jarName
  *          name of target file
  * @param sourceDir
  *          source directory name
  * @exception IOException
  *              error creating a target file
  */
 public void processJar(String jarName, String sourceDir) throws IOException {
   processJar(jarName, sourceDir, null);
 }
 /**
  * Implode target JAR file from a source directory
  * 
  * @param jarName
  *          name of target file
  * @param sourceDir
  *          source directory name (
  * @param comment
  * @exception IOException
  *              error creating a target file
  */
 public void processJar(String jarName, String sourceDir, String comment) throws IOException {
   processJar(jarName, sourceDir, comment, -1, -1);
 }
 /**
  * Implode target JAR file from a source directory
  * 
  * @param jarName -
  *          name of target .jar
  * @param sourceDir -
  *          source directory
  * @param comment -
  *          comment for .jar file
  * @param method
  * @param level
  * @throws IOException
  */
 public void processJar(String jarName, String sourceDir, String comment, int method, int level)
     throws IOException {
   String dest = setup(jarName, sourceDir);
   Manifest man = getManifest();
   JarOutputStream jos = man != null ? new JarOutputStream(new BufferedOutputStream(
       new FileOutputStream(dest)), man) : new JarOutputStream(new BufferedOutputStream(
       new FileOutputStream(dest)));
   configure(jos, comment, method, level);
   process(jos, new File(sourceDir));
 }
 /**
  * Implode target JAR file from a source directory
  * 
  * @param zipName
  *          name of target file
  * @param sourceDir
  *          source directory name (
  * @exception IOException
  *              error creating a target file
  */
 public void processZip(String zipName, String sourceDir) throws IOException {
   processZip(zipName, sourceDir, null);
 }
 /**
  * Implode target zip file from a source directory
  * 
  * @param zipName
  * @param sourceDir
  * @param comment
  * @throws IOException
  */
 public void processZip(String zipName, String sourceDir, String comment) throws IOException {
   processZip(zipName, sourceDir, comment, -1, -1);
 }
 /**
  * Implode target zip file from a source directory
  * 
  * @param zipName
  * @param sourceDir
  * @param comment
  * @param method
  * @param level
  * @throws IOException
  */
 public void processZip(String zipName, String sourceDir, String comment, int method, int level)
     throws IOException {
   String dest = setup(zipName, sourceDir);
   ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
   configure(zos, comment, method, level);
   process(zos, new File(sourceDir));
 }
 protected void configure(ZipOutputStream zos, String comment, int method, int level) {
   if (comment != null) {
     zos.setComment(comment);
   }
   if (method >= 0) {
     zos.setMethod(method);
   }
   if (level >= 0) {
     zos.setLevel(level);
   }
 }
 protected String setup(String zipName, String sourceDir) throws IOException {
   File dir = new File(sourceDir);
   if (!dir.exists() && !dir.isDirectory()) {
     throw new IOException("source must exist and be a directory: " + dir);
   }
   String source = dir.getCanonicalPath();
   String dest = new File(zipName).getCanonicalPath();
   return dest;
 }
 protected void process(ZipOutputStream zos, File dir) throws IOException {
   try {
     processDir(zos, dir);
   } finally {
     zos.close();
   }
 }
 protected String removeDrive(String path) {
   return path.length() >= 2 && path.charAt(1) == ":" ? path.substring(2) : path;
 }
 protected String removeLead(String path) {
   if (baseDir != null && path.startsWith(baseDir)) {
     path = path.substring(baseDir.length());
     if (path.length() >= 1) {
       if (path.charAt(0) == "/" || path.charAt(0) == "\\") {
         path = path.substring(1); // drop leading /
       }
     }
   }
   return path;
 }
 public void processDir(ZipOutputStream zos, File dir) throws IOException {
   String path = dir.getCanonicalPath();
   path = path.replace("\\", "/");
   if (includeDirs) {
     if (baseDir == null || path.length() > baseDir.length()) {
       String xpath = removeDrive(removeLead(path));
       if (xpath.length() > 0) {
         xpath += "/";
         ZipEntry ze = new ZipEntry(xpath);
         zos.putNextEntry(ze);
       }
     }
   }
   dirCount++;
   String[] files = dir.list();
   for (int i = 0; i < files.length; i++) {
     String file = files[i];
     File f = new File(dir, file);
     if (f.isDirectory()) {
       processDir(zos, f);
     } else {
       processFile(zos, f);
     }
   }
 }
 /**
  * process a single file for a .zip file
  * 
  * @param zos
  * @param f
  * @throws IOException
  */
 public void processFile(ZipOutputStream zos, File f) throws IOException {
   String path = f.getCanonicalPath();
   path = path.replace("\\", "/");
   String xpath = removeDrive(removeLead(path));
   ZipEntry ze = new ZipEntry(xpath);
   ze.setTime(f.lastModified());
   ze.setSize(f.length());
   zos.putNextEntry(ze);
   fileCount++;
   try {
     copyFileEntry(zos, f);
   } finally {
     zos.closeEntry();
   }
 }
 protected void copyFileEntry(ZipOutputStream zos, File f) throws IOException {
   DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));
   try {
     copyFileEntry(zos, dis);
   } finally {
     try {
       dis.close();
     } catch (IOException ioe) {
     }
   }
 }
 protected void copyFileEntry(ZipOutputStream zos, DataInputStream dis) throws IOException {
   byte[] bytes = readAllBytes(dis);
   zos.write(bytes, 0, bytes.length);
 }
 // *** below may be slow for large files ***
 /** Read all the bytes in a stream */
 protected byte[] readAllBytes(DataInputStream is) throws IOException {
   byte[] bytes = new byte[0];
   for (int len = is.available(); len > 0; len = is.available()) {
     byte[] xbytes = new byte[len];
     int count = is.read(xbytes);
     if (count > 0) {
       byte[] nbytes = new byte[bytes.length + count];
       System.arraycopy(bytes, 0, nbytes, 0, bytes.length);
       System.arraycopy(xbytes, 0, nbytes, bytes.length, count);
       bytes = nbytes;
     }
   }
   return bytes;
 }
 protected void print(String s) {
   System.out.print(s);
 }
 /** Print command help text. */
 public static void printHelp() {
   System.out.println();
   System.out.println("Usage: java " + ZipImploder.class.getName());
   System.out.println("       (-jar <jarName> {-manifest <manfile>} | -zip <zipName>)");
   System.out.println("       -dir <sourceDir> {-lead <leadDir>} {-doDirs} {-verbose}");
   System.out.println("Where:");
   System.out.println("  <jarName>     path to target jar");
   System.out.println("  <zipName>     path to target zip");
   System.out.println("  <manfile>     path to manifest file");
   System.out.println("  <sourceDir>   path to source directory; must exist");
   System.out
       .println("  <leadDir>     partial lead path to remove from stored entries; default: <sourceDir>");
   System.out.println("  <noDirs>      skip output of directory entries");
   System.out.println("  <verbose>     output progress information");
   System.out.println("Note: switch case or order is not important");
 }
 protected static void reportError(String msg) {
   System.err.println(msg);
   // printHelp();
   System.exit(1);
 }
 /**
  * Main command line entry point.
  * 
  * @param args
  */
 public static void main(final String[] args) {
   if (args.length == 0) {
     printHelp();
     System.exit(0);
   }
   String zipName = null;
   String jarName = null;
   String manName = null;
   String sourceDir = null;
   String leadDir = null;
   boolean jarActive = false, manActive = false, zipActive = false, sourceDirActive = false, leadDirActive = false;
   boolean verbose = false;
   boolean noDirs = false;
   // process arguments
   for (int i = 0; i < args.length; i++) {
     String arg = args[i];
     if (arg.charAt(0) == "-") { // switch
       arg = arg.substring(1);
       if (arg.equalsIgnoreCase("jar")) {
         jarActive = true;
         manActive = false;
         zipActive = false;
         sourceDirActive = false;
         leadDirActive = false;
       } else if (arg.equalsIgnoreCase("manifest")) {
         jarActive = false;
         manActive = true;
         zipActive = false;
         sourceDirActive = false;
         leadDirActive = false;
       } else if (arg.equalsIgnoreCase("zip")) {
         zipActive = true;
         manActive = false;
         jarActive = false;
         sourceDirActive = false;
         leadDirActive = false;
       } else if (arg.equalsIgnoreCase("dir")) {
         jarActive = false;
         manActive = false;
         zipActive = false;
         sourceDirActive = true;
         leadDirActive = false;
       } else if (arg.equalsIgnoreCase("lead")) {
         jarActive = false;
         manActive = false;
         zipActive = false;
         sourceDirActive = false;
         leadDirActive = true;
       } else if (arg.equalsIgnoreCase("noDirs")) {
         noDirs = true;
         jarActive = false;
         manActive = false;
         zipActive = false;
         sourceDirActive = false;
         leadDirActive = false;
       } else if (arg.equalsIgnoreCase("verbose")) {
         verbose = true;
         jarActive = false;
         manActive = false;
         zipActive = false;
         sourceDirActive = false;
         leadDirActive = false;
       } else {
         reportError("Invalid switch - " + arg);
       }
     } else {
       if (jarActive) {
         if (jarName != null) {
           reportError("Duplicate value - " + arg);
         }
         jarName = arg;
       } else if (manActive) {
         if (manName != null) {
           reportError("Duplicate value - " + arg);
         }
         manName = arg;
       } else if (zipActive) {
         if (zipName != null) {
           reportError("Duplicate value - " + arg);
         }
         zipName = arg;
       } else if (sourceDirActive) {
         if (sourceDir != null) {
           reportError("Duplicate value - " + arg);
         }
         sourceDir = arg;
       } else if (leadDirActive) {
         if (leadDir != null) {
           reportError("Duplicate value - " + arg);
         }
         leadDir = arg;
       } else {
         reportError("Too many parameters - " + arg);
       }
     }
   }
   if (sourceDir == null || (zipName == null && jarName == null)) {
     reportError("Missing parameters");
   }
   if (manName != null && zipName != null) {
     reportError("Manifests not supported on ZIP files");
   }
   if (leadDir == null) {
     leadDir = new File(sourceDir).getAbsolutePath().replace("\\", "/") + "/";
   }
   if (verbose) {
     System.out.println("Effective command: "
         + ZipImploder.class.getName()
         + (jarName != null ? " -jar " + jarName
             + (manName != null ? " -manifest " + manName : "") : "")
         + (zipName != null ? " -zip " + zipName : "") + " -dir " + sourceDir + " -lead "
         + leadDir + (noDirs ? " -noDirs" : "") + (verbose ? " -verbose" : ""));
   }
   try {
     ZipImploder zi = new ZipImploder(verbose);
     if (leadDir != null) {
       zi.setBaseDir(leadDir);
     }
     if (manName != null) {
       BufferedInputStream bis = new BufferedInputStream(new FileInputStream(manName));
       try {
         zi.setManifest(new Manifest(bis));
       } finally {
         bis.close();
       }
     }
     zi.setIncludeDirs(!noDirs);
     zi.process(zipName, jarName, sourceDir);
     if (verbose) {
       System.out
           .println("\nDone Directories=" + zi.getDirCount() + " Files=" + zi.getFileCount());
     }
   } catch (IOException ioe) {
     System.err.println("Exception - " + ioe.getMessage());
     // ioe.printStackTrace(); // *** debug ***
     System.exit(2);
   }
 }

}


 </source>