jsr356-experts@websocket-spec.java.net

[jsr356-experts] Re: More more programmatic deployment

From: Mark Thomas <mark_at_homeinbox.net>
Date: Tue, 26 Feb 2013 05:59:27 -0800

On 25/02/2013 16:42, Danny Coward wrote:
> Hi folks,
>
> I took some time looking over the existing mechanism:
> ServerApplicationConfiguration, and over the older requirements (below)
> we had on this when we first reworked the deployment APIs before
> Christmas. Including our long exploration into the mysteries of the SCI :)
>
> I've also added the 'programmatic deployment' case we've been talking
> about lately (3) and requirement (4) that I think we agree on, both of
> which the old deploy() method used to satisfy (perhaps rather too
> generally!).
>
> So, looking at all our deployment scenarios including this 'programmatic
> one', here I think is the sum total of server deployment requirements:-
>
> 1) we want annotation deployment to be simple when its simple (e.g. pick
> up all the annotated endpoints in my WAR, no special config !)
> 2) we want to leverage the servlet scanning mechanism when its active
> (easier controlled deployment of annotated endpoints and programmatic
> endpoints)
> 3) we want to precisely control which endpoints get deployed when
> scanning is turned off (using the absolute ordering element in the
> web.xml).

Almost. I'd like to see a deployment mechanism that is entirely
independent of Servlet 3.1 pluggability features - i.e. one that can be
called from a ServletContextListener rather than requiring the use of an
SCI.

> 4) we want deployment to happen only at application initialization time

While I'm happy with this restriction at this point (it keeps things a
little simpler) there is clearly demand to be able to deploy at any
point in time. I'm wondering if this restriction is too limiting. There
is also the issue about using the server API in environments other than
Servlet containers. That, I think, strengthens the argument for a
solution that does not use the Servlet 3.1 pluggability features.

> I'll add my own: I'd like there to be just one mechanism for this version.

OK. I think I know why (keeping things simple) but could you articulate
your reasoning behind this requirement?

> The benefits of the ServerApplicationConfiguration callback are that
> automatically enforces the restriction in 4) since the container makes
> the callback (I believe this is clear in its definition, to Rossen's
> point). It also provides the developer the bootstrap into the container:
> there's no need to locate the *Container object to do the deployment. It
> fits well with the SCI scheme. Right now though it can only itself be
> picked up when a scan happens, so it cannot satisfy 3).
>
> To satisfy (3) I think all we need is two additions to augment the
> existing scheme:
>
> a) a way to pick up ServerApplicationConfiguration without a scan. I'd
> suggest using ServletContext init params which the implementation can
> pick up without any scan using a ServletContainerInitializer registered
> in the META-INF/services of the implementation (Mark, my understanding
> is that this addresses the scanning point you made?).

Not quite. See above.

> Rossen to your
> point, although not consistent with the Servlet API, it is with JAX-RS.
>
> b) call the methods
> ServerApplicationConfiguration.getEndpointConfigurations(), and
> ServerApplicationConfiguration.getEndpointConfigurations() with null
> when no scan is made so the ServerApplicationConfiguration can
> distinguish between the scanned (non-null Set) and non-scanned case (null).
>
> In contrast, to go the full programmatic route we'd need:-
>
> i) two new methods deploy methods on WebSocketContainer, pretty much as
> Mark laid out:
> public void deploy(Class<?> annotated) throws IllegalStateException (if
> called at the wrong time)
> public void deploy(Class<Endpoint> programmatic,
> ServerEndpointConfiguration sec) throws IllegalStateException (if called
> at the wrong time)

Implementations are going to have to have something that implements this
functionality one way or another. All this does is provide a standard
API to access it.

> ii) a refactoring to a server-side container ServerWebSocketContainer to
> house the server-side only deploy() methods

Again, implementations are going to have to have something like this anyway.

> iii) an new entry point to access to ServerWebSocketContainer at
> application deployment time, Mark had suggested the static
> ServerWebSocketContainer.getContainer() as a hook to the container, but
> the developer would still need some form of callback (with no scan for
> ServletContextListeners) to call it at the right time.

The developer can add a ServletContextListener in web.xml. The advantage
of this approach is that applications and frameworks will probably
already be using a ServletContextListener. This will continue to work
even when all Servlet 3.1 pluggability features have been turned off.

> iv) in addition to the the existing scan based APIs and spec.
>
> When I look at all the scenarios, evolving the API we have does seem a
> lot simpler...provided what I wrote works: i.e. that it addresses the
> concern about locating the ServerApplicationConfiguration without a scan.

To sum up:
ServerApplicationConfiguration + init param:
- Still needs a SCI to trigger it which depends on Servlet pluggability
   features
- Only works in a Servlet container
- Minimal changes to current API
- Not realy suited to future extension to support deployment at any time

100% programmatic
- No dependency on Servlet pluggability
- Can be used in non-Servlet container environments
- Requires additional API (but hopefully mainly just exposing what
   implementations already have internally)
- Easily extended to allow deployment at any time

My preference remains for the 100% programmatic approach.

Mark