From 2fe08194950356f247107a256da91a3560b80fa3 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 17 Nov 2015 18:04:22 +0000 Subject: [PATCH] Isolate multiple Undertow deployments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, UndertowEmbeddedServletContainerFactory always used Undertow’s default ServletContainer. This meant that if there were two UndertowEmbeddedServletContainers created, they would share the same ServletContainer and the second one that was created would overwrite the deployment for the first. This resulted in a async request handling failing as the attempt to look up the deployment for the first embedded Undertow instance would incorrectly find the deployment for the second. This commit fixes the problem by ensuring that each UndertowEmbeddedServletContainerFactory uses a separate Undertow ServletContainer instance. Closes gh-4329 --- .../UndertowEmbeddedServletContainerFactory.java | 2 +- ...rtowEmbeddedServletContainerFactoryTests.java | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java index b04b9d22f2f..e966b2f8732 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java @@ -336,7 +336,7 @@ public class UndertowEmbeddedServletContainerFactory for (UndertowDeploymentInfoCustomizer customizer : this.deploymentInfoCustomizers) { customizer.customize(deployment); } - DeploymentManager manager = Servlets.defaultContainer().addDeployment(deployment); + DeploymentManager manager = Servlets.newContainer().addDeployment(deployment); manager.deploy(); SessionManager sessionManager = manager.getDeployment().getSessionManager(); int sessionTimeout = (getSessionTimeout() > 0 ? getSessionTimeout() : -1); 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 17b68cbad72..47082ff969d 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 @@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicReference; import io.undertow.Undertow.Builder; import io.undertow.servlet.api.DeploymentInfo; import io.undertow.servlet.api.DeploymentManager; +import io.undertow.servlet.api.ServletContainer; import org.junit.Test; import org.mockito.InOrder; @@ -39,6 +40,8 @@ import org.springframework.http.HttpStatus; import org.springframework.test.util.ReflectionTestUtils; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.anyObject; @@ -156,6 +159,19 @@ public class UndertowEmbeddedServletContainerFactoryTests assertEquals("/", contextPath.get()); } + @Test + public void eachFactoryUsesADiscreteServletContainer() { + assertThat(getServletContainerFromNewFactory(), + is(not(equalTo(getServletContainerFromNewFactory())))); + } + + private ServletContainer getServletContainerFromNewFactory() { + UndertowEmbeddedServletContainer undertow1 = (UndertowEmbeddedServletContainer) getFactory() + .getEmbeddedServletContainer(); + return ((DeploymentManager) ReflectionTestUtils.getField(undertow1, "manager")) + .getDeployment().getServletContainer(); + } + @Override protected Map getActualMimeMappings() { return ((DeploymentManager) ReflectionTestUtils.getField(this.container,