private static Tomcat createTomcat(int port, String contextPath, String docBase) throws ServletException { String tmpDir = System.getProperty("java.io.tmpdir"); Tomcat tomcat = new Tomcat(); tomcat.setBaseDir(tmpDir); tomcat.getHost().setAppBase(tmpDir); tomcat.getHost().setAutoDeploy(false); tomcat.getEngine().setBackgroundProcessorDelay(-1); tomcat.setConnector(newNioConnector()); tomcat.getConnector().setPort(port); tomcat.getService().addConnector(tomcat.getConnector()); Context context = tomcat.addWebapp(contextPath, docBase); StandardServer server = (StandardServer) tomcat.getServer(); server.addLifecycleListener(new AprLifecycleListener()); server.addLifecycleListener(new JreMemoryLeakPreventionListener()); return tomcat; }
@Override public void setUp() throws Exception { super.setUp(); Tomcat tomcat = getTomcatInstance(); // BZ 49218: The test fails if JreMemoryLeakPreventionListener is not // present. The listener affects the JVM, and thus not only the current, // but also the subsequent tests that are run in the same JVM. So it is // fair to add it in every test. tomcat.getServer().addLifecycleListener( new JreMemoryLeakPreventionListener()); }
@Override public void setUp() throws Exception { super.setUp(); Tomcat tomcat = getTomcatInstance(); // The test fails if JreMemoryLeakPreventionListener is not // present. The listener affects the JVM, and thus not only the current, // but also the subsequent tests that are run in the same JVM. So it is // fair to add it in every test. tomcat.getServer().addLifecycleListener( new JreMemoryLeakPreventionListener()); }
@Override public TomcatHostBuilder newStandardServer(int port, File baseDir, int httpPort, int ajpPort) { ContextResource memoryDatabase = new ContextResource(); memoryDatabase.setName("name"); memoryDatabase.setDescription("desc"); TomcatServerBuilder serverBuilder = newServer(port); if (baseDir != null) { serverBuilder.setCatalinaBase(baseDir); serverBuilder.setCatalinaHome(baseDir); } Map<String, String> connConfig = new HashMap<>(); connConfig.put(Constants.EXECUTOR_NAME_ATTR, DEFAULT_EXECUTOR_NAME); return serverBuilder.enableNaming() // .addLifecycleListener(SecurityListener.class) .addLifecycleListener(AprLifecycleListener.class) .addLifecycleListener(JreMemoryLeakPreventionListener.class) .addLifecycleListener(GlobalResourcesLifecycleListener.class) .addLifecycleListener(ThreadLocalLeakPreventionListener.class) .addGlobalResource(memoryDatabase) .addService(DEFAULT_SERVICE_NAME) // TODO .withDefaultRealm() .setBackgroundProcessorDelay(0) .setStartStopThreads(0) .addExecutor(DEFAULT_EXECUTOR_NAME, "tomcat-exec-", DEFAULT_EXECUTOR_MIN, DEFAULT_EXECUTOR_MAX, EMPTY_MAP) .addConnector(Tomcat.PROTOCOL_BIO, httpPort, connConfig) .addConnector(Tomcat.PROTOCOL_AJP, ajpPort, connConfig) .addHost(LOCALHOST, "webapps"); }
private static void configureServer(Server server) { LifecycleListener jasperListener = new JasperListener(); server.addLifecycleListener(jasperListener); jasperListener.lifecycleEvent(new LifecycleEvent(server, Lifecycle.BEFORE_INIT_EVENT, null)); server.addLifecycleListener(new JreMemoryLeakPreventionListener()); server.addLifecycleListener(new ThreadLocalLeakPreventionListener()); }
private static void configureServer(Server server) { //server.addLifecycleListener(new SecurityListener()); //server.addLifecycleListener(new AprLifecycleListener()); LifecycleListener jasperListener = new JasperListener(); server.addLifecycleListener(jasperListener); jasperListener.lifecycleEvent(new LifecycleEvent(server, Lifecycle.BEFORE_INIT_EVENT, null)); server.addLifecycleListener(new JreMemoryLeakPreventionListener()); //server.addLifecycleListener(new GlobalResourcesLifecycleListener()); server.addLifecycleListener(new ThreadLocalLeakPreventionListener()); }
@Test public void testThreadLocalLeak1() throws Exception { Tomcat tomcat = getTomcatInstance(); // Need to make sure we see a leak for the right reasons tomcat.getServer().addLifecycleListener( new JreMemoryLeakPreventionListener()); // No file system docBase required Context ctx = tomcat.addContext("", null); Tomcat.addServlet(ctx, "leakServlet1", "org.apache.tomcat.unittest.TesterLeakingServlet1"); ctx.addServletMapping("/leak1", "leakServlet1"); tomcat.start(); Executor executor = tomcat.getConnector().getProtocolHandler().getExecutor(); ((ThreadPoolExecutor) executor).setThreadRenewalDelay(-1); // Configure logging filter to check leak message appears LogValidationFilter f = new LogValidationFilter( "The web application [] created a ThreadLocal with key of"); LogManager.getLogManager().getLogger( "org.apache.catalina.loader.WebappClassLoaderBase").setFilter(f); // Need to force loading of all web application classes via the web // application class loader loadClass("TesterCounter", (WebappClassLoaderBase) ctx.getLoader().getClassLoader()); loadClass("TesterLeakingServlet1", (WebappClassLoaderBase) ctx.getLoader().getClassLoader()); // This will trigger the ThreadLocal creation int rc = getUrl("http://localhost:" + getPort() + "/leak1", new ByteChunk(), null); // Make sure request is OK Assert.assertEquals(HttpServletResponse.SC_OK, rc); // Destroy the context ctx.stop(); tomcat.getHost().removeChild(ctx); ctx = null; // Make sure we have a memory leak String[] leaks = ((StandardHost) tomcat.getHost()) .findReloadedContextMemoryLeaks(); Assert.assertNotNull(leaks); Assert.assertTrue(leaks.length > 0); // Make sure the message was logged Assert.assertEquals(1, f.getMessageCount()); }
@Test public void testThreadLocalLeak2() throws Exception { Tomcat tomcat = getTomcatInstance(); // Need to make sure we see a leak for the right reasons tomcat.getServer().addLifecycleListener( new JreMemoryLeakPreventionListener()); // No file system docBase required Context ctx = tomcat.addContext("", null); Tomcat.addServlet(ctx, "leakServlet2", "org.apache.tomcat.unittest.TesterLeakingServlet2"); ctx.addServletMapping("/leak2", "leakServlet2"); tomcat.start(); Executor executor = tomcat.getConnector().getProtocolHandler().getExecutor(); ((ThreadPoolExecutor) executor).setThreadRenewalDelay(-1); // Configure logging filter to check leak message appears LogValidationFilter f = new LogValidationFilter( "The web application [] created a ThreadLocal with key of"); LogManager.getLogManager().getLogger( "org.apache.catalina.loader.WebappClassLoaderBase").setFilter(f); // Need to force loading of all web application classes via the web // application class loader loadClass("TesterCounter", (WebappClassLoaderBase) ctx.getLoader().getClassLoader()); loadClass("TesterThreadScopedHolder", (WebappClassLoaderBase) ctx.getLoader().getClassLoader()); loadClass("TesterLeakingServlet2", (WebappClassLoaderBase) ctx.getLoader().getClassLoader()); // This will trigger the ThreadLocal creation int rc = getUrl("http://localhost:" + getPort() + "/leak2", new ByteChunk(), null); // Make sure request is OK Assert.assertEquals(HttpServletResponse.SC_OK, rc); // Destroy the context ctx.stop(); tomcat.getHost().removeChild(ctx); ctx = null; // Make sure we have a memory leak String[] leaks = ((StandardHost) tomcat.getHost()) .findReloadedContextMemoryLeaks(); Assert.assertNotNull(leaks); Assert.assertTrue(leaks.length > 0); // Make sure the message was logged Assert.assertEquals(1, f.getMessageCount()); }
private static void configureServer(Server server) { server.addLifecycleListener(new JreMemoryLeakPreventionListener()); server.addLifecycleListener(new ThreadLocalLeakPreventionListener()); }
@Test public void testThreadLocalLeak1() throws Exception { Tomcat tomcat = getTomcatInstance(); // Need to make sure we see a leak for the right reasons tomcat.getServer().addLifecycleListener( new JreMemoryLeakPreventionListener()); // Must have a real docBase - just use temp Context ctx = tomcat.addContext("", System.getProperty("java.io.tmpdir")); Tomcat.addServlet(ctx, "leakServlet1", "org.apache.tomcat.unittest.TesterLeakingServlet1"); ctx.addServletMapping("/leak1", "leakServlet1"); tomcat.start(); // Configure logging filter to check leak message appears LogValidationFilter f = new LogValidationFilter( "The web application [] created a ThreadLocal with key of"); LogManager.getLogManager().getLogger( "org.apache.catalina.loader.WebappClassLoader").setFilter(f); // Need to force loading of all web application classes via the web // application class loader loadClass("TesterCounter", (WebappClassLoader) ctx.getLoader().getClassLoader()); loadClass("TesterLeakingServlet1", (WebappClassLoader) ctx.getLoader().getClassLoader()); // This will trigger the ThreadLocal creation int rc = getUrl("http://localhost:" + getPort() + "/leak1", new ByteChunk(), null); // Make sure request is OK Assert.assertEquals(HttpServletResponse.SC_OK, rc); // Destroy the context ctx.stop(); tomcat.getHost().removeChild(ctx); ctx = null; // Make sure we have a memory leak String[] leaks = ((StandardHost) tomcat.getHost()) .findReloadedContextMemoryLeaks(); Assert.assertNotNull(leaks); Assert.assertTrue(leaks.length > 0); // Make sure the message was logged Assert.assertEquals(1, f.getMessageCount()); }
@Test public void testThreadLocalLeak2() throws Exception { Tomcat tomcat = getTomcatInstance(); // Need to make sure we see a leak for the right reasons tomcat.getServer().addLifecycleListener( new JreMemoryLeakPreventionListener()); // Must have a real docBase - just use temp Context ctx = tomcat.addContext("", System.getProperty("java.io.tmpdir")); Tomcat.addServlet(ctx, "leakServlet2", "org.apache.tomcat.unittest.TesterLeakingServlet2"); ctx.addServletMapping("/leak2", "leakServlet2"); tomcat.start(); // Configure logging filter to check leak message appears LogValidationFilter f = new LogValidationFilter( "The web application [] created a ThreadLocal with key of"); LogManager.getLogManager().getLogger( "org.apache.catalina.loader.WebappClassLoader").setFilter(f); // Need to force loading of all web application classes via the web // application class loader loadClass("TesterCounter", (WebappClassLoader) ctx.getLoader().getClassLoader()); loadClass("TesterThreadScopedHolder", (WebappClassLoader) ctx.getLoader().getClassLoader()); loadClass("TesterLeakingServlet2", (WebappClassLoader) ctx.getLoader().getClassLoader()); // This will trigger the ThreadLocal creation int rc = getUrl("http://localhost:" + getPort() + "/leak2", new ByteChunk(), null); // Make sure request is OK Assert.assertEquals(HttpServletResponse.SC_OK, rc); // Destroy the context ctx.stop(); tomcat.getHost().removeChild(ctx); ctx = null; // Make sure we have a memory leak String[] leaks = ((StandardHost) tomcat.getHost()) .findReloadedContextMemoryLeaks(); Assert.assertNotNull(leaks); Assert.assertTrue(leaks.length > 0); // Make sure the message was logged Assert.assertEquals(1, f.getMessageCount()); }