diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java index 41427095e75..3332d46d144 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/socket/server/upgrade/JettyRequestUpgradeStrategy.java @@ -37,11 +37,11 @@ import org.springframework.web.reactive.socket.adapter.JettyWebSocketHandlerAdap import org.springframework.web.reactive.socket.server.RequestUpgradeStrategy; import org.springframework.web.server.ServerWebExchange; - /** * A {@link RequestUpgradeStrategy} for use with Jetty. * * @author Violeta Georgieva + * @author Rossen Stoyanchev * @since 5.0 */ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Lifecycle { @@ -54,7 +54,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life private ServletContext servletContext; - private boolean running = false; + private volatile boolean running = false; private final Object lifecycleMonitor = new Object(); @@ -69,7 +69,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life this.factory.setCreator((request, response) -> adapterHolder.get()); this.factory.start(); } - catch (Exception ex) { + catch (Throwable ex) { throw new IllegalStateException("Unable to start WebSocketServerFactory", ex); } } @@ -80,29 +80,25 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life public void stop() { synchronized (this.lifecycleMonitor) { if (isRunning()) { + this.running = false; try { this.factory.stop(); } - catch (Exception ex) { + catch (Throwable ex) { throw new IllegalStateException("Failed to stop WebSocketServerFactory", ex); } - finally { - this.running = false; - } } } } @Override public boolean isRunning() { - synchronized (this.lifecycleMonitor) { - return this.running; - } + return this.running; } + @Override public Mono upgrade(ServerWebExchange exchange, WebSocketHandler handler) { - ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); JettyWebSocketHandlerAdapter adapter = new JettyWebSocketHandlerAdapter(request, response, handler); @@ -146,7 +142,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life synchronized (this.lifecycleMonitor) { if (this.servletContext == null) { this.servletContext = request.getServletContext(); - this.servletContext.setAttribute(DecoratedObjectFactory.ATTR, new DecoratedObjectFactory()); + this.servletContext.setAttribute(DecoratedObjectFactory.ATTR, new DecoratedObjectFactory()); start(); } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java index bae6c82712b..0e9a7aefa98 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java @@ -65,9 +65,12 @@ import org.springframework.web.socket.server.RequestUpgradeStrategy; */ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, ServletContextAware, Lifecycle { - private static final ThreadLocal wsContainerHolder = - new NamedThreadLocal<>("WebSocket Handler Container"); + private static final ThreadLocal containerHolder = + new NamedThreadLocal<>("WebSocketHandlerContainer"); + + // Configurable factory adapter due to Jetty 9.3.15+ API differences: + // using WebSocketServerFactory(ServletContext) as a version indicator private final WebSocketServerFactoryAdapter factoryAdapter = (ClassUtils.hasConstructor(WebSocketServerFactory.class, ServletContext.class) ? new ModernJettyWebSocketServerFactoryAdapter() : new LegacyJettyWebSocketServerFactoryAdapter()); @@ -129,8 +132,8 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv @Override public void stop() { if (isRunning()) { + this.running = false; try { - this.running = false; this.factoryAdapter.stop(); } catch (Throwable ex) { @@ -187,7 +190,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv new WebSocketHandlerContainer(handlerAdapter, selectedProtocol, selectedExtensions); try { - wsContainerHolder.set(container); + containerHolder.set(container); this.factoryAdapter.getFactory().acceptWebSocket(servletRequest, servletResponse); } catch (IOException ex) { @@ -195,7 +198,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv "Response update failed during upgrade to WebSocket: " + request.getURI(), ex); } finally { - wsContainerHolder.remove(); + containerHolder.remove(); } } @@ -263,7 +266,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv this.factory.setCreator(new WebSocketCreator() { @Override public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response) { - WebSocketHandlerContainer container = wsContainerHolder.get(); + WebSocketHandlerContainer container = containerHolder.get(); Assert.state(container != null, "Expected WebSocketHandlerContainer"); response.setAcceptedSubProtocol(container.getSelectedProtocol()); response.setExtensions(container.getExtensionConfigs());