Hello
I'd like to share great news about Pax Web 8 state.
For last few days I was working on tiny, single test related to Whiteboard-registration of WebSockets...
Normally (WAR) websockets are registered by some ServletContainerInitializer based ONLY on the classes passed to SCI.onStartup() and scanned using (usually) the information like this:
@HandlesTypes({
ServerEndpoint.class,
ServerApplicationConfig.class,
Endpoint.class
})
WAR scenario in Pax Web 8 was easy - simply an existing SCI (or custom one for Undertow) was sufficient.
The problem was the dynamics of Whiteboard approach. What should happen when you simply "add a websocket"?
Pax Web 7, when registering a websocket was adding an SCI to be invoked at (re)start time of the target (Jetty, Tomcat, Undertow) context. So easy calculation - 10 websockets == 10 SCIs.
This fact made me think wider - how restarts and SCIs should be handled?
I got back to most trivial question - how many ways there are to register a servlet? In Pax Web case there are FIVE:
- webcontainer.registerServlet()
- Whiteboard registration of javax.servlet.Servlet service
- an SCI may invoke servletContext.addServlet()
- a ServletContextListener may invoke servletContext.addServlet()
- an Undertow extension may add additional servlets to DeploymentInfo
the same is for filters and listeners (except that a ServletContextListener can't register more ServletContextListeners)
So when we register and SCI that registers a websocket we want it to be run, right? so we effectively want to "restart a context". But (and that's what I was working on during last 3 days):
- we don't want to lose servlets/filters/listeners registered previously through Whiteboard/HttpService
- we want to lose the servlets/filters/listeners registered by SCIs and ServletContextListeners, because if we call them again, we don't want conflicts!
- we want to clear the context attributes that could've been set by SCIs/ServletContextListeners before, because that's how SCis "mark" the context as processed - leaving there some flags that prevents them from doing some tasks more than once
And finally I have a working scenario:
- an SCI is Whiteboard registered and calls sc.addFilter() in onStartup()
- a ServletContextListener is Whiteboard registered and calls sc.setAttribute() and sc.addServlet() in contextInitialized()
- a servlet is Whiteboard registered
- a filter is Whiteboard registered
- a WebSocket (1) is registered by instance
- a WebSocket (2) is registered by class
- a WebSocket (2) is unregistered
In between the registrations, GET requests are performed to check the expected behavior - and everything works consistently across all 3 container runtimes!
And yes - I added the possibility to register actual WebSocket instance - Pax Web 7, even if you've registered a @ServerEndpoint-annotated object as WebSocket, was simply taking its getClass() and was using this class (instantiated later by actual runtime).
And what's more - even if you register/unregister more WebSockets, single, dedicated SCI is used to (re)register all needed WebSockets!
I hope the actual
8.0.0.GA is finally coming.
kind regards
Grzegorz Grzybek