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).
4) we want deployment to happen only at application initialization time
I'll add my own: I'd like there to be just one mechanism for this version.
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?). 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)
ii) a refactoring to a server-side container ServerWebSocketContainer to
house the server-side only deploy() methods
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.
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.
- Danny
--
<http://www.oracle.com> *Danny Coward *
Java EE
Oracle Corporation