Java Tutorial/File/JarFile
Содержание
- 1 A class to find resources in the classpath by their mime-type specified in the MANIFEST.
- 2 Add jar contents to the deployment archive under the given prefix
- 3 Create JarFile and use Pack200.Packer
- 4 Creating a JAR File
- 5 Get CRC code for each file in a Jar file
- 6 Get file comment
- 7 Get jar file Attribute
- 8 Get resource from Jar file
- 9 Get the jar entry
- 10 Get the jar file
- 11 Get uncompressed and compressed file size in a Jar file
- 12 Get zip method: ZipEntry.STORED, ZipEntry.DEFLATED
- 13 JAR Archives: Jar Lister
- 14 JAR Archives: Packer200
- 15 JAR Archives: Unpacker200
- 16 Jar Entry OutputStream
- 17 List all file names in a jar file
- 18 Listing the Entries of a JAR File Manifest
- 19 Listing the Main Attributes in a JAR File Manifest
- 20 Load resource from Jar file
- 21 Make Temp Jar
- 22 Manifest Writer
- 23 Retrieves the manifest from a JAR file and writes the manifest contents to a file.
- 24 Search class in class path and Jar files
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. * * 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 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>
Create JarFile and use Pack200.Packer
<source lang="java">
import java.io.FileOutputStream; import java.io.OutputStream; import java.util.jar.JarFile; import java.util.jar.Pack200; public class MainClass {
public static void main(String[] args) throws Exception { OutputStream out = null; JarFile f = new JarFile(args[0]); Pack200.Packer packer = Pack200.newPacker(); out = new FileOutputStream(args[0] + ".pack"); packer.pack(f, out); out.close(); }
}</source>
Creating a JAR File
<source lang="java">
// Create the jar file jar cf myjar.jar MyClass.class</source>
Get CRC code for each file in a Jar file
<source lang="java">
import java.io.IOException; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class MainClass {
public static void main(String[] args) throws IOException { JarFile jf = new JarFile(args[0]); Enumeration e = jf.entries(); while (e.hasMoreElements()) { JarEntry je = (JarEntry) e.nextElement(); String name = je.getName(); long crc = je.getCrc(); System.out.println("Its CRC is " + crc); String comment = je.getComment(); if (comment != null && !comment.equals("")) { System.out.println(comment); } if (je.isDirectory()) { System.out.println(name + " is a directory"); } } }
}</source>
Get file comment
<source lang="java">
import java.io.IOException; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class MainClass {
public static void main(String[] args) throws IOException { JarFile jf = new JarFile(args[0]); Enumeration e = jf.entries(); while (e.hasMoreElements()) { JarEntry je = (JarEntry) e.nextElement(); String name = je.getName(); long crc = je.getCrc(); System.out.println("Its CRC is " + crc); String comment = je.getComment(); if (comment != null && !comment.equals("")) { System.out.println(comment); } if (je.isDirectory()) { System.out.println(name + " is a directory"); } } }
}</source>
Get jar file Attribute
<source lang="java">
import java.io.IOException; import java.util.Enumeration; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class MainClass {
public static void main(String[] args) throws IOException { JarFile jf = new JarFile(args[0]); Enumeration e = jf.entries(); while (e.hasMoreElements()) { JarEntry je = (JarEntry) e.nextElement(); String name = je.getName(); 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]); } } } }
}</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 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 uncompressed and compressed file size in a Jar file
<source lang="java">
import java.io.IOException; import java.util.Date; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class MainClass {
public static void main(String[] args) throws IOException { JarFile jf = new JarFile(args[0]); Enumeration e = jf.entries(); while (e.hasMoreElements()) { JarEntry je = (JarEntry) e.nextElement(); String name = je.getName(); Date lastModified = new Date(je.getTime()); long uncompressedSize = je.getSize(); long compressedSize = je.getCompressedSize(); System.out.println(lastModified); System.out.println(uncompressedSize); System.out.println(compressedSize); } }
}</source>
Get zip method: ZipEntry.STORED, ZipEntry.DEFLATED
<source lang="java">
import java.io.IOException; import java.util.Date; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; public class MainClass {
public static void main(String[] args) throws IOException { JarFile jf = new JarFile(args[0]); Enumeration e = jf.entries(); while (e.hasMoreElements()) { JarEntry je = (JarEntry) e.nextElement(); String name = je.getName(); Date lastModified = new Date(je.getTime()); long uncompressedSize = je.getSize(); long compressedSize = je.getCompressedSize(); int method = je.getMethod(); if (method == ZipEntry.STORED) { System.out.println(name + " was stored at " + lastModified); System.out.println("with a size of " + uncompressedSize + " bytes"); } else if (method == ZipEntry.DEFLATED) { System.out.println(name + " was deflated at " + lastModified); System.out.println("from " + uncompressedSize + " bytes to " + compressedSize + " bytes, a savings of " + (100.0 - 100.0*compressedSize/uncompressedSize) + "%"); } else { System.out.println(name + " was compressed using an unrecognized method at " + lastModified); System.out.println("from " + uncompressedSize + " bytes to " + compressedSize + " bytes, a savings of " + (100.0 - 100.0*compressedSize/uncompressedSize) + "%"); } } }
}</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 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. * * 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>
List all file names in a jar file
<source lang="java">
import java.io.IOException; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class MainClass {
public static void main(String[] args) throws IOException { JarFile jf = new JarFile(args[0]); Enumeration e = jf.entries(); while (e.hasMoreElements()) { JarEntry je = (JarEntry) e.nextElement(); String name = je.getName(); System.out.println(name); } }
}</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 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>
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 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>