Java Tutorial/File/JarFile

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

A class to find resources in the classpath by their mime-type specified in the 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.
 */
/* $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:<br>
 * 
 * <pre>
 * Name: test.txt
 * Content-Type: text/plain
 * </pre>
 */
public final class ClasspathResource {
    /**
     * Actual Type: Map&lt;String,List&lt;URL&gt;&gt;.
     */
    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&lt;URL&gt;, 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());
    }
}





Add jar contents to the deployment archive under the given prefix

/*
 * 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);
    }
  }
}





Create JarFile and use Pack200.Packer

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();
  }
}





Creating a JAR File

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





Get CRC code for each file in a Jar file

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");
      }
    }
  }
}





Get file comment

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");
      }
    }
  }
}





Get jar file Attribute

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]);
        }
      }
    }
  }
}





Get resource from Jar file

/**
 * 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;
  }
}





Get the jar entry

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();
  }
}





Get the jar file

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();
  }
}





Get uncompressed and compressed file size in a Jar file

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);
    }
  }
}





Get zip method: ZipEntry.STORED, ZipEntry.DEFLATED

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) + "%");
      }
    }
  }
}





JAR Archives: Jar Lister

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();
    }
  }
}





JAR Archives: Packer200

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();
  }
}





JAR Archives: Unpacker200

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();
  }
}





Jar Entry OutputStream

/*
 * 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();
        }
    }
}





List all file names in a jar file

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);
    }
  }
}





Listing the Entries of a JAR File Manifest

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);
      }
    }
  }
}





Listing the Main Attributes in a JAR File Manifest

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);
    }
  }
}





Load resource from Jar file

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");
  }
}





Make Temp Jar

/*
 * 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;
}

}





Manifest Writer

/*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;
    }
  }
}





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

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();
  }
}





Search class in class path and Jar files

/*
 * $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()
                            + "].");
                }
            }
        }
    }
}