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:
1. webcontainer.registerServlet()
2. Whiteboard registration of javax.servlet.Servlet service
3. an SCI may invoke servletContext.addServlet()
4. a ServletContextListener may invoke servletContext.addServlet()
5. 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