Author: markt
Date: Tue Nov 5 00:06:50 2013
New Revision: 1538836
URL: http://svn.apache.org/r1538836
Log:
First cut at adding resource tracking
Added:
tomcat/trunk/java/org/apache/catalina/WebResourceTraceWrapper.java
tomcat/trunk/java/org/apache/catalina/webresources/TraceWrapperInputStream.java
Modified:
tomcat/trunk/java/org/apache/catalina/WebResourceRoot.java
tomcat/trunk/java/org/apache/catalina/webresources/AbstractResource.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/JarWarResource.java
tomcat/trunk/java/org/apache/catalina/webresources/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/webresources/StandardRoot.java
Modified: tomcat/trunk/java/org/apache/catalina/WebResourceRoot.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/WebResourceRoot.java?rev=1538836&r1=1538835&r2=1538836&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/WebResourceRoot.java (original)
+++ tomcat/trunk/java/org/apache/catalina/WebResourceRoot.java Tue Nov 5
00:06:50 2013
@@ -360,6 +360,33 @@ public interface WebResourceRoot extends
long getCacheMaxObjectSize();
/**
+ * Controls whether the trace locked files feature is enabled. If enabled,
+ * all calls to methods that return objects that lock a file and need to be
+ * closed to release that lock (e.g. {@link WebResource#getInputStream()}
+ * will perform a number of additional tasks.
+ * <ul>
+ * <li>The stack trace at the point where the method was called will be
+ * recorded and associated with the returned object.</li>
+ * <li>The returned object will be wrapped so that the point where
close()
+ * (or equivalent) is called to release the resources can be
detected.
+ * Tracking of the object will cease once the resources have been
+ * released.</li>
+ * <li>All remaining locked resources on web application shutdown will be
+ * logged and then closed.</li>
+ * </ul>
+ *
+ * @param traceLockedFiles @true to enable it, @false to disable it
+ */
+ void setTraceLockedFiles(boolean traceLockedFiles);
+
+ /**
+ * Has the trace locked files feature been enabled?
+ *
+ * @return @true if it has been enabled, otherwise @false
+ */
+ boolean getTraceLockedFiles();
+
+ /**
* This method will be invoked by the context on a periodic basis and
allows
* the implementation a method that executes periodic tasks, such as
purging
* expired cache entries.
@@ -372,4 +399,8 @@ public interface WebResourceRoot extends
POST,
CLASSES_JAR
}
+
+ void registerTracedResource(WebResourceTraceWrapper traceWrapper);
+
+ void deregisterTracedResource(WebResourceTraceWrapper
traceWrapperInputStream);
}
Added: tomcat/trunk/java/org/apache/catalina/WebResourceTraceWrapper.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/WebResourceTraceWrapper.java?rev=1538836&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/WebResourceTraceWrapper.java (added)
+++ tomcat/trunk/java/org/apache/catalina/WebResourceTraceWrapper.java Tue Nov
5 00:06:50 2013
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+package org.apache.catalina;
+
+import java.io.Closeable;
+
+public interface WebResourceTraceWrapper extends Closeable {
+ Exception getCreatedBy();
+ String getName();
+}
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=1538836&r1=1538835&r2=1538836&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:06:50 2013
@@ -128,5 +128,19 @@ public abstract class AbstractResource i
}
+ @Override
+ public final InputStream getInputStream() {
+ InputStream is = doGetInputStream();
+
+ if (is == null || !root.getTraceLockedFiles()) {
+ return is;
+ }
+
+ return new TraceWrapperInputStream(root, getName(), is);
+ }
+
+ protected abstract InputStream doGetInputStream();
+
+
protected abstract Log getLog();
}
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=1538836&r1=1538835&r2=1538836&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:06:50 2013
@@ -123,7 +123,7 @@ public class FileResource extends Abstra
}
@Override
- public InputStream getInputStream() {
+ protected InputStream doGetInputStream() {
if (resource.exists()) {
try {
return new FileInputStream(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=1538836&r1=1538835&r2=1538836&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:06:50 2013
@@ -39,7 +39,7 @@ public class JarResource extends Abstrac
}
@Override
- public InputStream getInputStream() {
+ protected InputStream doGetInputStream() {
try {
JarFile jarFile = new JarFile(getBase());
InputStream is = jarFile.getInputStream(getResource());
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=1538836&r1=1538835&r2=1538836&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:06:50 2013
@@ -104,7 +104,7 @@ public class JarResourceRoot extends Abs
}
@Override
- public InputStream getInputStream() {
+ protected InputStream doGetInputStream() {
return null;
}
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=1538836&r1=1538835&r2=1538836&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:06:50 2013
@@ -45,7 +45,7 @@ public class JarWarResource extends Abst
}
@Override
- public InputStream getInputStream() {
+ protected InputStream doGetInputStream() {
try {
JarFile warFile = new JarFile(getBase());
JarEntry jarFileInWar = warFile.getJarEntry(archivePath);
Modified:
tomcat/trunk/java/org/apache/catalina/webresources/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/LocalStrings.properties?rev=1538836&r1=1538835&r2=1538836&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/webresources/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/webresources/LocalStrings.properties
Tue Nov 5 00:06:50 2013
@@ -33,6 +33,7 @@ standardRoot.checkStateNotStarted=The re
standardRoot.createInvalidFile=Unable to create WebResourceSet from [{0}]
standardRoot.createNoFileResourceSet=The FileResourceSet feature has not yet
been implemented
standardRoot.createUnknownType=Unable to create WebResourceSet of unknown type
[{0}]
+standardRoot.lockedFile=The web application [{0}] failed to close the file
[{1}] opened via the following stack trace
standardRoot.noContext=A Context has not been configured for this
WebResourceRoot
standardRoot.startInvalidMain=The main resource set specified [{0}] is not
valid
standardRoot.unsupportedProtocol=The URL protocol [{0}] is not supported by
this web resources implementation
\ No newline at end of file
Modified: tomcat/trunk/java/org/apache/catalina/webresources/StandardRoot.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/StandardRoot.java?rev=1538836&r1=1538835&r2=1538836&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/webresources/StandardRoot.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/webresources/StandardRoot.java Tue
Nov 5 00:06:50 2013
@@ -17,6 +17,7 @@
package org.apache.catalina.webresources;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
@@ -33,7 +34,10 @@ import org.apache.catalina.LifecycleStat
import org.apache.catalina.WebResource;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.WebResourceSet;
+import org.apache.catalina.WebResourceTraceWrapper;
import org.apache.catalina.util.LifecycleMBeanBase;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;
/**
@@ -51,6 +55,7 @@ import org.apache.tomcat.util.res.String
public class StandardRoot extends LifecycleMBeanBase
implements WebResourceRoot {
+ private static final Log log = LogFactory.getLog(Cache.class);
protected static final StringManager sm =
StringManager.getManager(Constants.Package);
@@ -65,6 +70,9 @@ public class StandardRoot extends Lifecy
private Cache cache = new Cache(this);
private boolean cachingAllowed = true;
+ private boolean traceLockedFiles = false;
+ private Set<WebResourceTraceWrapper> tracedResources = new HashSet<>();
+
// Constructs to make iteration over all WebResourceSets simpler
private ArrayList<WebResourceSet> mainResources = new ArrayList<>();
private ArrayList<ArrayList<WebResourceSet>> allResources =
@@ -431,6 +439,16 @@ public class StandardRoot extends Lifecy
}
@Override
+ public void setTraceLockedFiles(boolean traceLockedFiles) {
+ this.traceLockedFiles = traceLockedFiles;
+ }
+
+ @Override
+ public boolean getTraceLockedFiles() {
+ return traceLockedFiles;
+ }
+
+ @Override
public Context getContext() {
return context;
}
@@ -483,6 +501,19 @@ public class StandardRoot extends Lifecy
cache.backgroundProcess();
}
+
+ @Override
+ public void registerTracedResource(WebResourceTraceWrapper traceResource) {
+ tracedResources.add(traceResource);
+ }
+
+
+ @Override
+ public void deregisterTracedResource(WebResourceTraceWrapper
traceResource) {
+ tracedResources.remove(traceResource);
+ }
+
+
// ----------------------------------------------------------- JMX
Lifecycle
@Override
protected String getDomainInternal() {
@@ -575,6 +606,17 @@ public class StandardRoot extends Lifecy
}
jarResources.clear();
+ for (WebResourceTraceWrapper tracedResource : tracedResources) {
+ log.error(sm.getString("standardRoot.lockedFile",
+ context.getName(),
+ tracedResource.getName()),
+ tracedResource.getCreatedBy());
+ try {
+ tracedResource.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
cache.clear();
setState(LifecycleState.STOPPING);
Added:
tomcat/trunk/java/org/apache/catalina/webresources/TraceWrapperInputStream.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/TraceWrapperInputStream.java?rev=1538836&view=auto
==============================================================================
---
tomcat/trunk/java/org/apache/catalina/webresources/TraceWrapperInputStream.java
(added)
+++
tomcat/trunk/java/org/apache/catalina/webresources/TraceWrapperInputStream.java
Tue Nov 5 00:06:50 2013
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+package org.apache.catalina.webresources;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.catalina.WebResourceRoot;
+import org.apache.catalina.WebResourceTraceWrapper;
+
+class TraceWrapperInputStream extends InputStream implements
WebResourceTraceWrapper {
+
+ private final WebResourceRoot root;
+ private final String name;
+ private final InputStream is;
+ private final Exception creation;
+
+ TraceWrapperInputStream(WebResourceRoot root, String name, InputStream is)
{
+ this.root = root;
+ this.name = name;
+ this.is = is;
+ this.creation = new Exception();
+
+ root.registerTracedResource(this);
+ }
+
+ @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 {
+ root.deregisterTracedResource(this);
+ is.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();
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Exception getCreatedBy() {
+ return creation;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]