From abb142048634046c5aeee1381e18ebcda0eea4fb Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 20 Sep 2013 18:14:26 +0100 Subject: [PATCH] Fixes #55: stop() connector to unbind socket The `Tomcat.start()` has to happen to initialize the `ServletContext` but we can immediately stop the connector and then restart it when the context is finished refreshing. Seems to make curl fail quickly if an app is slow to start. --- .../sample/tomcat/web/SampleController.java | 2 +- .../TomcatEmbeddedServletContainer.java | 12 ++++++++++- ...TomcatEmbeddedServletContainerFactory.java | 20 ++++++++----------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/spring-boot-samples/spring-boot-sample-tomcat/src/main/java/org/springframework/boot/sample/tomcat/web/SampleController.java b/spring-boot-samples/spring-boot-sample-tomcat/src/main/java/org/springframework/boot/sample/tomcat/web/SampleController.java index 99bdc021f1..4e47d64c2e 100644 --- a/spring-boot-samples/spring-boot-sample-tomcat/src/main/java/org/springframework/boot/sample/tomcat/web/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-tomcat/src/main/java/org/springframework/boot/sample/tomcat/web/SampleController.java @@ -27,7 +27,7 @@ public class SampleController { @Autowired private HelloWorldService helloWorldService; - + @RequestMapping("/") @ResponseBody public String helloWorld() { diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainer.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainer.java index ea08b33dd5..d3303b3953 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainer.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainer.java @@ -55,6 +55,16 @@ public class TomcatEmbeddedServletContainer implements EmbeddedServletContainer private synchronized void initialize() throws EmbeddedServletContainerException { try { this.tomcat.start(); + try { + // Allow the server to start so the ServletContext is available, but stop + // the connector to prevent requests from being handled before the Spring + // context is ready: + Connector connector = this.tomcat.getConnector(); + connector.getProtocolHandler().stop(); + } + catch (Exception e) { + this.logger.error("Cannot pause connector: ", e); + } // Unlike Jetty, all Tomcat threads are daemon threads. We create a // blocking non-daemon to stop immediate shutdown Thread awaitThread = new Thread("container-" + (containerCounter++)) { @@ -77,7 +87,7 @@ public class TomcatEmbeddedServletContainer implements EmbeddedServletContainer Connector connector = this.tomcat.getConnector(); if (connector != null) { try { - connector.getProtocolHandler().resume(); + connector.getProtocolHandler().start(); } catch (Exception e) { this.logger.error("Cannot start connector: ", e); diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java index 55f1f790cc..27772be06f 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java @@ -131,15 +131,6 @@ public class TomcatEmbeddedServletContainerFactory extends customizeConnector(connector); tomcat.getService().addConnector(connector); tomcat.setConnector(connector); - try { - // Allow the server to start so the ServletContext is available, but stop the - // connector to prevent requests from being handled before the Spring context - // is ready: - connector.getProtocolHandler().pause(); - } - catch (Exception e) { - this.logger.error("Cannot pause connector: ", e); - } tomcat.getHost().setAutoDeploy(false); tomcat.getEngine().setBackgroundProcessorDelay(-1); @@ -203,10 +194,15 @@ public class TomcatEmbeddedServletContainerFactory extends // Needs to be protected so it can be used by subclasses protected void customizeConnector(Connector connector) { connector.setPort(getPort()); - if (connector.getProtocolHandler() instanceof AbstractProtocol - && getAddress() != null) { - ((AbstractProtocol) connector.getProtocolHandler()).setAddress(getAddress()); + if (connector.getProtocolHandler() instanceof AbstractProtocol) { + if (getAddress() != null) { + ((AbstractProtocol) connector.getProtocolHandler()) + .setAddress(getAddress()); + } } + // If ApplicationContext is slow to start we want Tomcat not to bind to the socket + // prematurely... + connector.setProperty("bindOnInit", "false"); } /**