diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index ce18e29dd1..4bc842f0b9 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -45,6 +45,8 @@ Trunk (unreleased changes) HADOOP-6220. HttpServer wraps InterruptedExceptions by IOExceptions if interrupted in startup (stevel) + HADOOP-7703. Improved excpetion handling of shutting down web server. + (Devaraj K via Eric Yang) Release 0.23.0 - Unreleased diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java index c526e10286..37b89f4f89 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java @@ -210,7 +210,7 @@ public HttpServer(String name, String bindAddress, int port, webServer.setHandler(contexts); webAppContext = new WebAppContext(); - webAppContext.setDisplayName("WepAppsContext"); + webAppContext.setDisplayName(name); webAppContext.setContextPath("/"); webAppContext.setWar(appDir + "/" + name); webAppContext.getServletContext().setAttribute(CONF_CONTEXT_ATTRIBUTE, conf); @@ -696,8 +696,44 @@ public void start() throws IOException { * stop the server */ public void stop() throws Exception { - listener.close(); - webServer.stop(); + MultiException exception = null; + try { + listener.close(); + } catch (Exception e) { + LOG.error("Error while stopping listener for webapp" + + webAppContext.getDisplayName(), e); + exception = addMultiException(exception, e); + } + + try { + // clear & stop webAppContext attributes to avoid memory leaks. + webAppContext.clearAttributes(); + webAppContext.stop(); + } catch (Exception e) { + LOG.error("Error while stopping web app context for webapp " + + webAppContext.getDisplayName(), e); + exception = addMultiException(exception, e); + } + try { + webServer.stop(); + } catch (Exception e) { + LOG.error("Error while stopping web server for webapp " + + webAppContext.getDisplayName(), e); + exception = addMultiException(exception, e); + } + + if (exception != null) { + exception.ifExceptionThrow(); + } + + } + + private MultiException addMultiException(MultiException exception, Exception e) { + if(exception == null){ + exception = new MultiException(); + } + exception.add(e); + return exception; } public void join() throws InterruptedException { diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServerLifecycle.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServerLifecycle.java index a205bf8519..27dd67f39c 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServerLifecycle.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServerLifecycle.java @@ -56,16 +56,14 @@ private void assertNotLive(HttpServer server) { * * @throws Throwable on failure */ - @Test public void testStartedServerIsAlive() throws Throwable { + @Test + public void testStartedServerIsAlive() throws Throwable { HttpServer server = null; - try { - server = createTestServer(); - assertNotLive(server); - server.start(); - assertAlive(server); - } finally { - stop(server); - } + server = createTestServer(); + assertNotLive(server); + server.start(); + assertAlive(server); + stop(server); } /** @@ -105,4 +103,24 @@ private void assertToStringContains(HttpServer server, String text) { assertNotLive(server); } + /** + * Test that the server is alive once started + * + * @throws Throwable + * on failure + */ + @Test + public void testWepAppContextAfterServerStop() throws Throwable { + HttpServer server = null; + String key = "test.attribute.key"; + String value = "test.attribute.value"; + server = createTestServer(); + assertNotLive(server); + server.start(); + server.setAttribute(key, value); + assertAlive(server); + assertEquals(value, server.getAttribute(key)); + stop(server); + assertNull("Server context should have cleared", server.getAttribute(key)); + } }