eclipse-ee4j / jersey

Eclipse Jersey Project - Read our Wiki:
https://github.com/eclipse-ee4j/jersey/wiki
Other
689 stars 350 forks source link

Support for externally created Java SE containers #4039

Open mkarg opened 5 years ago

mkarg commented 5 years ago

The idea behind CDI 2's Java SE containers was that a "normal" Java SE main method would configure and create an instance of SeContainer, while all libraries and frameworks (including Jersey) used by that Java SE application would provide CDI Extensions to be able to re-configure that existing container.

The existing Java SE support documented by the CDI 2 SE Hello World and Counter Example relies on Jersey producing the container, hence the actual Java SE application is unable to configure and create the SE container upfront - or in other words, if it would do it as intended by the CDI 2 specification and shown in lots of tutorials, there would be two distinct containers in the end.

To "correctly" support CDI 2 Java SE Containers in the way intended by the CDI specification (i. e. Jersey re-configures pre-existing containers instead of creating a container), Jersey's CDI 2 module must get modified to not create a container but to rely on the actual Java SE application's creation of one. Jersey must simply be a CDI Extension which modifies that container (i. e. Jersey reacts upon CDI events and uses BeanManager to add more beans). In turn, the example application must explicitly create a container instead of letting Jersey do that.

jansupol commented 5 years ago

Helloworld-cdi2-se example is an application that is supposed to be run a Java SE environment, i.e. in a NOT CDI managed environment. For CDI managed environment, there is

        <dependency>
            <groupId>org.glassfish.jersey.ext.cdi</groupId>
            <artifactId>jersey-cdi1x</artifactId>
        </dependency>

to be used.

mkarg commented 5 years ago

You are right with that, but what this PR actually talks about is Java SE managed CDI, i. e. a Java SE application provides a container which is to be used by Jersey.

jansupol commented 5 years ago

Do you have any issue with using jersey-cdi1x in such a case?

mkarg commented 5 years ago

@jansupol According the name name jersey-cdi1x does not support Java SE Containers, as those are CDI 2 only.

jansupol commented 5 years ago

Ah, I understand what you mean

mkarg commented 5 years ago

@jansupol Good! :tada:

cdcarter commented 4 years ago

I'm pretty new to CDI and Jersey (so if I get the details wrong, please help correct my understanding), but I was trying to tackle this problem on a small project of mine. I already have a Weld SE container running, and I want it to start up Grizzly and Jersey to provide some resources.

The current jersey-weld2-se and jersey-cdi1x modules use different techniques for connecting Jersey and CDI.

The "SE" module does what you notice, and starts up a new SeContainer once Jersey is finished bootstrapping. As far as I can tell, this is so that the everything bound in HK2 can be added directly to the Weld environment, and all jersey injections can route through Weld. This means all Jersey beans are known at startup time and are fully available for Weld to verify. This is done through an Extension, but the Extension instance needs the fully bootstrapped Jersey to bind everything.

The CDI1x module, on the other hand, proxies all Weld injections to HK2 if it appears to be a Jersey thing (by inspecting the class package and other things). This means that Jersey doesn't need to be running to start up CDI, but calls into HK2 aren't as verifiable by weld (maybe?).

In either case, in order to use Jersey with an existing SE container, you either need to have Jersey start the container and provide all the HK2 things at startup OR some mashup of the two techniques needs to be made...

I'm not sure what's reasonable.