jakartaee / rest

Jakarta RESTful Web Services
Other
361 stars 117 forks source link

Drop support for @Context injection and related artifacts #951

Open spericas opened 3 years ago

spericas commented 3 years ago

Note that this issue is not about deprecation, but about dropping support, and it is targeted for the next major release. We should review other artifacts related to @Context that need removal.

jamezp commented 2 years ago

What is the intention for something like:

@GET
@Path("eventStream")
@Produces(MediaType.SERVER_SENT_EVENTS)
public void eventStream(@Context SseEventSink eventSink,
                        @Context Sse sse) {
    executor.execute(() -> {
        try (SseEventSink sink = eventSink) {
            eventSink.send(sse.newEvent("event1"));
            eventSink.send(sse.newEvent("event2"));
            eventSink.send(sse.newEvent("event3"));
        }
    });
}

Injecting the SseEventSink as a parameter is used in all the TCK tests and examples. I've personally only ever seen SseEventSink injected as a method parameter.

It would likely require large refactoring for users to remove parameter injection of @Context. Not that I'm opposed to using CDI and deprecating @Context and ContextResolver. I just worry about the removal for the migration issue.

P.S. I wasn't sure if I should have commented this here or on #569, but I opted for here only because it's newer :)

spericas commented 2 years ago

@jamezp It would be injectable as a normal CDI bean without the need to use @Context. Any CDI bean shall be injectable in param position on a resource method, in fact.

jamezp commented 2 years ago

@spericas Kind of what I assumed, but just wanted to verify thank you. I'm working on this for RESTEasy which seems like for full support is going to take some refactoring. However, that is not a spec issue :)

rmannibucau commented 2 years ago

Can you confirm you intend to break existing applications at two levels:

  1. Force users to move from context to inject
  2. Prevent users to distinguish between CDI and JAXRS beans without a custom qualifier (since currently context is considered as a classifier in several/most applications so you can have @Inject Foo foo; and @Inject @Context Foo foo - with implicit or not @Inject)
  3. Not be able to distinguish anymore what is a context from a payload in POST/PUT/... methods - guess you intend to fail somehow?

On my side I don't understand the gain to break something which works so I would request to maybe not do it to avoid people to have to rewrite their apps.

arjantijms commented 2 years ago

On my side I don't understand the gain

The gain is to go to a single component model, and not have 6 different ones, which all have their quirks in interaction and all have to be maintained separately. Faces moved to CDI in this release, and there's a long standing wish toi phase out EJB beans in favour of CDI compatible alternatives.

rmannibucau commented 2 years ago

@arjantijms I get this point but can't you get it without any breaking change defining @Context as a qualifier? Will keep existing code working and unify the model anyway. So proposal is to:

  1. deprecate @Context injection wtihout @Inject for fields/methods,
  2. define @Context as being a qualifier when ran in a CDI container (SE or EE)
  3. keep parameter injections as it is

This makes everyone happy (no code to rewrite, CDI fully embraced - actually it is what most JAXRS containers already do in CDI integrations).

arjantijms commented 2 years ago

Redefining Context as qualifier might be an option to consider.

We did do this once with jakarta.faces.convert.FacesConverter, which was made retroactively a qualifier. It wasn't without its own issues though, although the mistake we made there was perhaps not switching over completely (it supports converters being CDI and old-style at the same time).

rmannibucau commented 2 years ago

A side note is that CDI embracement is also about not keeping SeBootstrap unreleased class since defining CDI integration in JAXRS (scanning etc) solves wat SeBootstrap tries to do in a clumsy way since it requires users to either be fully explicit or reimplement the scanning + it does not promote what all implementations had been doing (cause it fits user requests) plus it has some other pitfalls like not being well integrated with the container since it is not linked to servlet container (only http layer in EE) to control the bindings. SE API already failed in other specs (thinking strongly to JAXWS Endpoint) so not sure current API SNAPSHOT is great so I think this issue should be part of an epic "CDI integration" which would mean:

  1. Ensure it is integrated with CDI at API level - previous proposal,
  2. Ensure it is integrated with CDI at scanning level (mainly define the CDI extension behavior to find providers, endpoints, features, application, ...) and start the server. Here it should work well and transparently with CDI SE API as well as CDI EE API when in an EE container (which would just get more scanning rules to stay backward compat but the minimum should work in both env making code way more reusable).
  3. Ensure beans can be CDI instances and not just injectable instances (it is not well defined currently IIRC), including the scope delegation (whatever scope should work, not only requetscoped or singleton/appscoped)
  4. (optional) define that an event is fired when the server starts/stops (to know endpoints are available or not)

Guess it would be the main integrations which would enable to run JAXRS in all env without learning a new programming model. Not sure how epics are managed for this project but feel free to promote as such that if it makes sense for you.

spericas commented 2 years ago

Redefining @Context as a qualifier isn't going to make the new Jakarta REST compatible. There are other significant differences (resource method parameters, context resolvers, entity params, etc.) that have been proposed and discussed. Moreover, making something that looks syntactically compatible but is semantically different is even worse (e.g, @Context can not be used in parameter position).

I understand that dropping backward compatibility has some cost, but Jakarta REST has been compatible for a decade and some of the initial decisions would have been different had CDI been matured at the time. Implementations that support the existing API will remain available for a long time for those that don't want to migrate.

spericas commented 2 years ago

@rmannibucau On the topic of scanning, absolutely, CDI scanning should be part of the SE proposal.

rmannibucau commented 2 years ago

@spericas well, if you want to enforce all JAXRS component to be CDI beans then you break 100% of JAXRS applications (most of features, body readers/writers etc are standalone instances and not even managed by CDI - which is good in general in terms of design for the application but also for libraries writers). To make it CDI compatible you don't have to break anything, just keep the integration with 3rd party libraries smooth and easy so probably don't drop @Context support without @Inject for not managed beans - this is the part to spec properly since it is undefined. Supporting @Inject @Context is a good move forward for CDI beans but this one requires @Context to be a qualifier. So overall the logic would be:

  1. if the instance is a cdi bean, only @Inject @Context are respected (which implies CDI bean instances are explicitly supported, yeah :))
  2. if the instance is a standalone bean only @Context are respected

This is exactly what jbatch does with quite some success. Moving to a full CDI model had been evaluated but was not judged realistic for end users and 3rd parties and I tend to think it would be the same for JAXRS.

arjantijms commented 2 years ago

if the instance is a standalone bean only @Context are respected

It's best not to have that confusing difference.

People also thought in 2003 not everything could be a spring bean in Spring, but they hold on to that concept and it worked quite well for them.

For Faces, people also thought it could not use CDI exclusively, and there we are; using CDI exclusively. And for Jakarta Security, the same was thought; invent a semi component model that abstracts from CDI, since who knows, some person, somewhere out there, might want to use Jakarta Security with Python, and doesn't want to use CDI. But it too uses CDI exclusively making everything a lot simpler.

Don't forget that Jakarta EE doesn't have even close to the resources it had before. Maintaining large abstraction framework over things that are essentially abstract themselves, who is going to maintain that?

rmannibucau commented 2 years ago

Not sure it is true, most jsf components are still not cdi beans and making it beans slows down things and makes the app consuming way more mem. Same for spring. Whatever you want, the way jaxrs is defined it has its own ioc so handling standalone is cheap and easy to understand for the consumers i mentionned. If you want to align it on cdi you should drop jaxrs filters, interceptors etc for the same argument/point so jaxrs becomes cdi centric and way lighter by dripping redundant concept. While I can see benefit to that it would be a huge breaking change but not doing it does not solve the duplication and ambiguities IMHO.

arjantijms commented 2 years ago

Not sure it is true, most jsf components are still not cdi beans

Faces UIComponents are not CDI beans, but I was referring to the managed beans (which are mostly used for backing beans). The own native managed bean / IOC facility of Faces has just been pruned and it's gone.

Internally several things are managed by CDI already, and there's more on the agenda. See e.g. https://arjan-tijms.omnifaces.org/p/jsf-23.html#cdi

and making it beans slows down things and makes the app consuming way more mem.

What is the slow down exactly? And how much more memory does it consume? Do you have any benchmarks related to this?

Whatever you want, the way jaxrs is defined it has its own ioc so handling standalone is cheap and easy to understand for the consumers i mentionned.

Is that really the case? Now Jersey for instance uses HK2 internally to handle the bean model and injection. Going forward that could be e.g. Weld. Why is Jersey using HK2 internally easier to understand than using Weld Internally?

mkarg commented 2 years ago

I'd like to propose to separate discussions into several issues, hence discuss replacing the annotation @Context by the annotation @Inject separately from enforcing the use of CDI, separately from how to deal with SeBootstrap shortcomings. There might be interrelations, but I assume it makes finding a consensus much easier.

rmannibucau commented 2 years ago

Agree but it also needs an "epic" to coordinate all of them with consistency otherwise we would end up with local solutions and no global one IMHO.

mkarg commented 2 years ago

Thank you for this idea, but actually I think the JAX-RS Committers have proven since years that they are pretty able to decide on their own how they organize their project.

rmannibucau commented 2 years ago

@mkarg exactly, this is why I asked how governance would be handled to avoid errors on this topic but it is really up to you to make it specified (my only request is no breaking change nor new useless api as an user).

spericas commented 2 years ago

Remaining backward compatible is definitely not a goal for 4.0. In fact, we have been trying to better align with CDI for a long time. Keeping support for @Context and all that implies would be for a new 3.X release, should the need for that arise.

rmannibucau commented 2 years ago

@spericas well since alignment is not done it can be added but the questions are "does it need to break" on one side and on ther other side "is the standalone feature used and needed". All applications I used were answering "no" and "yes" and with some good background so I think it can just be a clarification of CDI integration and not a restatement of the basis which would better fit a new spec where half of JAXRS concepts are dropped cause overlapping with CDI. To be super clear: you can break context support but if you really base JAXRS on CDI you drop all the JAXRS chains and half of the components/models/API so I humbly request a quick and dirty integration is not done if the goal is a deep integration but a full restart in a new spec to avoid ambiguity OR keep it compatible and aligned on the mainstream usage (way cheaper and likely sufficient for 99% of apps IMHO).

side note: microprofile played this "backward compatible is not a goal" but they lost a lot of users after very few years due to that and one of the biggest quality of JavaEE was to be backward compatible long enough regarding project life time so I hope it stays a fundation of JakartaEE too.

spericas commented 2 years ago

@rmannibucau I'm sorry but I cannot disagree more with your assessment of MP. In my view, Jakarta EE is the one at risk here if it continues to rely on old specs and does not bring better integration and innovations into the platform soon. As I stated before, if backward compatibility is essential, 3.X will continue to be supported by vendors for a long time.

rmannibucau commented 2 years ago

@spericas you assume moving forward means breaking. It implies that you take microprofile path, ie break each year applications enforcing coding for just upgrades (including security upgrade). This is a very bad experience for end user IMHO and technically not justifiable. Here, the topic is to specify the CDI integration in JAXRS spec, it is a relatively easy task - since all vendors did it almost the same way - and does not require any breaking change. If you want to break, you can indeed, but as explained, you will either take the MP path and make your user paying for no feature gain OR you will create a new spec so incrementing the version is irrelevant. The issue of EE is not relying on old specs (@Inject will likely stay for way more years without any issue) but to keep embracing new features properly - here I agree with you EE should keep up, for example defining what happens on a record, a better integration of Flow etc...nothing related to any breaking change, debt in JAXRS is not yet high enough to justify to break from the ground and I suspect it would go through another spec as explained.

OndroMih commented 2 years ago

Hi, my view on this is sort of mixed but practical. I've always had problems with @Context injection, which works completely on its own and doesn't even rely on plain @Inject like Batch injection does. On the other hand, I don't see much value in dropping @Context if it only means more work on the spec to remove it from the API, docs and tests. The only benefit for removing I see is that new potential implementations wouldn't need to implement it. For that sake, we can just make it optional and deprecated.

I would rather first focus on the replacement - to fully specify how CDI works in JAX-RS, how method arguments are injected (AFAIK this isn't supported by @Inject and CDI), and everything that would replace @Context.

Once we're done with that, we can drop @Context. Batch did it this way, improved CDI integration without dropping anything and left all removals for later. Faces defined CDI integration first with @Named and CDI scopes and only later dropped managed beans. But Faces now suffer a bit because a lot of tests will need to be removed or modified in the Jakarta TCK to align it.

bmarwell commented 2 years ago

Last comment sounds like a good idea. Maybe stretch dropping over a few releases. Yes, this means YEARS. Maybe like this?

Just my 2ยข because I agree with all of you: why break something for users which has been working like this forever? But then, don't hold on to old standards?

From a user's perspective (I use OpenLiberty a lot), jaxrs-x.0 will pull in servlet-y.0. Maybe some day servlet 3.0 will not be available anymore. Or I want to update step by step because (you got it:) big companies. And at some point you have to update.

So, if you need to break it, either give it a new name and artifact, or do it over multiple releases/years as gracefully as possible.

Thanks. ๐Ÿ˜‰

Oh, and thanks everyone for the good work and being a part of this. Even comments and opinions in the discussion matter a lot! ๐Ÿ™๐Ÿป

arjantijms commented 2 years ago

how method arguments are injected (AFAIK this isn't suppoeted by @Inject and CDI),

Well... actually it is. It's just that the parameters don't need to have the @Inject annotation applied to it. Producers and constructors use this all the time.

For instance:

@ApplicationScoped
public class ApplicationInit {

    private static final Logger logger = Logger.getLogger(ApplicationInit.class.getName());

    @Produces
    public HttpAuthenticationMechanism produce(InterceptionFactory<HttpAuthenticationMechanismWrapper> interceptionFactory, BeanManager beanManager) {
        .. 
    }
}

Here, the interceptionFactory and beanManager parameters are not part of any method signature and can be declared in any order, and any amount of parameters can be specified here. CDI will inject them as required, exactly as Jakarta REST does.

That said, we do have an issue open in CDI to make this a bit more convenient to use for arbitrary methods:

https://github.com/jakartaee/cdi/issues/460

arjantijms commented 2 years ago

Maybe stretch dropping over a few releases. Yes, this means YEARS.

In a way dropping @Context has already been in progress for give or take 13 to 14 years. Yes, that process already started before JAX-RS was released in 2009.

Somewhere around 2008 @gavinking noticed that the JAX-RS team was duplicating the efforts of the CDI team and went out to talk to them. It has been lost in history what exactly transpired in that talk, but shortly before the release of EE 6 a couple of amendments were made to provide some level of integration between the JAX-RS component model and the CDI one.

rmannibucau commented 2 years ago

@arjantijms your example is great to complete the reaons why @Context is needed. You example shows that @Inject can be omitted when implicit - your example is a CDI managed method where all parameters are CDI beans. JAX-RS is not that since parameters could come from CDI but they can also come from JAX-RS so it is not comparable, in particular with subresources or context instances which can be different from CDI instance (think to JSON-B instance for a trivial case but security and other transversal cases will get more complex usages of such a thing - multiple instances of the same bean "typed" in DI only through a qualifier).

The reason JAX-RS does not use CDI is because making it easy to run with another IoC always had been a goal which also led to creating the JAX-RS chains (filters, interceptors, etc...). All that is useless if you are based on CDI except @Context to remove the injection ambiguity as explained earlier so really think context is not the right fight for any coming release since best case it would be replaced by @Qualifier @interface Context {} which would be 1-1 for end users in all cases but the field/setter injections where @Inject would become required until CDI supports implicit inject for qualifiers - AFAIK it is more or less pushed by quarkus to become standard but some implementations already support it - quarkus/openwebbeans AFAIK.

spericas commented 2 years ago

CDI was fairly new and "unproven" at the time and it did not support SE in the early days. JAX-RS had other requirements that were difficult to achieve with a direct dependency on CDI. Times have changed, CDI is a core component in EE and MP, so there is no need to duplicate efforts any longer and make JAX-RS implementations complicated.

spericas commented 2 years ago

The reason JAX-RS does not use CDI is because making it easy to run with another IoC always had been a goal which also led to creating the JAX-RS chains (filters, interceptors, etc...). All that is useless if you are based on CDI

They are not useless. You could argue entity interceptors could be replaced (they don't really have to), but most of the other JAX-RS providers are far from useless.

arjantijms commented 2 years ago

The reason JAX-RS does not use CDI is because making it easy to run with another IoC always had been a goal

Are you sure? I can't remember that being stated anywhere at the time (or currently). Do you have any historical evidence for this? (not trying to be smart here, I spend a great amount of time finding out about the history of bean models and injection and writing about it for my CDI book).

At any length, CDI can be bridged to another component model / IoC just as well. Perhaps better even.

gavinking commented 2 years ago

Somewhere around 2008 @gavinking noticed that the JAX-RS team was duplicating the efforts of the CDI team and went out to talk to them. It has been lost in history what exactly transpired in that talk, but shortly before the release of EE 6 a couple of amendments were made to provide some level of integration between the JAX-RS component model and the CDI one

Haha OMG also entirely and completely lost to my memory. But it sounds like something that would have happened.

gavinking commented 2 years ago

The reason JAX-RS does not use CDI is because making it easy to run with another IoC always had been a goal

Mmmm. Naively this doesn't really sound quite right to me. How does JAX-RS having its totally own native thing help integrate with other dependency injection mechanisms? I believe the real reason was more likely that JAX-RS existed before CDI. If you want something more "neutral", @Inject is that something, IMO, not @Context.

P.S. It's probably not viable, but since @Inject itself is not specific to CDI, and is supported by other dependency injection frameworks, perhaps JAX-RS could try to talk more about @Inject than CDI. Depends how deep the integration needs to go. Probably not a useful suggestion.

rmannibucau commented 2 years ago

Guys, do you think #cdi is @Inject? Concretely if jaxrs goes #cdi it will never run on spring or guice because too much feature are missing. @Inject is another spec but it lacks any behabior definition so it is not usable as an IoC basis to a spec so at the end CDI implies what I explained.

Regardong the goal to be portable it is what I got as explanation why it was not CDI, "off" discussion was that some people were really pushing for spring at that time but not sure it is important today by itself but integrability is still even if personally CDI EE/SEwould be very fine as a basis.

@spericas do the exercise to create a jaxrs equivalent on top of cdi, you will not create so much abstraction and api will be / 2, just give it a try with all cdi concepts as core.

spericas commented 2 years ago

@rmannibucau The decision to drop abstractions from the API is completely ours. That exercise was started and there's a branch for that. Seems very different from what you have in mind. As for the Spring/Guice comment, not sure how to respond, this is a Jakarta EE spec that is core and as such part of MP as well.

mkarg commented 2 years ago

The reason JAX-RS does not use CDI is because making it easy to run with another IoC always had been a goal which also led to creating the JAX-RS chains (filters, interceptors, etc...).

The sole reason why JAX-RS does not use CDI simply is that when we invented JAX-RS simply CDI did not even exist, but we wanted to have context injection.

The sole reason why JAX-RS has filter and interceptor chains has nothing to with CDI at all but solely with the fact that we standardized around already existing standards and products: I copied the idea of Servlet filters while Bill Burke copied the concept of interceptors from RESTeasy.

Please do not make asumptions about the past of JAX-RS. Just ask us. We invented it.

mkarg commented 2 years ago

They are not useless. You could argue entity interceptors could be replaced (they don't really have to), but most of the other JAX-RS providers are far from useless.

Certainly they are not (not even interceptors, even if I doubted that back then when Bill Burke came up with it). Romain simply does not know the actual history. When back then I came up with the idea of adding a filter chain to JAX-RS I actually came from Servlet filters and, you won't believe but it is true, my first implementation of JAX-RS filter chain in fact was not written in Java at all but allowed to write ISAPI filter chains in Java (hence was written in C++ using JNI). See, while presumably all JAX-RS implementations today are written in Java (so could use CDI today), that was not the case back then. And still the JAX-RS spec does actually not say that a compliant implementation MUST be written in Java. So still filter chains MUST exist besides CDI. At least until we do enforce CDI hence drop support for non-Java implementations.

rmannibucau commented 2 years ago

@mkarg please don't write wrong things.

The sole reason why JAX-RS does not use CDI simply is that when we invented JAX-RS simply CDI did not even exist, but we wanted to have context injection.

Indeed it was there since they got published at the same time and it wouldnt have bezn the same time two specs work together for an EE release, was a wish. That said it does not help JAXRS to embrace CDI today without inventing a new peogramming model.

See, while presumably all JAX-RS implementations today are written in Java (so could use CDI today), that was not the case back then.

JAXRS only targets Java by design - API is java to have a trivial example - so not sure I understand the point there. If you only speak about the chain I agree CDI would prevent not java impl...but still not sure the point, spec prevents a lot of things starting from the routing algorithm which does not enable any REST API to be modelized and since rintime targets java runtimes only it is not a big deal IMHO. Functionally they are useless and make it harder for the user who has to learn 2 API and 2 ways to implement the same functional thing, this was my point.

Side note: cdi interceptor/delegator chain can be done in native too if you want to keep that part ;).

So overall is that jaxrs api is not designed to be cdi centric from the ground and if jaxrs breaks users and require to rewrite the code it would be great to do it full - I would recommend in another spec by ewtraction jaxrs core to ease transitions - OR to just not break if there is no gain like context topic.

mkarg commented 2 years ago

@mkarg please don't write wrong things.

I don't. You just misunderstand what "being there" means: Something that is already released and widely used. CDI was not release before JAX-RS, so it was not there. CDI was completely new, it came from a specific field of use, it was unclear if it will be here to stay.

JAXRS only targets Java by design

This is not true. JAX-RS aims for Java on the API side. The implementor's side is free of choice. Just like a RDMS can be written in C while the JDBC driver is written in Java, a JAX-RS Runtime could be written in C while the REST application is written in Java. Not that we strive for that, but we do not enforce a Runtime to be Java-based, actually. Anyways, this was only a historic example to indicate that the world is not quite that narrov as you see it.

So overall is that jaxrs api is not designed to be cdi centric from the ground and if jaxrs breaks users and require to rewrite the code it would be great to do it full - I would recommend in another spec by ewtraction jaxrs core to ease transitions - OR to just not break if there is no gain like context topic.

The JAX-RS committers will decide how to go on and I trust them to make the right decision. Users will then decide if they think 4.0 is so great that it makes sense to rewrite their apps in part, or whether to stick with 3.x.

jamezp commented 2 years ago

I'm not too sure where the best place for this comment is, but given the spec would like to align more with CDI injection it seems we should add @Inherited to the annotations. Per the CDI spec:

Inheritance of type-level metadata by beans from their superclasses is controlled via use of the Java @Inherited meta-annotation. Type-level metadata is never inherited from interfaces implemented by a bean.

This seems related to #539 and possibly to #968.

rmannibucau commented 2 years ago

@jamezp JAXRS-CDI integration already handles that AFAIK (only some implementations doing reflection on proxy without unwrapping have bugs but it is out of spec), @Inherited meaning seems unrelated to the linked issues and means something else so not sure it would help.

jamezp commented 2 years ago

@jamezp JAXRS-CDI integration already handles that AFAIK (only some implementations doing reflection on proxy without unwrapping have bugs but it is out of spec), @Inherited meaning seems unrelated to the linked issues and means something else so not sure it would help.

@rmannibucau I guess I was thinking more of the user, but maybe that doesn't matter. For example:

@Inject
MyApplication application;

public String getContextPath() {
    final ApplicationPath ap = application.getAnnotation(ApplicationPath.class);
    return ap == null ? "/" : ap.value();
}

Essentially anything the user injects. Granted, I could see a change like this as a backwards incompatible issue. However, if we're trying to move towards CDI then it seems like a reasonable expectation.

I came across this implementing CDI support for the SeBootstrap instance in RESTEasy and was just a bit surprised to see the annotations were not inherited.

rmannibucau commented 2 years ago

@jamezp it only partially solves the issue since you can get the exact same with most frameworks, even CDI depending how you setup/get the proxy. A CDI way to get this information is an extension or using the annotated type of the related class (MyApplication). Generally speaking, in CDI you should never do java.lang.reflect (application.getClass() in your example I assume) but always use CDI metamodel, this is why I think it is another issue.

jamezp commented 2 years ago

Okay, I apologize for the noise. This sounds like a user (me :)) error then.

rmannibucau commented 2 years ago

@jamezp it is a common one, can makes sense to emphasis it in CDI spec/doc ;)

ArneLimburg commented 2 years ago

What about this proposal: Deprecate the usage of JAX-RS specific Classes/Interfaces (I mean all that can be injected via @Context) as HTTP body.

Once this is done, we can simply recognize the Request body from every List of method paramters without using @Context).

After that we could finally remove @Context without really breaking any app. Field injection then would be via @Inject and parameter injection by type (to distinguish from request body). Apps, that have @Context in their code then can add an api dependency to compile it, at runtime it will simply be ignored.

rmannibucau commented 2 years ago

Context being custom injections too, not only readers/writers and others, it means spec must support cdi param injections so leads back to some param ambiguity no?

OndroMih commented 1 year ago

Reading the history of this issue, it seems that many different things were discussed here:

When we discuss all these in this issue, we should all understand that these are different issues and we can decided to do one or more, it's not all or nothing.

OndroMih commented 1 year ago

Ad. JAX-RS should keep support for running outside of CDI container

I think it was already decided in the platform level that there should be better integration with CDI and CDI should replace all other injection mechanisms if possible, even if it means that it won't be possible to use EE components outside of EE without loss of functionality. This vision has been adopted by e.g. Faces and Batch already. They both can be used outside of CDI. But CDI is either required for injection (in Faces), or a simple injection is supported without CDI (Batch). It could would be possible to use REST in Spring or plain Java SE even without injection, just context injection wouldn't work. We can provide a different mechanism to retrieve the context in Java SE, which I envisioned here for client API but it would work equally well for server: https://github.com/jakartaee/rest/issues/953#issuecomment-1478913666

Ad. whether we should drop @Context or keep API backwards compatibility

I believe we don't have to break existing applications by dropping the @Context completely. We can just define that it's supported only in a CDI container and how it works in the CDI container. All contexts that it can inject could be provided via CDI producers or extension as CDI beans. We can turn @Context into a qualifier to allow @Inject @Context Configuration config. Via a CDI extension, I think it's even possible to inject context without @Inject, in keeping backwards compatibility with the existing code. The ProcessAnnotatedType event should allow adding a virtual @Inject annotation everywhere next to the @Context annotation if it's not already present.

Ad. Delay dropping of @Context

There were many breaking changes in Jakarta EE 9 and 10 already. Dropping @Context would have significant impact on existing code, because I believe most of the JAX-RS apps use it at least a few times, and there might be libraries that also rely on it, which developers can't just change and would have to wait for their maintainers to update. So I'd like to avoid this in Jakarta EE 11, otherwise users would face significant breaking changes basically in every Jakarta EE release, making them tired of upgrading to Jakarta EE versions. We first implement CDI alternatives for injecting context in all places where @Context is supported, then create a release that allows using both CDI and @Context to inject the context, and later drop @Context. This would allow users to upgrade without breaking their applications, try out the new CDI way, but still be able to revert back to @Context if needed, until the next REST/Jakarta EE release that drops it.

With the previous point which allows complete transition to CDI and droping custom DI in REST, I think there's no desperate need to drop @Context and we could keep it for a long time, at least until we really need to introduce another breaking change which cannot be avoided. @Context would continue to be just an alias to @Inject.

spericas commented 1 year ago

If someone comes up with a detailed proposal in which @Context can be kept and makes sense, we should consider it. I'm not sure that proposal exists, and as usual the devil is in details. E.g., @Context can be used in parameter position and that is a real problem to align with CDI and the new proposal for executable methods.

With tighter CDI integration, keeping @Context around will likely create even more confusion, which is the very thing we are trying to eliminate as part of this effort.

rmannibucau commented 1 year ago

E.g., @Context can be used in parameter position and that is a real problem to align with CDI and the new proposal for executable methods.

Can you detail how it is a problem? JAXRS method parameters are handled by JAXRS runtime and CDI supports method parameters lookup - it is used by some libs and CDI itself.

Only real point is backward compat IMHO.