users@jsr311.java.net

Re: ApplicationConfig vs. Application

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 30 Jul 2008 18:45:45 +0200

Reto Bachmann-Gmür wrote:
> Hi Paul
>>> Not sure how this will work, for Providers there's usually just one
>>> instance, but resource classes by default are created one per
>>> resource. When will the singletons be used?
>>
>> It depends on the application requirements. We had some requirements
>> to support singletons where the instance is configured by something
>> else and that instance is passed to the JAX-RS runtime. This is a very
>> simple approach. For more complicated requirements to life-cycle and
>> initialization it is recommended to use an IoC framework.
> Still not sure how an implementation is supposed to handle the provided
> singletons. And if the application has to return Classes also for the
> resource classes and providers that are already returned as singletons.

Good point, we need to resolve that in the specification and JavaDoc.
Namely:

- if a class, X say, is a member of the set of classes and an instance
   of X is a member of the set of singletons then an error should occur.

- if two or more instances of the same concrete class are members of the
   set of singletons then an error should occur.


>>
>>
>>>> Since a class or instance of a class can be identified as a provider
>>>> class or a root resource class from annotations on the class there
>>>> is no need for separate methods.
>>> This leads to another question, why are provider marked by an
>>> annotation and why isn't there just a superinterface for
>>> ExceptionMapper, ContextResolver, MessageBodyReader and
>>> MessageBodyWriter. This would allow stronger typing:
>>>
>>> java.util.Set<java.lang.Class<Provider>> getProviderClasses()
>>>
>>> or, to allow greater flexibility to the Application
>>>
>>> java.util.Set<Provider> getProviders()
>>
>> We followed the same pattern as for root resource classes, mark the
>> class of interest with an annotation (rather than a marker interface).
> As Stephan pointed out, the developer wouldn't have to add a marker
> interface as this would already be a superinterface of the interfaces it
> has to implement anyway.

The RI also uses @Provider for RI specific classes. It enables a more
general way of identification without necessarily hard-coding specific
knowledge of provider-specific interfaces in an implementation.


>>
>>
>> > The implementation would have to deal with the case of classes
>>> being both provider and resource classes.
>>
>> Of primary importance is whether it is easier for the developer, this
>> is what motivated the changes.
> I completely agree, the specification just has to specify what to do
> with such hybrids. I only found the API and no specification that is in
> sync with it.

Right, your feedback is most useful, and we need to resolve that gap.


>> I anticipate that for the majority of cases providing the set of
>> classes and letting the runtime instantiate (perhaps with dependency
>> injection e.g. with WebBeans or Spring) will be the most common case
>> rather than the application providing instances (without dependency
>> injection by runtime for such instances).
> I think that many such frameworks will provide different methods to
> locate providers and resource classes than the ApplicationConfig approach.

The RI provides implementations of ApplicationConfig to dynamically scan
for resource classes and providers based on the classpath or package
names. So far it has worked out rather well.


>>
>>
>>> For resource classes for the current approach of one instance per
>>> request a single instance is of no use. If we have singleton resource
>>> classes I think it would be useful to have a method returning the
>>> classes for the one-instance-per-request resource classes and another
>>> method returning the singleton-instances, the classes of the
>>> instances returned by the latter are not in the set returned by the
>>> other method.
>>
>> This is much more restricted in terms of life-cycle than what we
>> currently have. The *default* life-cycle is per-request, but another
>> life-cycle may be specified by other means e.g. using say Spring or
>> WebBeans. I have already experimented with Spring and other
>> life-cycles with the RI using annotations, it works very well and it
>> is not necessary to be specific about the life-cycle when declaring
>> the resource classes in the application configuration.
>>
> I don't see why this is more restrictive,

You said a "method returning the classes for the
one-instance-per-request resource classes" which as i under stood to
mean that such classes are restricted to the per-request life-cycle. The
current approach allows for per-request, singleton or other life-cycles
(as determined by a JAX-RS implementation or an IoC framework) for
instances of those classes.


>> I have already used such functionality, especially for unit tests
>> where a bunch of resource classes and provider classes make up the
>> application. It is easier to declare the list of classes rather than
>> declaring a list of classes to the resource classes *and* another list
>> of the provider instances or classes.
> Not having to care about what kind of things you're dealing with can
> make things easier, it's just one list no need to think where something
> belongs, the implementation will sort it out. However I think this
> easiness is at cost of manageability and debugability. Resource classes
> and providers are quite different animals, an accidental provider in
> what is thought to be a list containing only resource-classes may cause
> quite a lot of debugging to be found.

It is the same for an accidental provider in a set of providers i.e.
just because the set is split (and typed or not) i doubt it really
reduces the possibility of such accidents happening. But i admit that is
pure speculation on my part.


> Also, with the concept "you name
> the classes we'll find out what to do with them" we have to expect
> complaints like "I put net.sf.saxon.TransformerFactoryImpl on my class
> list, but my application still gets the xalan TransformerFactory!",
> where does the flexibility end?
>

The class "TransformerFactoryImpl" is not annotated with @Path or
@Provider so it should be rejected preferably with some logged output
saying why it was rejected. I think we can make the JavaDoc clear in
this respect.

Paul.

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109