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
This commit is contained in:
Andy Wilkinson 2017-10-11 13:30:53 +01:00
parent c68173082d
commit c44b912fc2
2 changed files with 31 additions and 9 deletions

View File

@ -160,21 +160,40 @@ public class UndertowEmbeddedServletContainer implements EmbeddedServletContaine
.info("Undertow started on port(s) " + getPortsDescription());
}
catch (Exception ex) {
if (findBindException(ex) != null) {
List<Port> failedPorts = getConfiguredPorts();
List<Port> actualPorts = getActualPorts();
failedPorts.removeAll(actualPorts);
if (failedPorts.size() == 1) {
throw new PortInUseException(
failedPorts.iterator().next().getNumber());
try {
if (findBindException(ex) != null) {
List<Port> failedPorts = getConfiguredPorts();
List<Port> 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) {

View File

@ -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();
}
}