users@websocket-spec.java.net

[jsr356-users] [jsr356-experts] Re: Bootstrapping Web Socket Applications in different places

From: Danny Coward <danny.coward_at_oracle.com>
Date: Fri, 09 Nov 2012 17:08:59 -0800

On 11/7/12 7:22 PM, Scott Ferguson wrote:
> On 11/7/12 5:59 PM, Danny Coward wrote:
>> Hello experts,
>>
>> Close students of the EDR spec will see that this is how the
>> application is bootstrapped:-
>>
>> A) In the web container, POJOs and programmatic endpoints are
>> packaged in the WAR
>> i) The implementation scans the WAR for annotated POJOs and deploys
>> them when the WAR is deployed
>> ii) For programmatic endpoints, the application developer has to
>> bootstrap the application 'by hand': by configuring an entry point
>> (like ServletContainerInitializer), and using the API
>> ContainerProvider.getServerContainer().publishServer(endpoint,
>> endpointconfiguration).
>>
>> B) In the standalone cases: standalone server, and standalone client,
>> the developer has to bootstrap the application in main() using
>> ContainerProvider.getServerContainer() or
>> ContainerProvider.getClientContainer() to get the appropriate
>> reference to the web socket container, from which he can
>> publishServer() or connectToServer().
>>
>> I'd propose a couple things to improve this, both as a convenience
>> for developers, and to unhook the API-implementation dependency
>> implied by the ContainerProvider API class:-
>>
>> 1) Require the websocket enabled web container scan for programmatic
>> endpoints in the WAR file and deploy them on startup. This would
>> require an API change to allow the Endpoint to supply its own
>> Configuration object: specifically add public EndpointConfiguration
>> getEndpointConfiguration() to Endpoint.
>
> I'm not sure I understand the difference between (1) and (A.i). Is (1)
> a similar WAR scanning to (A.i) but looking for "extends Endpoint"
> instead of "@WebSocketEndpoint"?
>
> I have a counter-proposal :) It may be a bit too radical.
>
> Suppose we support only the POJO model and remove
> Endpoint/MessageHandler entirely. When an application calls
> ClientContainer.connectToServer or ServerContainer.publishServer, it
> passes a POJO class (or instance) that's introspected for the annotations.
>
> The advantage is that it unifies endpoint to one programming model
> (for example it avoids the need to scan for Endpoint and simplifies
> the spec document).
>
> The disadvantage is that it seems radical to me. I'm not sure why I
> think that though.
We have had feedback that developers like to be able to do programmatic
endpoints as well as annotations, but I know some people would rather
everything be only annotations.

I'd like to keep the programmatic endpoints unless there is a strong
reason or consensus in this group that they are a bad idea.

As much as the EE programming model is focused around annotations
nowadays, there are still many developers who prefer an API approach. I
also think that allowing other websocket frameworks to layer on top of
our standard Endpoint API is going to be a big plus. I'd rather than
kind of invention happen on top of our APIs that away from them.

>
>> 2) Remove the ContainerProvider API and use the Java SE standard
>> ServiceLoader mechanism instead:
>> http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
>
> That would be an unusual change. JCache, for example, has a
> javax.cache.Caching class that's like the current ContainerProvider.
> It uses ServiceLoader internally, but doesn't ask the application to
> use ServiceLoader itself. I'm pretty sure the new CDI draft added a
> similar CDI class. The Caching/CDI/ContainerProvider model is pretty
> much used everywhere else in the Java specs that I've worked with.
Absolutely, there are many specs that take this approach of a bootstrap
class, but many of them (like JCache) predate JDK 6 when ServiceLoader
was added. I can't find the CDI proposal - do you have a pointer ?

Its not really a big deal, but this was the kind of case ServiceLoader
was trying to address, and it does remove an awkward dependency between
an API class and the implementation.

The alternative of course is to use @Inject to inject the *Container,
but then we are left with the issue of non-CDI containers.

- Danny

>
> -- Scott
>
>
>>
>> As usual I'd welcome your thoughts and suggestions on this approach.
>>
>> Cheers,
>>
>> - Danny
>>
>>
>> --
>> <http://www.oracle.com> *Danny Coward *
>> Java EE
>> Oracle Corporation
>>
>


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