Author: markt Date: Tue Nov 5 00:07:51 2013 New Revision: 1538837 URL: http://svn.apache.org/r1538837 Log: Make certificates and manifests available
Modified: tomcat/trunk/java/org/apache/catalina/WebResource.java tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java tomcat/trunk/java/org/apache/catalina/webresources/AbstractArchiveResource.java tomcat/trunk/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java tomcat/trunk/java/org/apache/catalina/webresources/AbstractResource.java tomcat/trunk/java/org/apache/catalina/webresources/CachedResource.java tomcat/trunk/java/org/apache/catalina/webresources/EmptyResource.java tomcat/trunk/java/org/apache/catalina/webresources/FileResource.java tomcat/trunk/java/org/apache/catalina/webresources/JarResource.java tomcat/trunk/java/org/apache/catalina/webresources/JarResourceRoot.java tomcat/trunk/java/org/apache/catalina/webresources/JarResourceSet.java tomcat/trunk/java/org/apache/catalina/webresources/JarWarResource.java tomcat/trunk/java/org/apache/catalina/webresources/JarWarResourceSet.java Modified: tomcat/trunk/java/org/apache/catalina/WebResource.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/WebResource.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/WebResource.java (original) +++ tomcat/trunk/java/org/apache/catalina/WebResource.java Tue Nov 5 00:07:51 2013 @@ -18,6 +18,8 @@ package org.apache.catalina; import java.io.InputStream; import java.net.URL; +import java.security.cert.Certificate; +import java.util.jar.Manifest; /** * Represents a file or directory within a web application. It borrows heavily @@ -139,4 +141,19 @@ public interface WebResource { * part. */ WebResourceRoot getWebResourceRoot(); + + /** + * Obtain the certificates that were used to sign this resource to verify + * it or @null if none. + * + * @see java.util.jar.JarEntry#getCertificates() + */ + Certificate[] getCertificates(); + + /** + * Obtain the manifest associated with this resource or @null if none. + * + * @see java.util.jar.JarFile#getManifest() + */ + Manifest getManifest(); } Modified: tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java (original) +++ tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java Tue Nov 5 00:07:51 2013 @@ -60,7 +60,6 @@ import java.util.concurrent.CopyOnWriteA import java.util.concurrent.ThreadPoolExecutor; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; -import java.util.jar.JarEntry; import java.util.jar.Manifest; import org.apache.catalina.Globals; @@ -2427,8 +2426,6 @@ public class WebappClassLoader extends U if (entry != null) return entry; - int contentLength = -1; - InputStream binaryStream = null; boolean isClassResource = path.endsWith(CLASS_FILE_SUFFIX); WebResource resource = null; @@ -2441,61 +2438,38 @@ public class WebappClassLoader extends U return null; } - contentLength = (int) resource.getContentLength(); entry = new ResourceEntry(); entry.source = resource.getURL(); entry.codeBase = entry.source; entry.lastModified = resource.getLastModified(); - binaryStream = resource.getInputStream(); - if (needConvert) { if (path.endsWith(".properties")) { fileNeedConvert = true; } } - JarEntry jarEntry = null; - - try { - - /* Only cache the binary content if there is some content - * available and either: - * a) It is a class file since the binary content is only cached - * until the class has been loaded - * or - * b) The file needs conversion to address encoding issues (see - * below) - * - * In all other cases do not cache the content to prevent - * excessive memory usage if large resources are present (see - * https://issues.apache.org/bugzilla/show_bug.cgi?id=53081). - */ - if (binaryStream != null && - (isClassResource || fileNeedConvert)) { - - byte[] binaryContent = new byte[contentLength]; - - int pos = 0; - try { - - while (true) { - int n = binaryStream.read(binaryContent, pos, - binaryContent.length - pos); - if (n <= 0) - break; - pos += n; - } - } catch (IOException e) { - log.error(sm.getString("webappClassLoader.readError", name), e); - return null; - } - if (fileNeedConvert) { + /* Only cache the binary content if there is some content + * available and either: + * a) It is a class file since the binary content is only cached + * until the class has been loaded + * or + * b) The file needs conversion to address encoding issues (see + * below) + * + * In all other cases do not cache the content to prevent + * excessive memory usage if large resources are present (see + * https://issues.apache.org/bugzilla/show_bug.cgi?id=53081). + */ + if (isClassResource || fileNeedConvert) { + byte[] binaryContent = resource.getContent(); + if (binaryContent != null) { + if (fileNeedConvert) { // Workaround for certain files on platforms that use // EBCDIC encoding, when they are read through FileInputStream. // See commit message of rev.303915 for details // http://svn.apache.org/viewvc?view=revision&revision=303915 - String str = new String(binaryContent,0,pos); + String str = new String(binaryContent); try { binaryContent = str.getBytes(StandardCharsets.UTF_8); } catch (Exception e) { @@ -2503,22 +2477,12 @@ public class WebappClassLoader extends U } } entry.binaryContent = binaryContent; - - // The certificates are only available after the JarEntry - // associated input stream has been fully read - // TODO - if (jarEntry != null) { - entry.certificates = jarEntry.getCertificates(); - } - - } - } finally { - if (binaryStream != null) { - try { - binaryStream.close(); - } catch (IOException e) { /* Ignore */} + // The certificates and manifest are made available as a side + // effect of reading the binary content + entry.certificates = resource.getCertificates(); } } + entry.manifest = resource.getManifest(); if (isClassResource && entry.binaryContent != null && this.transformers.size() > 0) { Modified: tomcat/trunk/java/org/apache/catalina/webresources/AbstractArchiveResource.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/AbstractArchiveResource.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/AbstractArchiveResource.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/AbstractArchiveResource.java Tue Nov 5 00:07:51 2013 @@ -20,8 +20,10 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; +import java.security.cert.Certificate; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.jar.Manifest; import org.apache.catalina.WebResourceRoot; @@ -30,15 +32,19 @@ public abstract class AbstractArchiveRes private final String base; private final String baseUrl; private final JarEntry resource; + private final Manifest manifest; private final String name; + private boolean readCerts = false; + private Certificate[] certificates; protected AbstractArchiveResource(WebResourceRoot root, String webAppPath, String base, String baseUrl, JarEntry jarEntry, - String internalPath) { + String internalPath, Manifest manifest) { super(root, webAppPath); this.base = base; this.baseUrl = baseUrl; this.resource = jarEntry; + this.manifest = manifest; String resourceName = resource.getName(); if (resourceName.charAt(resourceName.length() - 1) == '/') { @@ -137,15 +143,74 @@ public abstract class AbstractArchiveRes } } + @Override + public final byte[] getContent() { + long len = getContentLength(); + + if (len > Integer.MAX_VALUE) { + // Can't create an array that big + throw new ArrayIndexOutOfBoundsException(sm.getString( + "abstractResource.getContentTooLarge", getWebappPath(), + Long.valueOf(len))); + } + + int size = (int) len; + byte[] result = new byte[size]; + + int pos = 0; + try (JarInputStreamWrapper jisw = getJarInputStreamWrapper()) { + while (pos < size) { + int n = jisw.read(result, pos, size - pos); + if (n < 0) { + break; + } + pos += n; + } + // Once the stream has been read, read the certs + certificates = jisw.getCertificates(); + readCerts = true; + } catch (IOException ioe) { + if (getLog().isDebugEnabled()) { + getLog().debug(sm.getString("abstractResource.getContentFail", + getWebappPath()), ioe); + } + } + + return result; + } + + + @Override + public Certificate[] getCertificates() { + if (!readCerts) { + // TODO - get content first + throw new IllegalStateException(); + } + return certificates; + } - protected static class JarInputStreamWrapper extends InputStream { + @Override + public Manifest getManifest() { + return manifest; + } + + @Override + protected final InputStream doGetInputStream() { + return getJarInputStreamWrapper(); + } + + protected abstract JarInputStreamWrapper getJarInputStreamWrapper(); + + protected class JarInputStreamWrapper extends InputStream { private final JarFile jarFile; + private final JarEntry jarEntry; private final InputStream is; - public JarInputStreamWrapper(JarFile jarFile, InputStream is) { + public JarInputStreamWrapper(JarFile jarFile, JarEntry jarEntry, InputStream is) { this.jarFile = jarFile; + this.jarEntry = jarEntry; this.is = is; } @@ -204,5 +269,9 @@ public abstract class AbstractArchiveRes public boolean markSupported() { return is.markSupported(); } + + public Certificate[] getCertificates() { + return jarEntry.getCertificates(); + } } } Modified: tomcat/trunk/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java Tue Nov 5 00:07:51 2013 @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Set; import java.util.jar.JarEntry; +import java.util.jar.Manifest; import org.apache.catalina.WebResource; import org.apache.catalina.WebResourceRoot; @@ -32,8 +33,13 @@ public abstract class AbstractArchiveRes private final HashMap<String,JarEntry> jarFileEntries = new HashMap<>(); private String baseUrl; + private Manifest manifest; + protected void setManifest(Manifest manifest) { + this.manifest = manifest; + } + public String getBaseUrl() { return baseUrl; } @@ -216,7 +222,7 @@ public abstract class AbstractArchiveRes if (jarEntry == null) { return new EmptyResource(root, path); } else { - return createArchiveResource(jarEntry, path); + return createArchiveResource(jarEntry, path, manifest); } } } else { @@ -225,5 +231,5 @@ public abstract class AbstractArchiveRes } protected abstract WebResource createArchiveResource(JarEntry jarEntry, - String webAppPath); + String webAppPath, Manifest manifest); } Modified: tomcat/trunk/java/org/apache/catalina/webresources/AbstractResource.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/AbstractResource.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/AbstractResource.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/AbstractResource.java Tue Nov 5 00:07:51 2013 @@ -16,7 +16,6 @@ */ package org.apache.catalina.webresources; -import java.io.IOException; import java.io.InputStream; import java.util.Date; @@ -91,44 +90,6 @@ public abstract class AbstractResource i @Override - public final byte[] getContent() { - long len = getContentLength(); - - if (len > Integer.MAX_VALUE) { - // Can't create an array that big - throw new ArrayIndexOutOfBoundsException(sm.getString( - "abstractResource.getContentTooLarge", getWebappPath(), - Long.valueOf(len))); - } - - int size = (int) len; - byte[] result = new byte[size]; - - int pos = 0; - try (InputStream is = getInputStream()) { - if (is == null) { - return null; - } - - while (pos < size) { - int n = is.read(result, pos, size - pos); - if (n < 0) { - break; - } - pos += n; - } - } catch (IOException ioe) { - if (getLog().isDebugEnabled()) { - getLog().debug(sm.getString("abstractResource.getContentFail", - getWebappPath()), ioe); - } - } - - return result; - } - - - @Override public final InputStream getInputStream() { InputStream is = doGetInputStream(); Modified: tomcat/trunk/java/org/apache/catalina/webresources/CachedResource.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/CachedResource.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/CachedResource.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/CachedResource.java Tue Nov 5 00:07:51 2013 @@ -19,6 +19,8 @@ package org.apache.catalina.webresources import java.io.ByteArrayInputStream; import java.io.InputStream; import java.net.URL; +import java.security.cert.Certificate; +import java.util.jar.Manifest; import org.apache.catalina.WebResource; import org.apache.catalina.WebResourceRoot; @@ -235,6 +237,16 @@ public class CachedResource implements W } @Override + public Certificate[] getCertificates() { + return webResource.getCertificates(); + } + + @Override + public Manifest getManifest() { + return webResource.getManifest(); + } + + @Override public WebResourceRoot getWebResourceRoot() { return webResource.getWebResourceRoot(); } Modified: tomcat/trunk/java/org/apache/catalina/webresources/EmptyResource.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/EmptyResource.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/EmptyResource.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/EmptyResource.java Tue Nov 5 00:07:51 2013 @@ -18,6 +18,8 @@ package org.apache.catalina.webresources import java.io.InputStream; import java.net.URL; +import java.security.cert.Certificate; +import java.util.jar.Manifest; import org.apache.catalina.WebResource; import org.apache.catalina.WebResourceRoot; @@ -133,6 +135,16 @@ public class EmptyResource implements We } @Override + public Certificate[] getCertificates() { + return null; + } + + @Override + public Manifest getManifest() { + return null; + } + + @Override public WebResourceRoot getWebResourceRoot() { return root; } Modified: tomcat/trunk/java/org/apache/catalina/webresources/FileResource.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/FileResource.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/FileResource.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/FileResource.java Tue Nov 5 00:07:51 2013 @@ -25,6 +25,8 @@ import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; import java.nio.file.attribute.BasicFileAttributes; +import java.security.cert.Certificate; +import java.util.jar.Manifest; import org.apache.catalina.WebResourceRoot; import org.apache.juli.logging.Log; @@ -137,6 +139,40 @@ public class FileResource extends Abstra } @Override + public final byte[] getContent() { + long len = getContentLength(); + + if (len > Integer.MAX_VALUE) { + // Can't create an array that big + throw new ArrayIndexOutOfBoundsException(sm.getString( + "abstractResource.getContentTooLarge", getWebappPath(), + Long.valueOf(len))); + } + + int size = (int) len; + byte[] result = new byte[size]; + + int pos = 0; + try (InputStream is = new FileInputStream(resource)) { + while (pos < size) { + int n = is.read(result, pos, size - pos); + if (n < 0) { + break; + } + pos += n; + } + } catch (IOException ioe) { + if (getLog().isDebugEnabled()) { + getLog().debug(sm.getString("abstractResource.getContentFail", + getWebappPath()), ioe); + } + } + + return result; + } + + + @Override public long getCreation() { try { BasicFileAttributes attrs = Files.readAttributes(resource.toPath(), @@ -168,6 +204,16 @@ public class FileResource extends Abstra } } + @Override + public Certificate[] getCertificates() { + return null; + } + + @Override + public Manifest getManifest() { + return null; + } + protected File getResourceInternal() { return resource; } Modified: tomcat/trunk/java/org/apache/catalina/webresources/JarResource.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/JarResource.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/JarResource.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/JarResource.java Tue Nov 5 00:07:51 2013 @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.jar.Manifest; import org.apache.catalina.WebResourceRoot; import org.apache.juli.logging.Log; @@ -34,16 +35,20 @@ public class JarResource extends Abstrac private static final Log log = LogFactory.getLog(JarResource.class); public JarResource(WebResourceRoot root, String webAppPath, String base, - String baseUrl, JarEntry jarEntry, String internalPath) { - super(root, webAppPath, base, "jar:" + baseUrl, jarEntry, internalPath); + String baseUrl, JarEntry jarEntry, String internalPath, + Manifest manifest) { + super(root, webAppPath, base, "jar:" + baseUrl, jarEntry, internalPath, + manifest); } @Override - protected InputStream doGetInputStream() { + protected JarInputStreamWrapper getJarInputStreamWrapper() { try { JarFile jarFile = new JarFile(getBase()); - InputStream is = jarFile.getInputStream(getResource()); - return new JarInputStreamWrapper(jarFile, is); + // Need to create a new JarEntry so the certificates can be read + JarEntry jarEntry = jarFile.getJarEntry(getResource().getName()); + InputStream is = jarFile.getInputStream(jarEntry); + return new JarInputStreamWrapper(jarFile, jarEntry, is); } catch (IOException e) { if (log.isDebugEnabled()) { log.debug(sm.getString("fileResource.getInputStreamFail", Modified: tomcat/trunk/java/org/apache/catalina/webresources/JarResourceRoot.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/JarResourceRoot.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/JarResourceRoot.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/JarResourceRoot.java Tue Nov 5 00:07:51 2013 @@ -20,6 +20,8 @@ import java.io.File; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; +import java.security.cert.Certificate; +import java.util.jar.Manifest; import org.apache.catalina.WebResourceRoot; import org.apache.juli.logging.Log; @@ -109,6 +111,11 @@ public class JarResourceRoot extends Abs } @Override + public byte[] getContent() { + return null; + } + + @Override public long getCreation() { return base.lastModified(); } @@ -130,4 +137,14 @@ public class JarResourceRoot extends Abs protected Log getLog() { return log; } + + @Override + public Certificate[] getCertificates() { + return null; + } + + @Override + public Manifest getManifest() { + return null; + } } Modified: tomcat/trunk/java/org/apache/catalina/webresources/JarResourceSet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/JarResourceSet.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/JarResourceSet.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/JarResourceSet.java Tue Nov 5 00:07:51 2013 @@ -22,6 +22,7 @@ import java.net.MalformedURLException; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.jar.Manifest; import org.apache.catalina.LifecycleException; import org.apache.catalina.WebResource; @@ -73,9 +74,9 @@ public class JarResourceSet extends Abst @Override protected WebResource createArchiveResource(JarEntry jarEntry, - String webAppPath) { + String webAppPath, Manifest manifest) { return new JarResource(getRoot(), webAppPath, getBase(), getBaseUrl(), - jarEntry, getInternalPath()); + jarEntry, getInternalPath(), manifest); } //-------------------------------------------------------- Lifecycle methods @@ -88,6 +89,7 @@ public class JarResourceSet extends Abst JarEntry entry = entries.nextElement(); getJarFileEntries().put(entry.getName(), entry); } + setManifest(jarFile.getManifest()); } catch (IOException ioe) { throw new IllegalArgumentException(ioe); } Modified: tomcat/trunk/java/org/apache/catalina/webresources/JarWarResource.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/JarWarResource.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/JarWarResource.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/JarWarResource.java Tue Nov 5 00:07:51 2013 @@ -21,6 +21,7 @@ import java.io.InputStream; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarInputStream; +import java.util.jar.Manifest; import org.apache.catalina.WebResourceRoot; import org.apache.juli.logging.Log; @@ -38,14 +39,14 @@ public class JarWarResource extends Abst public JarWarResource(WebResourceRoot root, String webAppPath, String base, String baseUrl, JarEntry jarEntry, String archivePath, - String internalPath) { + String internalPath, Manifest manifest) { super(root, webAppPath, base, "jar:war:" + baseUrl + "^/" + archivePath, - jarEntry, internalPath); + jarEntry, internalPath, manifest); this.archivePath = archivePath; } @Override - protected InputStream doGetInputStream() { + protected JarInputStreamWrapper getJarInputStreamWrapper() { try { JarFile warFile = new JarFile(getBase()); JarEntry jarFileInWar = warFile.getJarEntry(archivePath); @@ -72,7 +73,7 @@ public class JarWarResource extends Abst return null; } - return new JarInputStreamWrapper(warFile, jarIs); + return new JarInputStreamWrapper(warFile, entry, jarIs); } catch (IOException e) { if (log.isDebugEnabled()) { log.debug(sm.getString("fileResource.getInputStreamFail", Modified: tomcat/trunk/java/org/apache/catalina/webresources/JarWarResourceSet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/JarWarResourceSet.java?rev=1538837&r1=1538836&r2=1538837&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/webresources/JarWarResourceSet.java (original) +++ tomcat/trunk/java/org/apache/catalina/webresources/JarWarResourceSet.java Tue Nov 5 00:07:51 2013 @@ -23,6 +23,7 @@ import java.net.MalformedURLException; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarInputStream; +import java.util.jar.Manifest; import org.apache.catalina.LifecycleException; import org.apache.catalina.WebResource; @@ -76,9 +77,9 @@ public class JarWarResourceSet extends A @Override protected WebResource createArchiveResource(JarEntry jarEntry, - String webAppPath) { + String webAppPath, Manifest manifest) { return new JarWarResource(getRoot(), webAppPath, getBase(), getBaseUrl(), - jarEntry, archivePath, getInternalPath()); + jarEntry, archivePath, getInternalPath(), manifest); } //-------------------------------------------------------- Lifecycle methods @@ -95,8 +96,8 @@ public class JarWarResourceSet extends A getJarFileEntries().put(entry.getName(), entry); entry = jarIs.getNextJarEntry(); } + setManifest(jarIs.getManifest()); } - } catch (IOException ioe) { throw new IllegalArgumentException(ioe); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org