From: markt Date: Tue, 24 May 2011 16:04:08 +0000 (+0000) Subject: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=51226 X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=bb8c8b8f5339d3b442ad987659dc610389c02ce9;p=tomcat7.0 Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=51226 Add a findleaks Ant task for the Manager app. Based on a patch by Eiji Takahashi git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1127122 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/catalina/ant/FindLeaksTask.java b/java/org/apache/catalina/ant/FindLeaksTask.java new file mode 100644 index 000000000..7eda625b9 --- /dev/null +++ b/java/org/apache/catalina/ant/FindLeaksTask.java @@ -0,0 +1,57 @@ +/* + * 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.ant; + +import org.apache.tools.ant.BuildException; + +/** + * Ant task that implements the /findleaks command, supported by + * the Tomcat manager application. + */ +public class FindLeaksTask extends AbstractCatalinaTask { + + private boolean statusLine = true; + + /** + * Sets the statusLine parameter that controls if the response includes a + * status line or not. + */ + public void setStatusLine(boolean statusLine) { + this.statusLine = statusLine; + } + + /** + * Returns the statusLine parameter that controls if the response includes a + * status line or not. + */ + public boolean getStatusLine() { + return statusLine; + } + + /** + * Execute the requested operation. + * + * @exception BuildException if an error occurs + */ + @Override + public void execute() throws BuildException { + + super.execute(); + execute("/findleaks?statusLine=" + Boolean.toString(statusLine)); + } + +} diff --git a/java/org/apache/catalina/manager/HTMLManagerServlet.java b/java/org/apache/catalina/manager/HTMLManagerServlet.java index 7a5225a1d..d288ce10c 100644 --- a/java/org/apache/catalina/manager/HTMLManagerServlet.java +++ b/java/org/apache/catalina/manager/HTMLManagerServlet.java @@ -772,11 +772,16 @@ public final class HTMLManagerServlet extends ManagerServlet { StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); - super.findleaks(printWriter, smClient); + super.findleaks(false, printWriter, smClient); - if (stringWriter.getBuffer().length() > 0) { - msg.append(smClient.getString("htmlManagerServlet.findleaksList")); - msg.append(stringWriter.toString()); + String writerText = stringWriter.toString(); + + if (writerText.length() > 0) { + if (!writerText.startsWith("FAIL -")) { + msg.append(smClient.getString( + "htmlManagerServlet.findleaksList")); + } + msg.append(writerText); } else { msg.append(smClient.getString("htmlManagerServlet.findleaksNone")); } diff --git a/java/org/apache/catalina/manager/LocalStrings.properties b/java/org/apache/catalina/manager/LocalStrings.properties index 8e1f50aae..ae0a83f35 100644 --- a/java/org/apache/catalina/manager/LocalStrings.properties +++ b/java/org/apache/catalina/manager/LocalStrings.properties @@ -75,6 +75,8 @@ managerServlet.deployFailed=FAIL - Failed to deploy application at context path managerServlet.deployedButNotStarted=FAIL - Deployed application at context path {0} but context failed to start managerServlet.exception=FAIL - Encountered exception {0} managerServlet.findleaksFail=FAIL - Find leaks failed: Host not instance of StandardHost +managerServlet.findleaksList=OK - Found potential memory leaks in the following applications: +managerServlet.findleaksNone=OK - No memory leaks found managerServlet.invalidPath=FAIL - Invalid context path {0} was specified managerServlet.invalidWar=FAIL - Invalid application URL {0} was specified managerServlet.listed=OK - Listed applications for virtual host {0} diff --git a/java/org/apache/catalina/manager/ManagerServlet.java b/java/org/apache/catalina/manager/ManagerServlet.java index bbfc3e614..12bcb6083 100644 --- a/java/org/apache/catalina/manager/ManagerServlet.java +++ b/java/org/apache/catalina/manager/ManagerServlet.java @@ -335,6 +335,11 @@ public class ManagerServlet extends HttpServlet implements ContainerServlet { && (request.getParameter("update").equals("true"))) { update = true; } + + boolean statusLine = false; + if ("true".equals(request.getParameter("statusLine"))) { + statusLine = true; + } // Prepare our output writer to generate the response message response.setContentType("text/plain; charset=" + Constants.CHARSET); @@ -370,7 +375,7 @@ public class ManagerServlet extends HttpServlet implements ContainerServlet { } else if (command.equals("/undeploy")) { undeploy(writer, cn, smClient); } else if (command.equals("/findleaks")) { - findleaks(writer, smClient); + findleaks(statusLine, writer, smClient); } else { writer.println(smClient.getString("managerServlet.unknownCommand", command)); @@ -512,7 +517,8 @@ public class ManagerServlet extends HttpServlet implements ContainerServlet { /** * Find potential memory leaks caused by web application reload. */ - protected void findleaks(PrintWriter writer, StringManager smClient) { + protected void findleaks(boolean statusLine, PrintWriter writer, + StringManager smClient) { if (!(host instanceof StandardHost)) { writer.println(smClient.getString("managerServlet.findleaksFail")); @@ -522,11 +528,19 @@ public class ManagerServlet extends HttpServlet implements ContainerServlet { String[] results = ((StandardHost) host).findReloadedContextMemoryLeaks(); - for (String result : results) { - if ("".equals(result)) { - result = "/"; + if (results.length > 0) { + if (statusLine) { + writer.println( + smClient.getString("managerServlet.findleaksList")); + } + for (String result : results) { + if ("".equals(result)) { + result = "/"; + } + writer.println(result); } - writer.println(result); + } else if (statusLine) { + writer.println(smClient.getString("managerServlet.findleaksNone")); } } diff --git a/webapps/docs/manager-howto.xml b/webapps/docs/manager-howto.xml index cfa9f2be0..e2f3cd9e2 100644 --- a/webapps/docs/manager-howto.xml +++ b/webapps/docs/manager-howto.xml @@ -809,7 +809,7 @@ error message. Possible causes for problems include:

-http://localhost:8080/manager/text/findleaks +http://localhost:8080/manager/text/findleaks[?statusLine=[true|false]]

The find leaks diagnostic triggers a full garbage collection. It @@ -825,14 +825,18 @@ does not extend StandardHost.

Explicitly triggering a full garbage collection from Java code is documented to be unreliable. Furthermore, depending on the JVM used, there are options to disable explicit GC triggering, like -XX:+DisableExplicitGC. -If you want to make sure, that the diagnostics were successfully running a full GC, -you will need to check using tools like GC logging, JConsole or similar.

+If you want to make sure, that the diagnostics were successfully running a full +GC, you will need to check using tools like GC logging, JConsole or similar.

If this command succeeds, you will see a response like this:

/leaking-webapp +

If you wish to see a status line included in the response then include the +statusLine query parameter in the request with a value of +true.

+

Each context path for a web application that was stopped, reloaded or undeployed, but which classes from the previous runs are still loaded in memory, thus causing a memory leak, will be listed on a new line. If an application @@ -935,6 +939,7 @@ file might look something like this:

<taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask"/> <taskdef name="list" classname="org.apache.catalina.ant.ListTask"/> <taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask"/> + <taskdef name="findleaks" classname="org.apache.catalina.ant.FindLeaksTask"/> <taskdef name="resources" classname="org.apache.catalina.ant.ResourcesTask"/> <taskdef name="start" classname="org.apache.catalina.ant.StartTask"/> <taskdef name="stop" classname="org.apache.catalina.ant.StopTask"/>