You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/05/14 22:57:18 UTC
svn commit: r1482590 - in
/tomcat/trunk/java/org/apache/catalina/webresources:
AbstractFileResourceSet.java AbstractResourceSet.java JarResource.java
JarResourceSet.java
Author: markt
Date: Tue May 14 20:57:17 2013
New Revision: 1482590
URL: http://svn.apache.org/r1482590
Log:
Refactor handling of JAR resources so that JAR files containing resources (including WARs) are not permanently locked.
Modified:
tomcat/trunk/java/org/apache/catalina/webresources/AbstractFileResourceSet.java
tomcat/trunk/java/org/apache/catalina/webresources/AbstractResourceSet.java
tomcat/trunk/java/org/apache/catalina/webresources/JarResource.java
tomcat/trunk/java/org/apache/catalina/webresources/JarResourceSet.java
Modified: tomcat/trunk/java/org/apache/catalina/webresources/AbstractFileResourceSet.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/AbstractFileResourceSet.java?rev=1482590&r1=1482589&r2=1482590&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/webresources/AbstractFileResourceSet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/webresources/AbstractFileResourceSet.java Tue May 14 20:57:17 2013
@@ -121,10 +121,5 @@ public abstract class AbstractFileResour
}
- @Override
- protected void destroyInternal() throws LifecycleException {
- // NO-OP
- }
-
protected abstract void checkType(File file);
}
Modified: tomcat/trunk/java/org/apache/catalina/webresources/AbstractResourceSet.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/AbstractResourceSet.java?rev=1482590&r1=1482589&r2=1482590&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/webresources/AbstractResourceSet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/webresources/AbstractResourceSet.java Tue May 14 20:57:17 2013
@@ -91,4 +91,9 @@ public abstract class AbstractResourceSe
protected final void stopInternal() throws LifecycleException {
setState(LifecycleState.STOPPING);
}
+
+ @Override
+ protected final void destroyInternal() throws LifecycleException {
+ // NO-OP
+ }
}
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=1482590&r1=1482589&r2=1482590&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/webresources/JarResource.java (original)
+++ tomcat/trunk/java/org/apache/catalina/webresources/JarResource.java Tue May 14 20:57:17 2013
@@ -35,12 +35,12 @@ public class JarResource extends Abstrac
private static final Log log = LogFactory.getLog(JarResource.class);
- private final JarFile base;
+ private final String base;
private final String baseUrl;
private final JarEntry resource;
private final String name;
- public JarResource(WebResourceRoot root, JarFile base, String baseUrl,
+ public JarResource(WebResourceRoot root, String base, String baseUrl,
JarEntry jarEntry, String internalPath, String webAppPath) {
super(root, webAppPath);
this.base = base;
@@ -117,7 +117,9 @@ public class JarResource extends Abstrac
@Override
public InputStream getInputStream() {
try {
- return base.getInputStream(resource);
+ JarFile jarFile = new JarFile(base);
+ InputStream is = jarFile.getInputStream(resource);
+ return new JarInputStreamWrapper(jarFile, is);
} catch (IOException e) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("fileResource.getInputStreamFail",
@@ -149,4 +151,72 @@ public class JarResource extends Abstrac
protected Log getLog() {
return log;
}
+
+ private static class JarInputStreamWrapper extends InputStream {
+
+ private final JarFile jarFile;
+ private final InputStream is;
+
+
+ public JarInputStreamWrapper(JarFile jarFile, InputStream is) {
+ this.jarFile = jarFile;
+ this.is = is;
+ }
+
+
+ @Override
+ public int read() throws IOException {
+ return is.read();
+ }
+
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ return is.read(b);
+ }
+
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ return is.read(b, off, len);
+ }
+
+
+ @Override
+ public long skip(long n) throws IOException {
+ return is.skip(n);
+ }
+
+
+ @Override
+ public int available() throws IOException {
+ return is.available();
+ }
+
+
+ @Override
+ public void close() throws IOException {
+ // Closing the JarFile releases the file lock on the JAR and also
+ // closes all input streams created from the JarFile.
+ jarFile.close();
+ }
+
+
+ @Override
+ public synchronized void mark(int readlimit) {
+ is.mark(readlimit);
+ }
+
+
+ @Override
+ public synchronized void reset() throws IOException {
+ is.reset();
+ }
+
+
+ @Override
+ public boolean markSupported() {
+ return is.markSupported();
+ }
+ }
}
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=1482590&r1=1482589&r2=1482590&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/webresources/JarResourceSet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/webresources/JarResourceSet.java Tue May 14 20:57:17 2013
@@ -22,6 +22,8 @@ import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -36,7 +38,7 @@ import org.apache.catalina.util.Resource
*/
public class JarResourceSet extends AbstractResourceSet {
- private JarFile base;
+ private HashMap<String,JarEntry> jarFileEntries = new HashMap<>();
private String baseUrl;
private final String internalPath;
@@ -90,8 +92,8 @@ public class JarResourceSet extends Abst
* requested without the '/' subsequent calls to JarEntry.isDirectory()
* will return false.
*
- * Paths in JARs never start with '/'. Leading '/' need to be removed
- * before any JarFile.getEntry() call.
+ * Paths in JARs never start with '/'. Leading '/' need to be removed
+ * before any JarFile.getEntry() call.
*/
// If the JAR has been mounted below the web application root, return
@@ -106,23 +108,23 @@ public class JarResourceSet extends Abst
}
if (pathInJar.equals("")) {
// Special case
- return new JarResourceRoot(root, new File(base.getName()),
+ return new JarResourceRoot(root, new File(getBase()),
pathInJar, path);
} else {
JarEntry jarEntry = null;
if (!(pathInJar.charAt(pathInJar.length() - 1) == '/')) {
- jarEntry = base.getJarEntry(pathInJar + '/');
+ jarEntry = jarFileEntries.get(pathInJar + '/');
if (jarEntry != null) {
path = path + '/';
}
}
if (jarEntry == null) {
- jarEntry = base.getJarEntry(pathInJar);
+ jarEntry = jarFileEntries.get(pathInJar);
}
if (jarEntry == null) {
return new EmptyResource(root, path);
} else {
- return new JarResource(root, base, baseUrl, jarEntry,
+ return new JarResource(root, getBase(), baseUrl, jarEntry,
internalPath, path);
}
}
@@ -144,10 +146,9 @@ public class JarResourceSet extends Abst
if (pathInJar.charAt(0) == '/') {
pathInJar = pathInJar.substring(1);
}
- Enumeration<JarEntry> entries = base.entries();
- while (entries.hasMoreElements()) {
- JarEntry entry = entries.nextElement();
- String name = entry.getName();
+ Iterator<String> entries = jarFileEntries.keySet().iterator();
+ while (entries.hasNext()) {
+ String name = entries.next();
if (name.length() > pathInJar.length() &&
name.startsWith(pathInJar)) {
if (name.charAt(name.length() - 1) == '/') {
@@ -202,10 +203,9 @@ public class JarResourceSet extends Abst
pathInJar = pathInJar.substring(1);
}
- Enumeration<JarEntry> entries = base.entries();
- while (entries.hasMoreElements()) {
- JarEntry entry = entries.nextElement();
- String name = entry.getName();
+ Iterator<String> entries = jarFileEntries.keySet().iterator();
+ while (entries.hasNext()) {
+ String name = entries.next();
if (name.length() > pathInJar.length() &&
name.startsWith(pathInJar)) {
int nextSlash = name.indexOf('/', pathInJar.length());
@@ -257,24 +257,20 @@ public class JarResourceSet extends Abst
@Override
protected void initInternal() throws LifecycleException {
- try {
- this.base = new JarFile(getBase());
+ try (JarFile jarFile = new JarFile(getBase())) {
+ Enumeration<JarEntry> entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ jarFileEntries.put(entry.getName(), entry);
+ }
} catch (IOException ioe) {
throw new IllegalArgumentException(ioe);
}
+
try {
this.baseUrl = (new File(getBase())).toURI().toURL().toString();
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
}
-
- @Override
- protected void destroyInternal() throws LifecycleException {
- try {
- this.base.close();
- } catch (IOException ioe) {
- throw new LifecycleException(ioe);
- }
- }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org