ASF Bugzilla – Attachment 34902 Details for
Bug 60963
Optimize class loading for unpackWARs=false case
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Proposed patch
unpack-war-optimisation.patch (text/plain), 11.34 KB, created by
Thomas Meyer
on 2017-04-07 15:58:50 UTC
(
hide
)
Description:
Proposed patch
Filename:
MIME Type:
Creator:
Thomas Meyer
Created:
2017-04-07 15:58:50 UTC
Size:
11.34 KB
patch
obsolete
>diff --git a/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java b/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java >index 195b8a8..da93b18 100644 >--- a/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java >+++ b/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java >@@ -179,7 +178,7 @@ public abstract class AbstractArchiveResourceSet extends AbstractResourceSet { > * @return The archives entries mapped to their names or null if > * {@link #getArchiveEntry(String)} should be used. > */ >- protected abstract HashMap<String,JarEntry> getArchiveEntries(boolean single); >+ protected abstract Map<String,JarEntry> getArchiveEntries(boolean single); > > > /** >diff --git a/java/org/apache/catalina/webresources/AbstractSingleArchiveResourceSet.java b/java/org/apache/catalina/webresources/AbstractSingleArchiveResourceSet.java >index 2257803..0d86ff9 100644 >--- a/java/org/apache/catalina/webresources/AbstractSingleArchiveResourceSet.java >+++ b/java/org/apache/catalina/webresources/AbstractSingleArchiveResourceSet.java >@@ -21,6 +21,7 @@ import java.io.IOException; > import java.net.MalformedURLException; > import java.util.Enumeration; > import java.util.HashMap; >+import java.util.Map; > import java.util.jar.JarEntry; > import java.util.jar.JarFile; > >@@ -59,7 +60,7 @@ public abstract class AbstractSingleArchiveResourceSet extends AbstractArchiveRe > > > @Override >- protected HashMap<String,JarEntry> getArchiveEntries(boolean single) { >+ protected Map<String,JarEntry> getArchiveEntries(boolean single) { > synchronized (archiveLock) { > if (archiveEntries == null && !single) { > JarFile jarFile = null; >diff --git a/java/org/apache/catalina/webresources/JarWarResource.java b/java/org/apache/catalina/webresources/JarWarResource.java >index 90321ee..729197f 100644 >--- a/java/org/apache/catalina/webresources/JarWarResource.java >+++ b/java/org/apache/catalina/webresources/JarWarResource.java >@@ -21,6 +21,8 @@ import java.io.InputStream; > import java.util.jar.JarEntry; > import java.util.jar.JarFile; > import java.util.jar.JarInputStream; >+import java.util.zip.ZipInputStream; >+import java.util.zip.ZipEntry; > > import org.apache.juli.logging.Log; > import org.apache.juli.logging.LogFactory; >@@ -47,26 +49,23 @@ public class JarWarResource extends AbstractArchiveResource { > > @Override > protected JarInputStreamWrapper getJarInputStreamWrapper() { >- JarFile warFile = null; >- JarInputStream jarIs = null; >- JarEntry entry = null; > try { >- warFile = getArchiveResourceSet().openJarFile(); >- JarEntry jarFileInWar = warFile.getJarEntry(archivePath); >- InputStream isInWar = warFile.getInputStream(jarFileInWar); >- >- jarIs = new JarInputStream(isInWar); >- entry = jarIs.getNextJarEntry(); >- while (entry != null && >- !entry.getName().equals(getResource().getName())) { >- entry = jarIs.getNextJarEntry(); >- } >- >+ JarEntry entry = getArchiveResourceSet().getArchiveEntries(false).get(getResource().getName()); > if (entry == null) { > return null; > } > >- return new JarInputStreamWrapper(entry, jarIs); >+ JarFile warFile = getArchiveResourceSet().openJarFile(); >+ JarEntry jarFileInWar = warFile.getJarEntry(archivePath); >+ >+ Long skipPos = ((JarWarResourceSet)getArchiveResourceSet()).getArchiveEntryPositions().get(getResource().getName()); >+ InputStream isInWar = warFile.getInputStream(jarFileInWar); >+ isInWar.skip(skipPos); >+ >+ /* entry exists and was alread verified */ >+ ZipInputStream zipIs = new ZipInputStream(isInWar); >+ ZipEntry ze = zipIs.getNextEntry(); >+ return new JarInputStreamWrapper(entry, zipIs); > } catch (IOException e) { > if (log.isDebugEnabled()) { > log.debug(sm.getString("jarResource.getInputStreamFail", >@@ -74,18 +73,6 @@ public class JarWarResource extends AbstractArchiveResource { > } > return null; > } finally { >- if (entry == null) { >- if (jarIs != null) { >- try { >- jarIs.close(); >- } catch (IOException ioe) { >- // Ignore >- } >- } >- if (warFile != null) { >- getArchiveResourceSet().closeJarFile(); >- } >- } > } > } > >diff --git a/java/org/apache/catalina/webresources/JarWarResourceSet.java b/java/org/apache/catalina/webresources/JarWarResourceSet.java >index 7f16b63..544ece0 100644 >--- a/java/org/apache/catalina/webresources/JarWarResourceSet.java >+++ b/java/org/apache/catalina/webresources/JarWarResourceSet.java >@@ -19,12 +19,18 @@ package org.apache.catalina.webresources; > import java.io.File; > import java.io.IOException; > import java.io.InputStream; >+import java.io.FilterInputStream; >+import java.io.PushbackInputStream; >+import java.util.zip.ZipInputStream; >+import java.util.zip.ZipEntry; > import java.net.MalformedURLException; > import java.util.HashMap; >+import java.util.Map; > import java.util.jar.JarEntry; > import java.util.jar.JarFile; > import java.util.jar.JarInputStream; > import java.util.jar.Manifest; >+import java.util.Collections; > > import org.apache.catalina.LifecycleException; > import org.apache.catalina.WebResource; >@@ -39,6 +45,7 @@ import org.apache.tomcat.util.buf.UriUtil; > public class JarWarResourceSet extends AbstractArchiveResourceSet { > > private final String archivePath; >+ private Map<String, Long> archiveEntryPositions; > > /** > * Creates a new {@link org.apache.catalina.WebResourceSet} based on a JAR >@@ -94,18 +101,20 @@ public class JarWarResourceSet extends AbstractArchiveResourceSet { > * returned. > */ > @Override >- protected HashMap<String,JarEntry> getArchiveEntries(boolean single) { >+ protected Map<String,JarEntry> getArchiveEntries(boolean single) { > synchronized (archiveLock) { > if (archiveEntries == null) { > JarFile warFile = null; >- InputStream jarFileIs = null; > archiveEntries = new HashMap<>(); >+ archiveEntryPositions = new HashMap<>(); >+ > try { > warFile = openJarFile(); > JarEntry jarFileInWar = warFile.getJarEntry(archivePath); >- jarFileIs = warFile.getInputStream(jarFileInWar); > >- try (JarInputStream jarIs = new JarInputStream(jarFileIs)) { >+ /* process and validate the JAR file */ >+ try (InputStream jarFileIs = warFile.getInputStream(jarFileInWar); >+ JarInputStream jarIs = new JarInputStream(jarFileIs)) { > JarEntry entry = jarIs.getNextJarEntry(); > while (entry != null) { > archiveEntries.put(entry.getName(), entry); >@@ -113,6 +122,22 @@ public class JarWarResourceSet extends AbstractArchiveResourceSet { > } > setManifest(jarIs.getManifest()); > } >+ >+ /* process again, this time with positions of PK entries */ >+ try (InputStream jarFileIs = warFile.getInputStream(jarFileInWar); >+ ZipInputStreamWithPosition zipIs = new ZipInputStreamWithPosition(jarFileIs)) { >+ long posBefore = zipIs.getBytesRead(); >+ ZipEntry entry = zipIs.getNextEntry(); >+ while (entry != null) { >+ if(archiveEntries.containsKey(entry.getName())) { >+ archiveEntryPositions.put(entry.getName(), posBefore); >+ } >+ zipIs.closeEntry(); >+ >+ posBefore = zipIs.getBytesRead(); >+ entry = zipIs.getNextEntry(); >+ } >+ } > } catch (IOException ioe) { > // Should never happen > archiveEntries = null; >@@ -121,16 +146,9 @@ public class JarWarResourceSet extends AbstractArchiveResourceSet { > if (warFile != null) { > closeJarFile(); > } >- if (jarFileIs != null) { >- try { >- jarFileIs.close(); >- } catch (IOException e) { >- // Ignore >- } >- } > } > } >- return archiveEntries; >+ return Collections.unmodifiableMap(archiveEntries); > } > } > >@@ -146,6 +164,9 @@ public class JarWarResourceSet extends AbstractArchiveResourceSet { > throw new IllegalStateException("Coding error"); > } > >+ public Map<String, Long> getArchiveEntryPositions() { >+ return Collections.unmodifiableMap(archiveEntryPositions); >+ } > > //-------------------------------------------------------- Lifecycle methods > @Override >@@ -169,3 +190,84 @@ public class JarWarResourceSet extends AbstractArchiveResourceSet { > } > } > } >+ >+class ZipInputStreamWithPosition extends ZipInputStream { >+ >+ public ZipInputStreamWithPosition(final InputStream in) throws IOException { >+ super(in); >+ this.in = new PushbackCountingInputStream(in, 512); >+ } >+ >+ /** >+ * Returns the current number of bytes read from this stream. >+ * @return the number of read bytes >+ */ >+ public long getBytesRead() { >+ return ((PushbackCountingInputStream)in).getBytesRead(); >+ } >+} >+ >+/** >+ * Stream that tracks the number of bytes read. >+ * @NotThreadSafe >+ */ >+class PushbackCountingInputStream extends PushbackInputStream { >+ private long bytesRead; >+ >+ public PushbackCountingInputStream(final InputStream in, int size) { >+ super(in, size); >+ } >+ >+ @Override >+ public int read() throws IOException { >+ final int r = super.read(); >+ if (r >= 0) { >+ count(1); >+ } >+ return r; >+ } >+ @Override >+ public int read(final byte[] b) throws IOException { >+ return read(b, 0, b.length); >+ } >+ @Override >+ public int read(final byte[] b, final int off, final int len) throws IOException { >+ final int r = super.read(b, off, len); >+ if (r >= 0) { >+ count(r); >+ } >+ return r; >+ } >+ /** >+ * Increments the counter of already read bytes. >+ * Doesn't increment if the EOF has been hit (read == -1) >+ * >+ * @param read the number of bytes read >+ */ >+ protected final void count(final long read) { >+ if (read != -1) { >+ bytesRead += read; >+ } >+ } >+ >+ /** >+ * Returns the current number of bytes read from this stream. >+ * @return the number of read bytes >+ */ >+ public long getBytesRead() { >+ return bytesRead; >+ } >+ >+ @Override >+ public void unread(int b) throws IOException { >+ super.unread(b); >+ bytesRead--; >+ } >+ >+ @Override >+ public void unread(byte[] b, int off, int len) throws IOException { >+ super.unread(b,off,len); >+ bytesRead -= len; >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 60963
:
34902
|
34980
|
34981