Author: veithen Date: Sat Sep 25 13:37:06 2010 New Revision: 1001210 URL: http://svn.apache.org/viewvc?rev=1001210&view=rev Log: Added a new module containing code to debug resource leaks caused by missing calls to TransportSender#cleanup.
Added: axis/axis2/java/transports/trunk/modules/debug/ axis/axis2/java/transports/trunk/modules/debug/pom.xml (with props) axis/axis2/java/transports/trunk/modules/debug/src/ axis/axis2/java/transports/trunk/modules/debug/src/main/ axis/axis2/java/transports/trunk/modules/debug/src/main/java/ axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/ axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/ axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/ axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/ axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/ axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/DebugTransportSender.java (with props) axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/Invocation.java (with props) axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/ReportScheduler.java (with props) axis/axis2/java/transports/trunk/src/site/apt/debug.apt Modified: axis/axis2/java/transports/trunk/pom.xml axis/axis2/java/transports/trunk/src/site/site.xml Added: axis/axis2/java/transports/trunk/modules/debug/pom.xml URL: http://svn.apache.org/viewvc/axis/axis2/java/transports/trunk/modules/debug/pom.xml?rev=1001210&view=auto ============================================================================== --- axis/axis2/java/transports/trunk/modules/debug/pom.xml (added) +++ axis/axis2/java/transports/trunk/modules/debug/pom.xml Sat Sep 25 13:37:06 2010 @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.axis2</groupId> + <artifactId>axis2-transports</artifactId> + <version>1.1.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + <groupId>org.apache.axis2</groupId> + <artifactId>axis2-transport-debug</artifactId> + <name>Apache Axis2 - Transport - Debugging tools</name> + <description>Contains a set of debugging tools for Axis2 transports</description> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.apache.axis2</groupId> + <artifactId>axis2-kernel</artifactId> + <version>${axis2.version}</version> + </dependency> + </dependencies> +</project> Propchange: axis/axis2/java/transports/trunk/modules/debug/pom.xml ------------------------------------------------------------------------------ svn:eol-style = native Added: axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/DebugTransportSender.java URL: http://svn.apache.org/viewvc/axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/DebugTransportSender.java?rev=1001210&view=auto ============================================================================== --- axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/DebugTransportSender.java (added) +++ axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/DebugTransportSender.java Sat Sep 25 13:37:06 2010 @@ -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.axis2.transport.debug; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.description.Parameter; +import org.apache.axis2.description.TransportOutDescription; +import org.apache.axis2.handlers.AbstractHandler; +import org.apache.axis2.transport.TransportSender; +import org.apache.axis2.util.Loader; + +public class DebugTransportSender extends AbstractHandler implements TransportSender { + private static final String INVOCATION_KEY = DebugTransportSender.class.getName() + ".INVOCATION"; + + private final Set<Invocation> invocations = Collections.synchronizedSet(new HashSet<Invocation>()); + private ReportScheduler scheduler; + private TransportSender target; + + public void init(ConfigurationContext confContext, TransportOutDescription transportOut) throws AxisFault { + Parameter targetClassParameter = transportOut.getParameter("targetClass"); + if (targetClassParameter == null) { + throw new AxisFault("targetClass parameter is mandatory"); + } + try { + target = (TransportSender)Loader.loadClass((String)targetClassParameter.getValue()).newInstance(); + } catch (Exception ex) { + throw new AxisFault("Unable to create target TransportSender", ex); + } + scheduler = new ReportScheduler(this); + new Thread(scheduler).start(); + target.init(confContext, transportOut); + } + + public void cleanup(MessageContext msgContext) throws AxisFault { + Invocation invocation = (Invocation)msgContext.getProperty(INVOCATION_KEY); + if (invocation == null) { + System.out.println("TransportSender#cleanup called without corresponding call to TransportSender#invoke!"); + } else if (!invocations.remove(invocation)) { + System.out.println("TransportSender#cleanup called twice for the same message context."); + } + scheduler.scheduleReport(); + target.cleanup(msgContext); + } + + public InvocationResponse invoke(MessageContext msgContext) throws AxisFault { + Invocation invocation = new Invocation(Thread.currentThread().getStackTrace()); + invocations.add(invocation); + msgContext.setProperty(INVOCATION_KEY, invocation); + scheduler.scheduleReport(); + return target.invoke(msgContext); + } + + public void stop() { + target.stop(); + scheduler.stop(); + generateReport(); + } + + void generateReport() { + synchronized (invocations) { + int size = invocations.size(); + if (size > 0) { + System.out.println("There is/are " + size + + " pending invocation(s) for which TransportSender#cleanup has not been called yet:"); + for (Invocation invocation : invocations) { + System.out.println(); + for (StackTraceElement ste : invocation.getStackTrace()) { + System.out.println(ste); + } + } + } + } + } +} Propchange: axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/DebugTransportSender.java ------------------------------------------------------------------------------ svn:eol-style = native Added: axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/Invocation.java URL: http://svn.apache.org/viewvc/axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/Invocation.java?rev=1001210&view=auto ============================================================================== --- axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/Invocation.java (added) +++ axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/Invocation.java Sat Sep 25 13:37:06 2010 @@ -0,0 +1,31 @@ +/* + * 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.axis2.transport.debug; + +class Invocation { + private final StackTraceElement[] stackTrace; + + public Invocation(StackTraceElement[] stackTrace) { + this.stackTrace = stackTrace; + } + + public StackTraceElement[] getStackTrace() { + return stackTrace; + } +} Propchange: axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/Invocation.java ------------------------------------------------------------------------------ svn:eol-style = native Added: axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/ReportScheduler.java URL: http://svn.apache.org/viewvc/axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/ReportScheduler.java?rev=1001210&view=auto ============================================================================== --- axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/ReportScheduler.java (added) +++ axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/ReportScheduler.java Sat Sep 25 13:37:06 2010 @@ -0,0 +1,58 @@ +/* + * 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.axis2.transport.debug; + +class ReportScheduler implements Runnable { + private final DebugTransportSender sender; + private long nextReport = -1; + private boolean running; + + public ReportScheduler(DebugTransportSender sender) { + this.sender = sender; + } + + public synchronized void run() { + while (running) { + try { + if (nextReport == -1) { + wait(); + } else { + long timeout = nextReport - System.currentTimeMillis(); + if (timeout > 0) { + wait(timeout); + } else { + sender.generateReport(); + } + } + } catch (InterruptedException ex) { + break; + } + } + } + + public synchronized void scheduleReport() { + nextReport = System.currentTimeMillis() + 10000; + notifyAll(); + } + + public synchronized void stop() { + running = false; + notifyAll(); + } +} Propchange: axis/axis2/java/transports/trunk/modules/debug/src/main/java/org/apache/axis2/transport/debug/ReportScheduler.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: axis/axis2/java/transports/trunk/pom.xml URL: http://svn.apache.org/viewvc/axis/axis2/java/transports/trunk/pom.xml?rev=1001210&r1=1001209&r2=1001210&view=diff ============================================================================== --- axis/axis2/java/transports/trunk/pom.xml (original) +++ axis/axis2/java/transports/trunk/pom.xml Sat Sep 25 13:37:06 2010 @@ -160,6 +160,7 @@ <module>modules/jms</module> <module>modules/sms</module> <module>modules/testkit</module> + <module>modules/debug</module> <module>modules/all</module> </modules> Added: axis/axis2/java/transports/trunk/src/site/apt/debug.apt URL: http://svn.apache.org/viewvc/axis/axis2/java/transports/trunk/src/site/apt/debug.apt?rev=1001210&view=auto ============================================================================== --- axis/axis2/java/transports/trunk/src/site/apt/debug.apt (added) +++ axis/axis2/java/transports/trunk/src/site/apt/debug.apt Sat Sep 25 13:37:06 2010 @@ -0,0 +1,53 @@ +~~ 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. + +Transport debugging tools + + The <<<axis2-transport-debug>>> module contains tools to debug transport related problems. + +* Locating missing calls to <<<TransportSender#cleanup(MessageContext)>>> + + The Axis2 transport API requires that <<<TransportSender#cleanup(MessageContext)>>> be called for + for every call to <<<TransportSender#invoke(MessageContext)>>>. This is necessary to allow the transport + sender to clean up resources after the response message has been processed. When using the <<<ServiceClient>>> + API, this is done explicitly by a call to <<<ServiceClient#cleanupTransport()>>> or implicitly + when sending another request. + + Failure to call <<<TransportSender#cleanup(MessageContext)>>> will cause resource leaks. + However, this type of problem is difficult to debug because the error that is triggered by + the resource leak usually can't be correlated directly with the <<<TransportSender#invoke(MessageContext)>>> + invocation(s) for which the cleanup has not been done. + + In these situations, <<<DebugTransportSender>>> comes to the rescue. It acts as a wrapper + around an existing <<<TransportSender>>> implementation and keeps track of the calls to + <<<TransportSender#invoke(MessageContext)>>> and <<<TransportSender#cleanup(MessageContext)>>>. + If it detects that <<<TransportSender#cleanup(MessageContext)>>> has not been called after a + given timeout, it will output a report containing the stack trace of the invocation of + <<<TransportSender#invoke(MessageContext)>>>. + + In order to enable this feature for a given transport, simply replace the configured + class by <<<org.apache.axis2.transport.debug.DebugTransportSender>>> and add a + <<<targetClass>>> parameter with the real (original) transport sender implementation. + Here is an example for the HTTP transport: + ++------------------------+ +<transportSender name="http" class="org.apache.axis2.transport.debug.DebugTransportSender"> + <parameter name="targetClass">org.apache.axis2.transport.http.CommonsHTTPTransportSender</parameter> + <parameter name="PROTOCOL">HTTP/1.1</parameter> + <parameter name="Transfer-Encoding">chunked</parameter> +</transportSender> ++------------------------+ Modified: axis/axis2/java/transports/trunk/src/site/site.xml URL: http://svn.apache.org/viewvc/axis/axis2/java/transports/trunk/src/site/site.xml?rev=1001210&r1=1001209&r2=1001210&view=diff ============================================================================== --- axis/axis2/java/transports/trunk/src/site/site.xml (original) +++ axis/axis2/java/transports/trunk/src/site/site.xml Sat Sep 25 13:37:06 2010 @@ -59,6 +59,7 @@ <item name="UDP" href="udp.html"/> <item name="XMPP" href="xmpp.html"/> <item name="SMS" href="sms.html"/> + <item name="Debug" href="debug.html"/> </item> <item name="Project Information" href="project-info.html"> <item name="Mailing Lists" href="mail-lists.html"/>