diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index 85532a004ac..125356e7de1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -776,6 +776,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu } finally { + if (_availability==Availability.STARTING) + _availability=Availability.UNAVAILABLE; exitScope(null); __context.set(old_context); // reset the classloader diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java index f1854501774..6dff88c98c7 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java @@ -62,8 +62,10 @@ public class HotSwapHandler extends AbstractHandlerContainer @Override public Handler[] getHandlers() { - return new Handler[] - { _handler }; + Handler handler=_handler; + if (handler==null) + return new Handler[0]; + return new Handler[] { handler }; } /* ------------------------------------------------------------ */ @@ -73,14 +75,13 @@ public class HotSwapHandler extends AbstractHandlerContainer */ public void setHandler(Handler handler) { - if (handler == null) - throw new IllegalArgumentException("Parameter handler is null."); try { + Server server = getServer(); + if (handler!=null) + handler.setServer(server); updateBean(_handler,handler,true); _handler=handler; - Server server = getServer(); - handler.setServer(server); } catch (Exception e) @@ -116,9 +117,10 @@ public class HotSwapHandler extends AbstractHandlerContainer @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - if (_handler != null && isStarted()) + Handler handler=_handler; + if (handler != null && isStarted() && handler.isStarted()) { - _handler.handle(target,baseRequest,request,response); + handler.handle(target,baseRequest,request,response); } } @@ -126,7 +128,9 @@ public class HotSwapHandler extends AbstractHandlerContainer @Override protected void expandChildren(List list, Class byClass) { - expandHandler(_handler,list,byClass); + Handler handler=_handler; + if (handler!=null) + expandHandler(handler,list,byClass); } /* ------------------------------------------------------------ */ diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java index 2457a9043ec..2e1311821fa 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java @@ -538,7 +538,9 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container, { try { - stop((LifeCycle)bean._bean); + LifeCycle lc=(LifeCycle)bean._bean; + if (lc.isRunning()) + stop(lc); } catch(RuntimeException | Error e) { diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java index 391aaade1da..5ea461a921b 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java @@ -25,10 +25,14 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import javax.servlet.GenericServlet; import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -37,9 +41,11 @@ import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.HandlerList; +import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceCollection; +import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; @@ -237,4 +243,80 @@ public class WebAppContextTest this.getServletContext().getContext("/B/s"); } } + + @Test + public void testServletContextListener() throws Exception + { + Server server = new Server(); + ServletContextHandler context = new ServletContextHandler( + ServletContextHandler.SESSIONS); + context.setContextPath("/"); + context.setResourceBase(System.getProperty("java.io.tmpdir")); + server.setHandler(context); + + final List history=new ArrayList<>(); + + context.addEventListener(new ServletContextListener() + { + @Override + public void contextInitialized(ServletContextEvent servletContextEvent) + { + history.add("I1"); + } + + @Override + public void contextDestroyed(ServletContextEvent servletContextEvent) + { + history.add("D1"); + } + }); + context.addEventListener(new ServletContextListener() + { + @Override + public void contextInitialized(ServletContextEvent servletContextEvent) + { + history.add("I2"); + throw new RuntimeException("Listener2 broken"); + } + + @Override + public void contextDestroyed(ServletContextEvent servletContextEvent) + { + history.add("D2"); + } + }); + context.addEventListener(new ServletContextListener() + { + @Override + public void contextInitialized(ServletContextEvent servletContextEvent) + { + history.add("I3"); + } + + @Override + public void contextDestroyed(ServletContextEvent servletContextEvent) + { + history.add("D3"); + } + }); + + try + { + server.start(); + } + catch(Exception e) + { + // System.err.println(e); + } + finally + { + server.stop(); + } + + // TODO should be either: + // Assert.assertThat(history,Matchers.contains("I1","I2","D1")); + // or + // Assert.assertThat(history,Matchers.contains("I1","I2","D3","D3","D1")); + Assert.assertThat(history,Matchers.contains("I1","I2","D3","D2","D1")); + } }