Java/File Input Output/Jar File
Содержание
- 1 A class to find resources in the classpath by their mime-type specified in the MANIFEST.
- 2 Add a jar entry to the deployment archive
- 3 Add jar contents to the deployment archive under the given prefix
- 4 class for exploding jar/zip files onto the file system
- 5 Create a Jar archive containing the src file/directory
- 6 Create a URL that refers to a jar file in the file system
- 7 Create a URL that refers to an entry in the jar file
- 8 Create Jar file
- 9 Creating a JAR File
- 10 Determine whether a file is a JAR File.
- 11 Get resource from Jar file
- 12 Get the entry name; it should be the same as specified on URL
- 13 Get the jar entry
- 14 Get the jar file
- 15 Get the jar file from a URL
- 16 Getting a Jar File Using a URL
- 17 Helper Class to manipulate Java Archive File
- 18 InstallJars - a utility to download and install files, Jars and Zips.
- 19 JAR Archives: Jar Lister
- 20 JAR Archives: Packer200
- 21 JAR Archives: Unpacker200
- 22 Jar builder
- 23 Jar Entry OutputStream
- 24 Jar file helper to deployment
- 25 Jarring and unjarring files and directories.
- 26 List files in a jar file
- 27 Listing the Entries of a JAR File Manifest
- 28 Listing the Main Attributes in a JAR File Manifest
- 29 Load an Icon from a jar
- 30 Load an Image from a JAR file
- 31 Load resource from Jar file
- 32 Make Temp Jar
- 33 Manifest Writer
- 34 Reading a text file from a jar file without unzipping
- 35 Retreive Binary File From Jar
- 36 Retreive Text File From Jar
- 37 Retrieves the manifest from a JAR file and writes the manifest contents to a file.
- 38 Search all jar and zip files in the current directory for a given class file
- 39 Search class in class path and Jar files
- 40 Sign jar with the certificate named alias in the keystore
- 41 Some utility classes for manipulating JAR files
- 42 Unjar a file
- 43 When no entry is specified on the URL, the entry name is null
- 44 Zip jar Imploder
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 totrue
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 totrue
for verbose mode * @param sorted - * set totrue
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 * * @returntrue
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>