jsr356-experts@websocket-spec.java.net

[jsr356-experts] Re: More more programmatic deployment

From: Danny Coward <danny.coward_at_oracle.com>
Date: Tue, 26 Feb 2013 13:52:23 -0800

Hi Mark and Rossen,

OK, let me change tack here, and make sure I understand what you are
both proposing, and that in fact you agree with each other :)

In addition to the existing scan + ServerApplicationConfiguration
mechanism, you'd like (* denotes new API)

ServerContainer* extends WebSocketContainer {
     public void deploy(Class<?> pojo) throws DeploymentException;
     public void deploy(Class<? extends Endpoint> programmaticEndpoint,
ServerEndpointConfiguration sec) throws DeploymentException;
}

So from some some kind of deployment initialization code you would write

ServerContainer* sc = ServerContainerProvider*.getServerContainer();
sc.deploy(...); ///etc

and your placing of such deployment initialization code would be:
1) no webcontainer: not defined
2) web container: using some existing servlet mechanism, e.g. inside a
ServletContextListener configured in the web.xml.

Is that right ?

If so, we are currently trying to restrict there to be one
ServerContainer instance per websocket application. Do you have enough
context under the ServerContainerProvider*.getServerContainer(); call to
do that ?

- Danny


On 2/26/13 5:59 AM, Mark Thomas wrote:
> 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


-- 
<http://www.oracle.com> 	*Danny Coward *
Java EE
Oracle Corporation