static StandardContext configure(Tomcat tomcat, Props props) { try { StandardContext context = (StandardContext) tomcat.addWebapp(getContextPath(props), webappPath(props)); context.setClearReferencesHttpClientKeepAliveThread(false); context.setClearReferencesStatic(false); context.setClearReferencesStopThreads(false); context.setClearReferencesStopTimerThreads(false); context.setClearReferencesStopTimerThreads(false); context.setAntiResourceLocking(false); context.setReloadable(false); context.setUseHttpOnly(true); context.setTldValidation(false); context.setXmlValidation(false); context.setXmlNamespaceAware(false); context.setUseNaming(false); context.setDelegate(true); context.setJarScanner(new NullJarScanner()); configureRails(props, context); for (Map.Entry<Object, Object> entry : props.rawProperties().entrySet()) { String key = entry.getKey().toString(); context.addParameter(key, entry.getValue().toString()); } return context; } catch (Exception e) { throw new IllegalStateException("Fail to configure webapp", e); } }
@Test public void testTimerThreadLeak() throws Exception { Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); if (ctx instanceof StandardContext) { ((StandardContext) ctx).setClearReferencesStopThreads(true); } ExecutorServlet executorServlet = new ExecutorServlet(); Tomcat.addServlet(ctx, "taskServlet", executorServlet); ctx.addServletMapping("/", "taskServlet"); tomcat.start(); // This will trigger the timer & thread creation getUrl("http://localhost:" + getPort() + "/"); // Stop the context ctx.stop(); // Should be shutdown once the stop() method above exists Assert.assertTrue(executorServlet.tpe.isShutdown()); // The time taken to shutdown the executor can vary between systems. Try // to avoid false test failures due to timing issues. Give the executor // upto 10 seconds to close down. int count = 0; while (count < 100 && !executorServlet.tpe.isTerminated()) { count++; Thread.sleep(100); } // If the executor has not terminated, there is a thread/memory leak Assert.assertTrue(executorServlet.tpe.isTerminated()); }