Skip to content

SpringBootTest with MockMvc and WebSocketHandlers work with Tomcat and Undertow but not with Jetty #7487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
isopov opened this issue Nov 25, 2016 · 15 comments
Assignees
Labels
status: invalid An issue that we don't feel is valid

Comments

@isopov
Copy link
Contributor

isopov commented Nov 25, 2016

Test projects may be found here: https://github.com/isopov/mockmvc-test-websocket

Basically it is simple "hello world" application with "do nothing" WebSocketHandler and MockMvc-based SpringBootTest to test "hello world" endpoint. This test passes successfully with Tomcat and Undertow in the classpath, but not with Jetty.

Full stacktrace is:

java.lang.IllegalStateException: Failed to load ApplicationContext
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) ~[spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83) ~[spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189) ~[spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131) ~[spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230) ~[spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228) [spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287) [spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289) [spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247) [spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) [spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) [spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) [.cp/:na]
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na]
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) [.cp/:na]
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na]
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na]
Caused by: org.springframework.context.ApplicationContextException: Failed to start bean 'webSocketHandlerMapping'; nested exception is java.lang.IllegalStateException: Unable to initialize Jetty WebSocketServerFactory
	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:176) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:112) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:879) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
	at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:111) ~[spring-boot-test-1.4.2.RELEASE.jar:1.4.2.RELEASE]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) ~[spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) ~[spring-test-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	... 25 common frames omitted
Caused by: java.lang.IllegalStateException: Unable to initialize Jetty WebSocketServerFactory
	at org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy.start(JettyRequestUpgradeStrategy.java:164) ~[spring-websocket-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.web.socket.server.support.AbstractHandshakeHandler.doStart(AbstractHandshakeHandler.java:204) ~[spring-websocket-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.web.socket.server.support.AbstractHandshakeHandler.start(AbstractHandshakeHandler.java:198) ~[spring-websocket-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.web.socket.server.support.WebSocketHttpRequestHandler.start(WebSocketHttpRequestHandler.java:132) ~[spring-websocket-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.web.socket.server.support.WebSocketHandlerMapping.start(WebSocketHandlerMapping.java:65) ~[spring-websocket-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	... 37 common frames omitted
Caused by: javax.servlet.ServletException: Not running on Jetty, WebSocket support unavailable
	at org.eclipse.jetty.websocket.server.WebSocketServerFactory.init(WebSocketServerFactory.java:393) ~[websocket-server-9.3.14.v20161028.jar:9.3.14.v20161028]
	at org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy.start(JettyRequestUpgradeStrategy.java:160) ~[spring-websocket-4.3.4.RELEASE.jar:4.3.4.RELEASE]
	... 42 common frames omitted
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 25, 2016
@wilkinsona wilkinsona self-assigned this Nov 28, 2016
@wilkinsona
Copy link
Member

There's no standardised API for performing a WebSocket upgrade so Spring Framework has a strategy interface, RequestUpgradeStrategy, and a number of container-specific implementations. The Jetty implementation requires Jetty to be running. I don't think there's anything we can do about that in Spring Boot as it's simply due to the way that Jetty's been implemented.

@SpringBootTest indicates that you are integration testing your entire application so it would not be appropriate for Spring Boot to ignore @EnableWebSocket. You could use @SpringBootTest with webEnvironment=RANDOM_PORT and use TestRestTemplate rather than MockMvc. If you want to continue using MockMvc, then I think you'd probably be better restructuring things a little so that @EnableWebSocket only comes into effect when you're running your app or a full-blown integration test that actually starts the embedded container.

One final point to note is that this test will reproduce the problem without any involvement from Spring Boot:

public class MockServletContextJettyWebSocketTests {

    @Test
    public void test() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setServletContext(new MockServletContext());
        context.register(ExampleConfiguration.class);
        context.refresh();
    }

    @Configuration
    @EnableWebSocket
    static class ExampleConfiguration implements WebSocketConfigurer {

        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
            registry.addHandler(webSocketHandler(), "/ws");
        }

        @Bean
        public WebSocketHandler webSocketHandler() {
            return new TextWebSocketHandler();
        }

    }
    
}

If you'd like to pursue your current arrangement working with Jetty then please open a Spring Framework JIRA ticket.

@wilkinsona wilkinsona added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 28, 2016
@jmc420
Copy link

jmc420 commented Mar 22, 2018

I have been struggling to get integration tests working with jetty and websockets and came across this issue.

I checked out https://github.com/isopov/mockmvc-test-websocket and it does not work with jetty.

It seems to be related to https://jira.spring.io/browse/SPR-16263

Within the init method of WebSocketServerFactory, this exception is thrown

ContextHandler handler = ContextHandler.getContextHandler(context);

if (handler == null)
{
throw new ServletException("Not running on Jetty, WebSocket support unavailable");
}

According to the jira, it appears this is because Spring's MockServletContext doesn't implement Jetty's ContextHandler.Context; i.e. ContextHandler.getContextHandler(context); returns null.

is there anyway to get websocket integration tests (with or without spring boot) to work jetty?

@wilkinsona
Copy link
Member

Is there anyway to get websocket integration tests (with or without spring boot) to work jetty?

Yes, I believe you can integration test WebSockets with Jetty by starting Jetty rather than trying to use MockMvc. If you need some help with that, please ask on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

@jmc420
Copy link

jmc420 commented Mar 23, 2018

@joakime
Copy link

joakime commented Mar 23, 2018

@jmc420 start a real jetty server for your websocket testing. It starts faster then the Spring MockMVC anyway. (in our testing we can start a real server, toss a dozen messages with echo at the websocket, and shutdown the server in under 150ms)

As for ...

ContextHandler handler = ContextHandler.getContextHandler(context);

if (handler == null)
{
throw new ServletException("Not running on Jetty, WebSocket support unavailable");
}

That's from the WebSocketUpgradeFilter (Not the WebSocketServerFactory).

In WebSocket on Jetty there are 2 such checks ...

org/eclipse/jetty/websocket/server/WebSocketUpgradeFilter.java

org/eclipse/jetty/websocket/jsr356/server/deploy/WebSocketServerContainerInitializer.java

The internal use of the Jetty ContextHandler and ServletContextHandler exist to manage the Jetty object LifeCycle and allow reuse of other expensive LifeCycle components (such as the ThreadPool, Executor, and HttpClient)

I'd be open to making Jetty (perhaps Jetty 9.4.10, definitely Jetty 10.x) a bit more flexible here to allow MockMVC.

What's the requirements from the MockMVC point of view?

@jmc420
Copy link

jmc420 commented Mar 23, 2018

@joakime Thanks for the reply.

I would see if you can get it working with the (unit) test in the example repo above:

https://github.com/isopov/mockmvc-test-websocket/blob/master/mockmvc-test-websocket-jetty/src/test/java/com/example/MockmvcTestWebsocketJettyApplicationTests.java

As I mentioned in the stackoverflow post, I am running a Jetty integration (rather than unit) test using these annotations:

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( classes = { ApplicationConfig.class } )
@WebAppConfiguration

When I run this without a WebSocket configuration picked up by component scanning, everything works fine, but when I introduce a WebSocket configuration it fails because of which is the exception (throw new ServletException("Not running on Jetty, WebSocket support unavailable");)

I am running Jetty 9.3 which is why it appears for me in WebSocketServerFactory rather than WebSocketUpgradeFilter.

@joakime
Copy link

joakime commented Mar 28, 2018

Looking at this ...

Why does JettyRequestUpgradeStrategy exist this way?
Why is the ServletContext arriving late? and via a .setServletContext call, and not as part of the constructor?
Using Jetty's WebSocketHandler as your example to base JettyRequestUpgradeStrategy against is super strange.
Of the various ways to implement a websocket server on Jetty, someone chose to use the one and only way that doesn't have/use a standard javax.servlet.ServletContext to begin with.
Does this MockMVC layer perform any javax.servlet.ServletContainerInitializer behaviors? (doesn't appear to)

Hmm, lots of strange decisions here.
I'll have to work out why first, then see if I can replace all of this with just a simple SCI usage. (it would be backward compatible to Jetty 9.0 too!)

@wilkinsona
Copy link
Member

Those are interesting questions, but they're question for the Spring Framework team. The code in question is not part of Spring Boot.

/cc @rstoyanchev

@joakime
Copy link

joakime commented Mar 28, 2018

I've made some minor changes to WebSocketServerFactory to allow MockMVC to function.

Jetty Branch: https://github.com/eclipse/jetty.project/tree/jetty-9.4.x-issue-2376-ws-context-relaxation
Mockmvc-test-websocket fork: https://github.com/joakime/mockmvc-test-websocket

Let me know if this is sufficient (for now), or of anything else is needed?

Aside: I think the Jetty implementation for upgrade at Spring Framework needs an overhaul to be more resilient.
Using the WebSocketServerFactory directly like it's doing is probably the most complex approach that could have been taken.

@joakime
Copy link

joakime commented Mar 28, 2018

Note: I had to upgrade to version 2.0.0 in my fork.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.0.RELEASE)

2018-03-28 13:37:29.618  INFO 10332 --- [           main] org.eclipse.jetty.util.log               : Logging initialized @1325ms to org.eclipse.jetty.util.log.Slf4jLog
2018-03-28 13:37:29.673  INFO 10332 --- [           main] ockmvcTestWebsocketJettyApplicationTests : Starting MockmvcTestWebsocketJettyApplicationTests on tethys with PID 10332 (started by joakim in C:\code\jetty\stackoverflow\mockmvc-test-websocket\mockmvc-test-websocket-jetty)
2018-03-28 13:37:29.674  INFO 10332 --- [           main] ockmvcTestWebsocketJettyApplicationTests : No active profile set, falling back to default profiles: default
2018-03-28 13:37:29.726  INFO 10332 --- [           main] o.s.w.c.s.GenericWebApplicationContext   : Refreshing org.springframework.web.context.support.GenericWebApplicationContext@20140db9: startup date [Wed Mar 28 13:37:29 CDT 2018]; root of context hierarchy
2018-03-28 13:37:30.605  INFO 10332 --- [           main] o.s.w.s.s.s.WebSocketHandlerMapping      : Mapped URL path [/ws] onto handler of type [class org.springframework.web.socket.server.support.WebSocketHttpRequestHandler]
2018-03-28 13:37:30.789  INFO 10332 --- [           main] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring FrameworkServlet ''
2018-03-28 13:37:30.790  INFO 10332 --- [           main] o.s.t.web.servlet.TestDispatcherServlet  : FrameworkServlet '': initialization started
2018-03-28 13:37:30.905  INFO 10332 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/],methods=[GET]}" onto public java.lang.String com.example.MockmvcTestWebsocketJettyApplication.hello()
2018-03-28 13:37:30.910  INFO 10332 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-03-28 13:37:30.911  INFO 10332 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-03-28 13:37:30.955  INFO 10332 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-03-28 13:37:30.955  INFO 10332 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-03-28 13:37:30.978  INFO 10332 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-03-28 13:37:31.163  INFO 10332 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext@20140db9: startup date [Wed Mar 28 13:37:29 CDT 2018]; root of context hierarchy
2018-03-28 13:37:31.261  INFO 10332 --- [           main] o.s.t.web.servlet.TestDispatcherServlet  : FrameworkServlet '': initialization completed in 471 ms
2018-03-28 13:37:31.589  INFO 10332 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 2147483647
2018-03-28 13:37:31.616  INFO 10332 --- [           main] o.e.j.w.server.WebSocketServerFactory    : No DecoratedObjectFactory provided, using new org.eclipse.jetty.util.DecoratedObjectFactory[decorators=1]
2018-03-28 13:37:31.641  INFO 10332 --- [           main] o.e.j.w.server.WebSocketServerFactory    : No Executor provided, using new QueuedThreadPool[WebSocketServerFactory]@6a969fb8{STARTED,8<=8<=200,i=4,q=0}
2018-03-28 13:37:31.651  INFO 10332 --- [           main] ockmvcTestWebsocketJettyApplicationTests : Started MockmvcTestWebsocketJettyApplicationTests in 2.379 seconds (JVM running for 3.36)
2018-03-28 13:37:31.804  INFO 10332 --- [      Thread-11] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@20140db9: startup date [Wed Mar 28 13:37:29 CDT 2018]; root of context hierarchy
2018-03-28 13:37:31.806  INFO 10332 --- [      Thread-11] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 2147483647

The two key lines ...

No DecoratedObjectFactory provided, using new org.eclipse.jetty.util.DecoratedObjectFactory[decorators=1]
No Executor provided, using new QueuedThreadPool[WebSocketServerFactory]@6a969fb8{STARTED,8<=8<=200,i=4,q=0}

If those concepts are not provided, or found in the context hierarchy, or found via the server reference, then they are created locally.

@rstoyanchev
Copy link
Contributor

rstoyanchev commented Mar 28, 2018

I have been struggling to get integration tests working with jetty and websockets

@jmc420, judging from your comments here and on SO, I think there is a misunderstanding. Can you clarify which do you want? To test WebSocket endpoints with MockMvc, or to test regular HTTP endpoints with MockMvc but can't load your Spring config because of failures related to WebSocket initialization?

Spring MVC Test uses mock Servlet API objects and for such tests there is no running Servlet container. It exists mainly to help with testing controllers (for which plain unit tests are useless) taking into account annotations and Spring configuration. To test WebSockets you need a running server. Or if you're using annotated controllers with STOMP over WebSocket, you can see this here.

The referenced sample test is actually targetting a regular controller method. It succeeds on Tomcat and Undertow because WebSocket initialization does not fail, not because WebSockets are used in the test.

In SPR-16263 the goal is also not to test WebSockets but to load Spring configuration in a test environment, and that configuration includes WebSocket endpoints. I think the answer there would be to separate the WebSocket related configuration and avoid loading it during the test, or to use the Spring config profile feature to mark and exclude it in tests.

@joakime the purpose of RequestUpgradeStrategy is to allow WebSocket handshakes to be mapped within Spring MVC as any other HTTP request, and to decide whether to upgrade or not at runtime, rather than on startup. There is more on that in the docs, and I can answer follow-up questions, but there are cases where registering WebSocket endpoints on startup is not flexible enough.

JSR-356 did not provide such a mechanism, even though we requested it (the spec JIRA is now gone so I can no longer link). That request was up-voted but as you know there were never any real spec updates beyond the initial release.

Over time we did ask various servers to expose some API for this use case, and we got it from Tomcat, Undertow, and WebSphere. I don't recall any longer TBH if we did ask the Jetty team or not. It would be great to have such an API for performing a WebSocket upgrade at runtime explicitly supported in Jetty. Or perhaps there is an existing API I have misssed?

@joakime
Copy link

joakime commented Mar 28, 2018

@rstoyanchev the current location of the JSR-356 spec issues is https://github.com/eclipse-ee4j/websocket-api/issues btw.

Your documentation has a link to https://java.net/jira/browse/WEBSOCKET_SPEC-211
The new location is a 1::1 mapping of the spec number.
See: jakartaee/websocket#211

@rstoyanchev
Copy link
Contributor

Good to know about the new location, and I've updated the documentation to point to it.

@joakime
Copy link

joakime commented Mar 28, 2018

Linking back to jetty/jetty.project#2376 for historical/tracking reasons.

@jmc420
Copy link

jmc420 commented Mar 29, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

6 participants