Topics

CDI integration

Pavel Bucek
 

Hi Guillermo,

The only caveat is that the implementation will need to know the classes by that point, which is before ServletContainerInitializer is fired
that certainly is a problem, we do rely on servlet scanning..

Regards,
Pavel


On 02/06/2017 19:11, Guillermo González de Agüero wrote:
Hi,

I've checked it and adding a new bean with CDI 2.0 is just as simple as creating an extension like this (taken from http://www.next-presso.com/2017/02/nobody-expects-the-cdi-portable-extensions/):

public class JaxRsExtension implements Extension {
   
    public void addClasses(@Observes BeforeBeanDiscovery bbd) {
        bbd.addAnnotatedType(RestResource.class, RestResource.class.getName()).
                add(RequestScoped.Literal.INSTANCE);
    }
}


The only caveat is that the implementation will need to know the classes by that point, which is before ServletContainerInitializer is fired (I'm not sure that's a problem; just stating so implementers may comment on it). That prevents the hard dependency on CDI, making everyone happy.

Thoughts?


Regards,

Guillermo González de Agüero


On Fri, Jun 2, 2017 at 5:32 PM, Pavel Bucek <pavel.bucek@...> wrote:

consider this as a subthread :)


On 02/06/2017 16:27, Guillermo González de Agüero wrote:

Ad @Stereotype - I'd need to check whether we can easily do that, since it would create a dependency on javax.enterprise.inject. I don't understand the remark about that annotation not being there in the runtime - it will be there, it has retention runtime (otherwise it wouldn't work)

I meant CDI will only be needed at (JAX-RS implementation) compile time. Applications won't need it as annotations not present on the classpath are just erased at runtime. So people using Spring or wathever non-CDI framework won't see any difference. Hope it clearer now?

To be absolutely honest, I'd expect CNFE or something like that. I already wrote a test, which corresponds to what you wrote ;) So thanks for that info, I wasn't aware of this behavior.

There is a little (forward) issue with this - similarly to any other "optional" dependency, there will be issues with this when Java 9 modules are used. Once the dependency on CDI API is declared in JAX-RS API module-info, CDI API will be required on the module path of any JAX-RS enabled app/code (at least for compilation).

Not saying that is a deal breaker, it's just something we need to consider.

Regards,
Pavel


Ondrej Mihályi
 

>> The only caveat is that the implementation will need to know the classes by that point, which is before ServletContainerInitializer is fired
that certainly is a problem, we do rely on servlet scanning..
Even it wouldn't be a problem, if @Path annotation isn't a bean defining annotation, the event wouldn't be fired at all in the "annotated" discovery mode if there are no other CDI beans (possible if resources only want to inject beans from other modules).

The approach of turning @Path into a stereotype is very nice and it doesn't require a runtime dependency on CDI at all. CDI API would be needed only to compile JAX-RS API because annotations not found on the classpath are ignored by the JVM, CDI impl wouldn't be needed at all. If we specify @RequestScoped in the stereotype, it would just specify what I believe all implementations do anyway -> create a resource instance per request, which is the default behavior mandated by the previous JAX-RS 2.0
It would be possible to override the scope for each class in a standard way by providing a scope annotation along with @Path.

Furthermore, if @Path is a stereotype, it would also become a bean-defining annotation and turn on CDI by default, even if there are no other CDI beans in the module, which is what most people would expect.

Ondro

Ondrej Mihályi
 

Regarding the dependency on CDI, I don't think that JAX-RS must depend on CDI at runtime at this stage. However, it could at least depend on @Inject from JSR 330 which should be preferred to @Context where applicable (naturally everywhere except method parameters).

Ondro

Ondrej Mihályi
 

I created an new issue to turn the @Path annotation into a CDI stereotype if used in a CDI container: https://github.com/jax-rs/api/issues/556

 

Turning on CDI by default implies that all methods have to be non-final, which is not backwards compatible to JAX-RS 2.0. So we cannot do that.

-Markus

 

From: jaxrs-spec@javaee.groups.io [mailto:jaxrs-spec@javaee.groups.io] On Behalf Of Ondrej Mihályi
Sent: Dienstag, 6. Juni 2017 16:27
To: jaxrs-spec@javaee.groups.io
Subject: Re: [jaxrs] CDI integration

 

>> The only caveat is that the implementation will need to know the classes by that point, which is before ServletContainerInitializer is fired

that certainly is a problem, we do rely on servlet scanning..

Even it wouldn't be a problem, if @Path annotation isn't a bean defining annotation, the event wouldn't be fired at all in the "annotated" discovery mode if there are no other CDI beans (possible if resources only want to inject beans from other modules).

The approach of turning @Path into a stereotype is very nice and it doesn't require a runtime dependency on CDI at all. CDI API would be needed only to compile JAX-RS API because annotations not found on the classpath are ignored by the JVM, CDI impl wouldn't be needed at all. If we specify @RequestScoped in the stereotype, it would just specify what I believe all implementations do anyway -> create a resource instance per request, which is the default behavior mandated by the previous JAX-RS 2.0
It would be possible to override the scope for each class in a standard way by providing a scope annotation along with @Path.

Furthermore, if @Path is a stereotype, it would also become a bean-defining annotation and turn on CDI by default, even if there are no other CDI beans in the module, which is what most people would expect.

Ondro

Santiago Pericas-Geertsen
 


On Jun 6, 2017, at 11:42 AM, Markus KARG <markus@...> wrote:

Turning on CDI by default implies that all methods have to be non-final, which is not backwards compatible to JAX-RS 2.0. So we cannot do that.
-Markus

 That's a good point, and certainly not something we can easily resolve.

 As others have mentioned, a strength of Java EE is integration with other specs like CDI, JSON-B, etc. But let us not forget that just as important is to ensure backward compatibility; adoption of newer versions of Java EE and JAX-RS depend on this compatibility not being threatened.

— Santiago

 
From: jaxrs-spec@javaee.groups.io [mailto:jaxrs-spec@javaee.groups.io] On Behalf Of Ondrej Mihályi
Sent: Dienstag, 6. Juni 2017 16:27
To: jaxrs-spec@javaee.groups.io
Subject: Re: [jaxrs] CDI integration
 
>> The only caveat is that the implementation will need to know the classes by that point, which is before ServletContainerInitializer is fired
that certainly is a problem, we do rely on servlet scanning..
Even it wouldn't be a problem, if @Path annotation isn't a bean defining annotation, the event wouldn't be fired at all in the "annotated" discovery mode if there are no other CDI beans (possible if resources only want to inject beans from other modules).

The approach of turning @Path into a stereotype is very nice and it doesn't require a runtime dependency on CDI at all. CDI API would be needed only to compile JAX-RS API because annotations not found on the classpath are ignored by the JVM, CDI impl wouldn't be needed at all. If we specify @RequestScoped in the stereotype, it would just specify what I believe all implementations do anyway -> create a resource instance per request, which is the default behavior mandated by the previous JAX-RS 2.0
It would be possible to override the scope for each class in a standard way by providing a scope annotation along with @Path.

Furthermore, if @Path is a stereotype, it would also become a bean-defining annotation and turn on CDI by default, even if there are no other CDI beans in the module, which is what most people would expect.

Ondro