Skip to content

Commit 75034c3

Browse files
committed
Revert "Update websocket support for Jetty 9.3+"
This reverts commit 305cea2.
1 parent 305cea2 commit 75034c3

File tree

3 files changed

+53
-184
lines changed

3 files changed

+53
-184
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ configure(allprojects) { project ->
5555
ext.jackson2Version = "2.8.4"
5656
ext.jasperreportsVersion = "6.2.1" // our tests fail with JR-internal NPEs against 6.2.2 and higher
5757
ext.javamailVersion = "1.5.6"
58-
ext.jettyVersion = "9.4.0.RC3"
58+
ext.jettyVersion = "9.3.13.v20161014"
5959
ext.jodaVersion = "2.9.6"
6060
ext.jrubyVersion = "1.7.26" // JRuby 9000 only supported through JSR-223 (StandardScriptFactory)
6161
ext.jtaVersion = "1.2"

spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketSession.java

Lines changed: 4 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.web.socket.adapter.jetty;
1818

1919
import java.io.IOException;
20-
import java.lang.reflect.Method;
2120
import java.net.InetSocketAddress;
2221
import java.net.URI;
2322
import java.security.Principal;
@@ -27,14 +26,11 @@
2726

2827
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
2928
import org.eclipse.jetty.websocket.api.Session;
30-
import org.eclipse.jetty.websocket.api.UpgradeRequest;
31-
import org.eclipse.jetty.websocket.api.UpgradeResponse;
3229
import org.eclipse.jetty.websocket.api.WebSocketException;
3330
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
3431

3532
import org.springframework.http.HttpHeaders;
3633
import org.springframework.util.ObjectUtils;
37-
import org.springframework.util.ReflectionUtils;
3834
import org.springframework.web.socket.BinaryMessage;
3935
import org.springframework.web.socket.CloseStatus;
4036
import org.springframework.web.socket.PingMessage;
@@ -49,22 +45,10 @@
4945
*
5046
* @author Phillip Webb
5147
* @author Rossen Stoyanchev
52-
* @author Brian Clozel
5348
* @since 4.0
5449
*/
5550
public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
5651

57-
// As of Jetty 9.4, UpgradeRequest and UpgradeResponse are interfaces instead of classes
58-
private static final boolean isJetty94;
59-
60-
private static Method getUpgradeRequest;
61-
private static Method getUpgradeResponse;
62-
private static Method getRequestURI;
63-
private static Method getHeaders;
64-
private static Method getAcceptedSubProtocol;
65-
private static Method getExtensions;
66-
private static Method getUserPrincipal;
67-
6852
private String id;
6953

7054
private URI uri;
@@ -77,23 +61,6 @@ public class JettyWebSocketSession extends AbstractWebSocketSession<Session> {
7761

7862
private Principal user;
7963

80-
static {
81-
isJetty94 = UpgradeRequest.class.isInterface();
82-
if (!isJetty94) {
83-
try {
84-
getUpgradeRequest = Session.class.getMethod("getUpgradeRequest");
85-
getUpgradeResponse = Session.class.getMethod("getUpgradeResponse");
86-
getRequestURI = UpgradeRequest.class.getMethod("getRequestURI");
87-
getHeaders = UpgradeRequest.class.getMethod("getHeaders");
88-
getAcceptedSubProtocol = UpgradeResponse.class.getMethod("getAcceptedSubProtocol");
89-
getExtensions = UpgradeResponse.class.getMethod("getExtensions");
90-
getUserPrincipal = UpgradeRequest.class.getMethod("getUserPrincipal");
91-
}
92-
catch (NoSuchMethodException ex) {
93-
throw new IllegalStateException("Incompatible Jetty API", ex);
94-
}
95-
}
96-
}
9764

9865
/**
9966
* Create a new {@link JettyWebSocketSession} instance.
@@ -197,64 +164,20 @@ public boolean isOpen() {
197164
@Override
198165
public void initializeNativeSession(Session session) {
199166
super.initializeNativeSession(session);
200-
if (isJetty94) {
201-
initializeJetty94Session(session);
202-
}
203-
else {
204-
initializeJettySession(session);
205-
}
206-
}
207-
208-
@SuppressWarnings("unchecked")
209-
private void initializeJettySession(Session session) {
210-
211-
Object request = ReflectionUtils.invokeMethod(getUpgradeRequest, session);
212-
Object response = ReflectionUtils.invokeMethod(getUpgradeResponse, session);
213167

214-
this.id = ObjectUtils.getIdentityHexString(getNativeSession());
215-
this.uri = (URI) ReflectionUtils.invokeMethod(getRequestURI, request);
216-
217-
this.headers = new HttpHeaders();
218-
this.headers.putAll((Map<String, List<String>>) ReflectionUtils.invokeMethod(getHeaders, request));
219-
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
220-
221-
this.acceptedProtocol = (String) ReflectionUtils.invokeMethod(getAcceptedSubProtocol, response);
222-
223-
List<ExtensionConfig> source = (List<ExtensionConfig>) ReflectionUtils.invokeMethod(getExtensions, response);
224-
if (source != null) {
225-
this.extensions = new ArrayList<WebSocketExtension>(source.size());
226-
for (ExtensionConfig ec : source) {
227-
this.extensions.add(new WebSocketExtension(ec.getName(), ec.getParameters()));
228-
}
229-
}
230-
else {
231-
this.extensions = new ArrayList<WebSocketExtension>(0);
232-
}
233-
234-
if (this.user == null) {
235-
this.user = (Principal) ReflectionUtils.invokeMethod(getUserPrincipal, request);
236-
}
237-
}
238-
239-
private void initializeJetty94Session(Session session) {
240168
this.id = ObjectUtils.getIdentityHexString(getNativeSession());
241169
this.uri = session.getUpgradeRequest().getRequestURI();
242170

243171
this.headers = new HttpHeaders();
244-
this.headers.putAll(session.getUpgradeRequest().getHeaders());
172+
this.headers.putAll(getNativeSession().getUpgradeRequest().getHeaders());
245173
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
246174

247175
this.acceptedProtocol = session.getUpgradeResponse().getAcceptedSubProtocol();
248176

249177
List<ExtensionConfig> source = getNativeSession().getUpgradeResponse().getExtensions();
250-
if (source != null) {
251-
this.extensions = new ArrayList<WebSocketExtension>(source.size());
252-
for (ExtensionConfig ec : source) {
253-
this.extensions.add(new WebSocketExtension(ec.getName(), ec.getParameters()));
254-
}
255-
}
256-
else {
257-
this.extensions = new ArrayList<WebSocketExtension>(0);
178+
this.extensions = new ArrayList<WebSocketExtension>(source.size());
179+
for (ExtensionConfig ec : source) {
180+
this.extensions.add(new WebSocketExtension(ec.getName(), ec.getParameters()));
258181
}
259182

260183
if (this.user == null) {

spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java

Lines changed: 48 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.web.socket.server.jetty;
1818

1919
import java.io.IOException;
20+
import java.lang.reflect.Method;
2021
import java.security.Principal;
2122
import java.util.ArrayList;
2223
import java.util.List;
@@ -26,7 +27,8 @@
2627
import javax.servlet.http.HttpServletRequest;
2728
import javax.servlet.http.HttpServletResponse;
2829

29-
import org.eclipse.jetty.util.DecoratedObjectFactory;
30+
import org.eclipse.jetty.websocket.api.UpgradeRequest;
31+
import org.eclipse.jetty.websocket.api.UpgradeResponse;
3032
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
3133
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
3234
import org.eclipse.jetty.websocket.server.HandshakeRFC6455;
@@ -54,54 +56,69 @@
5456
import org.springframework.web.socket.server.RequestUpgradeStrategy;
5557

5658
/**
57-
* A {@link RequestUpgradeStrategy} for use with Jetty 9.1-9.3. Based on Jetty's
59+
* A {@link RequestUpgradeStrategy} for use with Jetty 9.0-9.3. Based on Jetty's
5860
* internal {@code org.eclipse.jetty.websocket.server.WebSocketHandler} class.
5961
*
6062
* @author Phillip Webb
6163
* @author Rossen Stoyanchev
62-
* @author Brian Clozel
6364
* @since 4.0
6465
*/
6566
public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Lifecycle, ServletContextAware {
6667

68+
// Pre-Jetty 9.3 init method without ServletContext
69+
private static final Method webSocketFactoryInitMethod =
70+
ClassUtils.getMethodIfAvailable(WebSocketServerFactory.class, "init");
71+
6772
private static final ThreadLocal<WebSocketHandlerContainer> wsContainerHolder =
6873
new NamedThreadLocal<WebSocketHandlerContainer>("WebSocket Handler Container");
6974

70-
// Actually 9.3.15+
71-
private static boolean isJetty94 = ClassUtils.hasConstructor(WebSocketServerFactory.class, ServletContext.class);
72-
73-
private static boolean isJetty91 = ClassUtils.hasMethod(WebSocketServerFactory.class, "init");
7475

75-
private WebSocketServerFactoryAdapter factoryAdapter;
76+
private final WebSocketServerFactory factory;
7677

7778
private volatile List<WebSocketExtension> supportedExtensions;
7879

79-
protected ServletContext servletContext;
80+
private ServletContext servletContext;
8081

8182
private volatile boolean running = false;
8283

84+
8385
/**
8486
* Default constructor that creates {@link WebSocketServerFactory} through
8587
* its default constructor thus using a default {@link WebSocketPolicy}.
8688
*/
8789
public JettyRequestUpgradeStrategy() {
88-
this(WebSocketPolicy.newServerPolicy());
90+
this(new WebSocketServerFactory());
8991
}
9092

9193
/**
92-
* A constructor accepting a {@link WebSocketPolicy}
93-
* to be used when creating the {@link WebSocketServerFactory} instance.
94-
* @since 4.3
94+
* A constructor accepting a {@link WebSocketServerFactory}.
95+
* This may be useful for modifying the factory's {@link WebSocketPolicy}
96+
* via {@link WebSocketServerFactory#getPolicy()}.
9597
*/
96-
public JettyRequestUpgradeStrategy(WebSocketPolicy webSocketPolicy) {
97-
this.factoryAdapter = isJetty94 ? new Jetty94WebSocketServerFactoryAdapter()
98-
: new JettyWebSocketServerFactoryAdapter();
99-
this.factoryAdapter.setWebSocketPolicy(webSocketPolicy);
98+
public JettyRequestUpgradeStrategy(WebSocketServerFactory factory) {
99+
Assert.notNull(factory, "WebSocketServerFactory must not be null");
100+
this.factory = factory;
101+
this.factory.setCreator(new WebSocketCreator() {
102+
@Override
103+
public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response) {
104+
// Cast to avoid infinite recursion
105+
return createWebSocket((UpgradeRequest) request, (UpgradeResponse) response);
106+
}
107+
// For Jetty 9.0.x
108+
public Object createWebSocket(UpgradeRequest request, UpgradeResponse response) {
109+
WebSocketHandlerContainer container = wsContainerHolder.get();
110+
Assert.state(container != null, "Expected WebSocketHandlerContainer");
111+
response.setAcceptedSubProtocol(container.getSelectedProtocol());
112+
response.setExtensions(container.getExtensionConfigs());
113+
return container.getHandler();
114+
}
115+
});
100116
}
101117

118+
102119
@Override
103120
public String[] getSupportedVersions() {
104-
return new String[] {String.valueOf(HandshakeRFC6455.VERSION)};
121+
return new String[] { String.valueOf(HandshakeRFC6455.VERSION) };
105122
}
106123

107124
@Override
@@ -114,7 +131,7 @@ public List<WebSocketExtension> getSupportedExtensions(ServerHttpRequest request
114131

115132
private List<WebSocketExtension> getWebSocketExtensions() {
116133
List<WebSocketExtension> result = new ArrayList<WebSocketExtension>();
117-
for (String name : this.factoryAdapter.getFactory().getExtensionFactory().getExtensionNames()) {
134+
for (String name : this.factory.getExtensionFactory().getExtensionNames()) {
118135
result.add(new WebSocketExtension(name));
119136
}
120137
return result;
@@ -136,24 +153,24 @@ public void start() {
136153
if (!isRunning()) {
137154
this.running = true;
138155
try {
139-
this.factoryAdapter.start();
156+
if (webSocketFactoryInitMethod != null) {
157+
webSocketFactoryInitMethod.invoke(this.factory);
158+
}
159+
else {
160+
this.factory.init(this.servletContext);
161+
}
140162
}
141163
catch (Exception ex) {
142-
throw new IllegalStateException("Unable to start Jetty WebSocketServerFactory", ex);
164+
throw new IllegalStateException("Unable to initialize Jetty WebSocketServerFactory", ex);
143165
}
144166
}
145167
}
146168

147169
@Override
148170
public void stop() {
149171
if (isRunning()) {
150-
try {
151-
this.running = false;
152-
factoryAdapter.stop();
153-
}
154-
catch (Exception ex) {
155-
throw new IllegalStateException("Unable to stop Jetty WebSocketServerFactory", ex);
156-
}
172+
this.running = false;
173+
this.factory.cleanup();
157174
}
158175
}
159176

@@ -168,8 +185,7 @@ public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
168185
Assert.isInstanceOf(ServletServerHttpResponse.class, response);
169186
HttpServletResponse servletResponse = ((ServletServerHttpResponse) response).getServletResponse();
170187

171-
Assert.isTrue(this.factoryAdapter.getFactory()
172-
.isUpgradeRequest(servletRequest, servletResponse), "Not a WebSocket handshake");
188+
Assert.isTrue(this.factory.isUpgradeRequest(servletRequest, servletResponse), "Not a WebSocket handshake");
173189

174190
JettyWebSocketSession session = new JettyWebSocketSession(attributes, user);
175191
JettyWebSocketHandlerAdapter handlerAdapter = new JettyWebSocketHandlerAdapter(wsHandler, session);
@@ -179,7 +195,7 @@ public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
179195

180196
try {
181197
wsContainerHolder.set(container);
182-
this.factoryAdapter.getFactory().acceptWebSocket(servletRequest, servletResponse);
198+
this.factory.acceptWebSocket(servletRequest, servletResponse);
183199
}
184200
catch (IOException ex) {
185201
throw new HandshakeFailureException(
@@ -203,7 +219,7 @@ public WebSocketHandlerContainer(JettyWebSocketHandlerAdapter handler, String pr
203219
this.handler = handler;
204220
this.selectedProtocol = protocol;
205221
if (CollectionUtils.isEmpty(extensions)) {
206-
this.extensionConfigs = new ArrayList<ExtensionConfig>();
222+
this.extensionConfigs = null;
207223
}
208224
else {
209225
this.extensionConfigs = new ArrayList<ExtensionConfig>();
@@ -226,74 +242,4 @@ public List<ExtensionConfig> getExtensionConfigs() {
226242
}
227243
}
228244

229-
private static abstract class WebSocketServerFactoryAdapter {
230-
231-
protected WebSocketServerFactory factory;
232-
233-
protected WebSocketPolicy webSocketPolicy;
234-
235-
public WebSocketServerFactory getFactory() {
236-
return factory;
237-
}
238-
239-
public void setWebSocketPolicy(WebSocketPolicy webSocketPolicy) {
240-
this.webSocketPolicy = webSocketPolicy;
241-
}
242-
243-
protected void configureFactory() {
244-
this.factory.setCreator(new WebSocketCreator() {
245-
@Override
246-
public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response) {
247-
WebSocketHandlerContainer container = wsContainerHolder.get();
248-
Assert.state(container != null, "Expected WebSocketHandlerContainer");
249-
response.setAcceptedSubProtocol(container.getSelectedProtocol());
250-
response.setExtensions(container.getExtensionConfigs());
251-
return container.getHandler();
252-
}
253-
});
254-
}
255-
256-
abstract void start() throws Exception;
257-
258-
abstract void stop() throws Exception;
259-
}
260-
261-
private class JettyWebSocketServerFactoryAdapter extends WebSocketServerFactoryAdapter {
262-
263-
@Override
264-
void start() throws Exception {
265-
this.factory = WebSocketServerFactory.class.getConstructor(WebSocketPolicy.class)
266-
.newInstance(this.webSocketPolicy);
267-
configureFactory();
268-
if(isJetty91) {
269-
WebSocketServerFactory.class.getMethod("init").invoke(this.factory);
270-
}
271-
else {
272-
WebSocketServerFactory.class.getMethod("init", ServletContext.class)
273-
.invoke(this.factory, servletContext);
274-
}
275-
}
276-
277-
@Override
278-
void stop() throws Exception {
279-
WebSocketServerFactory.class.getMethod("cleanup").invoke(this.factory);
280-
}
281-
}
282-
283-
private class Jetty94WebSocketServerFactoryAdapter extends WebSocketServerFactoryAdapter {
284-
285-
@Override
286-
void start() throws Exception {
287-
servletContext.setAttribute(DecoratedObjectFactory.ATTR, new DecoratedObjectFactory());
288-
this.factory = new WebSocketServerFactory(servletContext, this.webSocketPolicy);
289-
configureFactory();
290-
this.factory.start();
291-
}
292-
293-
@Override
294-
void stop() throws Exception {
295-
this.factory.stop();
296-
}
297-
}
298-
299245
}

0 commit comments

Comments
 (0)