Spring MVC WebApp : @schedule: java-sdk-http-connection-reaper : Failed to Stop

amazon-dynamodb, java, spring, spring-mvc, tomcat

Solution

This is likely caused by the AWS library which starts a thread in the background called com.amazonaws.http.IdleConnectionReaper

You can shut it down by implementing a ServletContextListener to close it on shutdown

public class YourListener implements ServletContextListener {

@Override
public void contextInitialized(ServletContextEvent contextEvent) {

}

@Override
public void contextDestroyed(ServletContextEvent contextEvent) {

    try {
        com.amazonaws.http.IdleConnectionReaper.shutdown();
    } catch (Throwable t) {
        // log the error
    }
}
}

and adding this to your web.xml

<listener>
    <listener-class>
        your.package.YourListener 
    </listener-class>
</listener>

Problem

I have a Web Application(using Spring 3.1) which uses @Scheduled Annotation for periodically executing a worker task (scheduled delay). The worker task opens up a connection to AWS DynamoDb and does some DB read/updates. When I stop the webapp (from Tomcat manager) I get this message in catalina.out: "SEVERE: The web application [] appears to have started a thread named [java-sdk-http-connection-reaper] but has failed to stop it. This is very likely to create a memory leak." I get a feeling that this has something to do with my scheduled task still running even after Tomcat stops. ``` @Service public class TaskScheduler implements ApplicationListener<ContextClosedEvent>{ @Autowired private WorkerTask workerTask; AmazonDynamoDBClient myDbConn = null; private TaskScheduler() { myDbConn = new AWSConnector("aws.properties").getDynamoConnection(); } /* * Will be repeatedly called, 10 seconds after the finish of the previous * invocation. */ @Scheduled(fixedDelay=100000) public void process() { System.out.println("Scheduling worker task"); //worker task does some db read/writes Future<String> status = workerTask.work(myDbConn); if (status.isDone()) { System.out.println("Completed Task"); return; } } @Override public void onApplicationEvent(ContextClosedEvent arg0) { if(event instanceof ContextClosedEvent) { // TODO Auto-generated method stub if(myDbConn != null) { this.myDbConn.shutdown(); } } } ``` dispatcher-servlet.xml: ``` <task:annotation-driven scheduler="taskScheduler"/> <task:scheduler id="taskScheduler" pool-size="2"/> ...... <bean id="TaskScheduler" class="com.sample.TaskScheduler"/> ``` Am I doing this correctly? a) I don't explicitly start the TaskScheduler. So i'm assuming spring takes care of starting this service. The 'this.myDbConn.shutdown()' is called. Despite this, I get the error. I'm using Spring MVC.

Original source