From c44b912fc297e1fa5efc27a419eb05a3a451b4ed Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 11 Oct 2017 13:30:53 +0100 Subject: [PATCH] Ensure that Undertow is stopped when it fails to start Previously, if Undertow failed to start, some of Undertow's internal components would have been started but the started field of UndertowEmbeddedServletContainer remained false. This meant that when stop() was called nothing was done as the container believed it had not been started. This commit updates UndertowEmbeddedServletContainer to stop both the DeploymentManager and the Undertow instance in start() if an exception is thrown. This aligns the behaviour of UndertowEmbeddedServletContainer with that of the Tomcat equivalent. Closes gh-10528 --- .../UndertowEmbeddedServletContainer.java | 37 ++++++++++++++----- ...wEmbeddedServletContainerFactoryTests.java | 3 ++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainer.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainer.java index f654da7ea53..093a692ff59 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainer.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainer.java @@ -160,21 +160,40 @@ public class UndertowEmbeddedServletContainer implements EmbeddedServletContaine .info("Undertow started on port(s) " + getPortsDescription()); } catch (Exception ex) { - if (findBindException(ex) != null) { - List failedPorts = getConfiguredPorts(); - List actualPorts = getActualPorts(); - failedPorts.removeAll(actualPorts); - if (failedPorts.size() == 1) { - throw new PortInUseException( - failedPorts.iterator().next().getNumber()); + try { + if (findBindException(ex) != null) { + List failedPorts = getConfiguredPorts(); + List actualPorts = getActualPorts(); + failedPorts.removeAll(actualPorts); + if (failedPorts.size() == 1) { + throw new PortInUseException( + failedPorts.iterator().next().getNumber()); + } } + throw new EmbeddedServletContainerException( + "Unable to start embedded Undertow", ex); + } + finally { + stopSilently(); } - throw new EmbeddedServletContainerException( - "Unable to start embedded Undertow", ex); } } } + private void stopSilently() { + try { + if (this.manager != null) { + this.manager.stop(); + } + if (this.undertow != null) { + this.undertow.stop(); + } + } + catch (Exception ex) { + // Ignore + } + } + private BindException findBindException(Exception ex) { Throwable candidate = ex; while (candidate != null) { diff --git a/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java index 752fd71f8be..cebe2497ab2 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactoryTests.java @@ -318,6 +318,9 @@ public class UndertowEmbeddedServletContainerFactoryTests int blockedPort) { assertThat(ex).isInstanceOf(PortInUseException.class); assertThat(((PortInUseException) ex).getPort()).isEqualTo(blockedPort); + Object undertow = ReflectionTestUtils.getField(this.container, "undertow"); + Object worker = ReflectionTestUtils.getField(undertow, "worker"); + assertThat(worker).isNull(); } }