Implementation of RFC-193 CDI

classic Classic list List threaded Threaded
35 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Implementation of RFC-193 CDI

Raymond Auge
Hello All,

I've been working through implementing RFC-193 [1] and have a relatively decent initial cut with most major details already sorted out.

I'm wondering if Apache Aries project is interested in hosting this implementation?

- Ray

[1] https://github.com/osgi/design/tree/master/rfcs/rfc0193

PS: If you look at RFC-193 in it's current state please note that it needs to be re-factored so that the technical section follows from the requirements section and I will do that in the next little while.

Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

David Bosschaert
Hi Ray,

I think that it would be a great addition for Apache Aries!

+1 from me,

David

On 23 November 2016 at 15:33, Raymond Auge <[hidden email]> wrote:
Hello All,

I've been working through implementing RFC-193 [1] and have a relatively decent initial cut with most major details already sorted out.

I'm wondering if Apache Aries project is interested in hosting this implementation?

- Ray

[1] https://github.com/osgi/design/tree/master/rfcs/rfc0193

PS: If you look at RFC-193 in it's current state please note that it needs to be re-factored so that the technical section follows from the requirements section and I will do that in the next little while.


Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Christian Schneider
In reply to this post by Raymond Auge
+1

Looking forward to this since I talked with Emily at eclipsecon 2015 :-)

Christian

On 23.11.2016 16:33, Raymond Auge wrote:
Hello All,

I've been working through implementing RFC-193 [1] and have a relatively decent initial cut with most major details already sorted out.

I'm wondering if Apache Aries project is interested in hosting this implementation?

- Ray

[1] https://github.com/osgi/design/tree/master/rfcs/rfc0193

PS: If you look at RFC-193 in it's current state please note that it needs to be re-factored so that the technical section follows from the requirements section and I will do that in the next little while.



-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com
Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Raymond Auge
Also I'm not a committer at Aries, so I guess this would be a request to become one with the donation of this code.

Sincerely,
- Ray

On Wed, Nov 23, 2016 at 10:58 AM, Christian Schneider <[hidden email]> wrote:
+1

Looking forward to this since I talked with Emily at eclipsecon 2015 :-)

Christian


On 23.11.2016 16:33, Raymond Auge wrote:
Hello All,

I've been working through implementing RFC-193 [1] and have a relatively decent initial cut with most major details already sorted out.

I'm wondering if Apache Aries project is interested in hosting this implementation?

- Ray

[1] https://github.com/osgi/design/tree/master/rfcs/rfc0193

PS: If you look at RFC-193 in it's current state please note that it needs to be re-factored so that the technical section follows from the requirements section and I will do that in the next little while.



-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com



--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)
Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Guillaume Nodet-2
In reply to this post by Raymond Auge
I find this RFC quite worthless from a pure OSGi pov.  If the only purpose is to allow existing CDI application to be ported to OSGi, that's fine.  It can't and should not (imho) be used for people that target OSGi.
So this is a really bad idea, but I've already said so quite a few times and proposed a solution in pax-cdi that actually solves the problem correctly in my mind: it has the exact same possibilities than DS (actually being based on the felix scr runtime) which is a well proven technology to handle OSGi dynamics.  The assumption in the RFC that "CDI does not support dynamic dependencies" is just wrong and is the basis for a bad design imho : scopes can be dynamic so that beans can have a lifecycle tied to a web request or web session, so it obviously can support having beans tied to the fact its runtime dependencies are available in OSGi.

Just my 2 cents

2016-11-23 16:33 GMT+01:00 Raymond Auge <[hidden email]>:
Hello All,

I've been working through implementing RFC-193 [1] and have a relatively decent initial cut with most major details already sorted out.

I'm wondering if Apache Aries project is interested in hosting this implementation?

- Ray

[1] https://github.com/osgi/design/tree/master/rfcs/rfc0193

PS: If you look at RFC-193 in it's current state please note that it needs to be re-factored so that the technical section follows from the requirements section and I will do that in the next little while.




--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration


Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

David Bosschaert
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

On 23 November 2016 at 16:14, Guillaume Nodet <[hidden email]> wrote:
I find this RFC quite worthless from a pure OSGi pov.  If the only purpose is to allow existing CDI application to be ported to OSGi, that's fine.  It can't and should not (imho) be used for people that target OSGi.
So this is a really bad idea, but I've already said so quite a few times and proposed a solution in pax-cdi that actually solves the problem correctly in my mind: it has the exact same possibilities than DS (actually being based on the felix scr runtime) which is a well proven technology to handle OSGi dynamics.  The assumption in the RFC that "CDI does not support dynamic dependencies" is just wrong and is the basis for a bad design imho : scopes can be dynamic so that beans can have a lifecycle tied to a web request or web session, so it obviously can support having beans tied to the fact its runtime dependencies are available in OSGi.

Just my 2 cents

2016-11-23 16:33 GMT+01:00 Raymond Auge <[hidden email]>:
Hello All,

I've been working through implementing RFC-193 [1] and have a relatively decent initial cut with most major details already sorted out.

I'm wondering if Apache Aries project is interested in hosting this implementation?

- Ray

[1] https://github.com/osgi/design/tree/master/rfcs/rfc0193

PS: If you look at RFC-193 in it's current state please note that it needs to be re-factored so that the technical section follows from the requirements section and I will do that in the next little while.




--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration



Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Christian Schneider
I think it would be great if Guillaume and Ray could work on the impl
together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian

On 23.11.2016 17:30, David Bosschaert wrote:

> Hi Guillaume,
>
> My understanding is that the technical design of the RFC will be
> significantly changed to better support the OSGi dynamics - hopefully
> we'll see an update soon at
> https://github.com/osgi/design/tree/master/rfcs/rfc0193
>
> If I understand things correctly then Ray's CDI implementation will
> support the improved design.
>
> Cheers,
>
> David

--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Raymond Auge
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)
Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Guillaume Nodet-2


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration


Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Raymond Auge


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function.

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)
Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Raymond Auge
One more thing, Guillaume, you have much much much more knowledge of CDI than I. There is no debate there. So let's just put that out there to start so that no one get's confused about it.

- Ray

On Wed, Nov 23, 2016 at 12:40 PM, Raymond Auge <[hidden email]> wrote:


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function.

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)
Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Guillaume Nodet-2
In reply to this post by Raymond Auge


2016-11-23 18:40 GMT+01:00 Raymond Auge <[hidden email]>:


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

And you're ruling out the existence of other scopes or that the spec supports custom scopes.  The prototype scope is the default scope, it does not mean it's the only one. @RequestScope and @SessionScope do handle dynamics very well : the beans are not created until a request or session exist and is destroyed when the request / session is destroyed : if that's not dynamic, I'm not sure what it is.
That's what I'm proposing : having the ability to use a custom scope to support more OSGi dynamics.  
My solution has both a global lifecycle suited to porting JEE applications (where the whole container lifecycle is tied to the global set of dependencies) and one custom scope that can handle specific bean lifecycles, so that OSGi users can benefit from a correct support of OSGi dynamism as in DS.
 

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function. 

I don't see how having extensions is related to scopes and lifecycle.  Supporting extensions is a must-have in CDI.  What you implied is that because you want to support extensions, we can't use custom scopes.  I think I was the one to suggest using generic capabilities to support extension in the RFC years ago.

And to answer your other email, I do not pretend to have a really good knowledge of CDI (really, I don't). I may be missing things in using custom scopes, but I'd like to understand what exactly, if any.
 

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration


Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Raymond Auge
So let's purely focus on scopes then. Because as far as I've observed, in my limited CDI experience, is that there are really only two scopes in CDI, technically:

- singleton
- not-singleton or rather "limited by some boundary"

Take any CDI scope and you can fit it in one of those two buckets:

ApplicationScoped
ConversationScoped
RequestScoped
SessionScoped
Dependent
Singleton
etc.

Enter any custom scope and they should pretty much fall into one of those two buckets.

The instance either lives from the beginning of the application 'til the end OR some "Context" logic instantiates an instance at some point in time, and later releases it. Perhaps multiple threads create their own instance, perhaps the instance lives during the life of a transaction, etc. The business logic around the actual lifetime is irrelevant, but the instantiation and reclamation is important.

The one difference in scopes that exists in OSGi but not in CDI is "osgi bundle scope" vs "osgi singleton scope". However this difference only relates to what CDI can emit or consume from OSGi as services. Internally it would have no meaning because the CDI container is fundamentally scoped to the bundle (at least in terms of the RFC requirements... which I think are sound in this case) and so it need not concern itself to distinguish between a singleton scoped service and a bundle scoped service (but it can certainly force the requirement either way if it really wishes but internally to CDI it makes no difference).

In fact, the bean wrapper we place around OSGi services is really the guardian of how the implementation creates and destroys instances based on the context of the CDI scope.

However, the OSGi service layer very nicely abstracts this for us in a clever way for which we don't necessarily need to concern ourselves over the context, and lifetime (or boundary) of the scope.

If we simply always assume and use of the OSGi prototype API, then we transparently satisfy any boundaries implemented by the CDI scope because the osgi prototype API transparently supports services which are any of singleton, bundle or prototype scope.

So with a single bean implementation around all osgi services we safely support pretty much any CDI scope.

The problem then becomes having a mechanism to enforce that a given scope really only allows binding prototype scoped osgi services, but I think this is not a real issue. It sounds reasonable that people would not redefine a singleton, or application scope, and in that respect we could simply assume that if the scope is not explicitly declared as:

Singleton
ApplicationScoped
BundleScoped (osgi cdi spec)
SingletonScoped (osgi cdi spec?? not really sure we need to redefine this)

that we automatically assume they should require prototype scoped services in order to satisfy the fact that the scope needs to create and destroy instances at it's own leisure.

😕😲🙄 Hopefully that made some kind of sense!!!

- Ray



On Wed, Nov 23, 2016 at 12:48 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:40 GMT+01:00 Raymond Auge <[hidden email]>:


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

And you're ruling out the existence of other scopes or that the spec supports custom scopes.  The prototype scope is the default scope, it does not mean it's the only one. @RequestScope and @SessionScope do handle dynamics very well : the beans are not created until a request or session exist and is destroyed when the request / session is destroyed : if that's not dynamic, I'm not sure what it is.
That's what I'm proposing : having the ability to use a custom scope to support more OSGi dynamics.  
My solution has both a global lifecycle suited to porting JEE applications (where the whole container lifecycle is tied to the global set of dependencies) and one custom scope that can handle specific bean lifecycles, so that OSGi users can benefit from a correct support of OSGi dynamism as in DS.
 

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function. 

I don't see how having extensions is related to scopes and lifecycle.  Supporting extensions is a must-have in CDI.  What you implied is that because you want to support extensions, we can't use custom scopes.  I think I was the one to suggest using generic capabilities to support extension in the RFC years ago.

And to answer your other email, I do not pretend to have a really good knowledge of CDI (really, I don't). I may be missing things in using custom scopes, but I'd like to understand what exactly, if any.
 

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)
Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Raymond Auge
actually, I have to correct myself because after a little more consideration, it seems that @ApplicationScoped and @Singleton map quite literally to osgi's "bundle scope" and "singleton scope" respectively.

- Ray

On Wed, Nov 23, 2016 at 1:48 PM, Raymond Auge <[hidden email]> wrote:
So let's purely focus on scopes then. Because as far as I've observed, in my limited CDI experience, is that there are really only two scopes in CDI, technically:

- singleton
- not-singleton or rather "limited by some boundary"

Take any CDI scope and you can fit it in one of those two buckets:

ApplicationScoped
ConversationScoped
RequestScoped
SessionScoped
Dependent
Singleton
etc.

Enter any custom scope and they should pretty much fall into one of those two buckets.

The instance either lives from the beginning of the application 'til the end OR some "Context" logic instantiates an instance at some point in time, and later releases it. Perhaps multiple threads create their own instance, perhaps the instance lives during the life of a transaction, etc. The business logic around the actual lifetime is irrelevant, but the instantiation and reclamation is important.

The one difference in scopes that exists in OSGi but not in CDI is "osgi bundle scope" vs "osgi singleton scope". However this difference only relates to what CDI can emit or consume from OSGi as services. Internally it would have no meaning because the CDI container is fundamentally scoped to the bundle (at least in terms of the RFC requirements... which I think are sound in this case) and so it need not concern itself to distinguish between a singleton scoped service and a bundle scoped service (but it can certainly force the requirement either way if it really wishes but internally to CDI it makes no difference).

In fact, the bean wrapper we place around OSGi services is really the guardian of how the implementation creates and destroys instances based on the context of the CDI scope.

However, the OSGi service layer very nicely abstracts this for us in a clever way for which we don't necessarily need to concern ourselves over the context, and lifetime (or boundary) of the scope.

If we simply always assume and use of the OSGi prototype API, then we transparently satisfy any boundaries implemented by the CDI scope because the osgi prototype API transparently supports services which are any of singleton, bundle or prototype scope.

So with a single bean implementation around all osgi services we safely support pretty much any CDI scope.

The problem then becomes having a mechanism to enforce that a given scope really only allows binding prototype scoped osgi services, but I think this is not a real issue. It sounds reasonable that people would not redefine a singleton, or application scope, and in that respect we could simply assume that if the scope is not explicitly declared as:

Singleton
ApplicationScoped
BundleScoped (osgi cdi spec)
SingletonScoped (osgi cdi spec?? not really sure we need to redefine this)

that we automatically assume they should require prototype scoped services in order to satisfy the fact that the scope needs to create and destroy instances at it's own leisure.

😕😲🙄 Hopefully that made some kind of sense!!!

- Ray



On Wed, Nov 23, 2016 at 12:48 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:40 GMT+01:00 Raymond Auge <[hidden email]>:


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

And you're ruling out the existence of other scopes or that the spec supports custom scopes.  The prototype scope is the default scope, it does not mean it's the only one. @RequestScope and @SessionScope do handle dynamics very well : the beans are not created until a request or session exist and is destroyed when the request / session is destroyed : if that's not dynamic, I'm not sure what it is.
That's what I'm proposing : having the ability to use a custom scope to support more OSGi dynamics.  
My solution has both a global lifecycle suited to porting JEE applications (where the whole container lifecycle is tied to the global set of dependencies) and one custom scope that can handle specific bean lifecycles, so that OSGi users can benefit from a correct support of OSGi dynamism as in DS.
 

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function. 

I don't see how having extensions is related to scopes and lifecycle.  Supporting extensions is a must-have in CDI.  What you implied is that because you want to support extensions, we can't use custom scopes.  I think I was the one to suggest using generic capabilities to support extension in the RFC years ago.

And to answer your other email, I do not pretend to have a really good knowledge of CDI (really, I don't). I may be missing things in using custom scopes, but I'd like to understand what exactly, if any.
 

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)
Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Guillaume Nodet-2
In reply to this post by Raymond Auge

2016-11-23 19:48 GMT+01:00 Raymond Auge <[hidden email]>:
So let's purely focus on scopes then. Because as far as I've observed, in my limited CDI experience, is that there are really only two scopes in CDI, technically:

- singleton
- not-singleton or rather "limited by some boundary"

I'd say those are the same.  The singleton scope is just one scope which uses boundaries equals to the container lifecycle.
 

Take any CDI scope and you can fit it in one of those two buckets:

ApplicationScoped
ConversationScoped
RequestScoped
SessionScoped
Dependent
Singleton
etc.

Enter any custom scope and they should pretty much fall into one of those two buckets.

Yes, they all define a boundary.
 

The instance either lives from the beginning of the application 'til the end OR some "Context" logic instantiates an instance at some point in time, and later releases it. Perhaps multiple threads create their own instance, perhaps the instance lives during the life of a transaction, etc. The business logic around the actual lifetime is irrelevant, but the instantiation and reclamation is important.

The one difference in scopes that exists in OSGi but not in CDI is "osgi bundle scope" vs "osgi singleton scope". However this difference only relates to what CDI can emit or consume from OSGi as services. Internally it would have no meaning because the CDI container is fundamentally scoped to the bundle (at least in terms of the RFC requirements... which I think are sound in this case) and so it need not concern itself to distinguish between a singleton scoped service and a bundle scoped service (but it can certainly force the requirement either way if it really wishes but internally to CDI it makes no difference).

In fact, the bean wrapper we place around OSGi services is really the guardian of how the implementation creates and destroys instances based on the context of the CDI scope.

However, the OSGi service layer very nicely abstracts this for us in a clever way for which we don't necessarily need to concern ourselves over the context, and lifetime (or boundary) of the scope.

If we simply always assume and use of the OSGi prototype API, then we transparently satisfy any boundaries implemented by the CDI scope because the osgi prototype API transparently supports services which are any of singleton, bundle or prototype scope.

So with a single bean implementation around all osgi services we safely support pretty much any CDI scope.

What do you mean by "supporting any CDI scope" ?  You mean exposing beans with any CDI scope in the OSGi registry ?
I'm not sure I understand what that would mean exporting a @RequestScoped bean as an OSGi service.
 

The problem then becomes having a mechanism to enforce that a given scope really only allows binding prototype scoped osgi services, but I think this is not a real issue. It sounds reasonable that people would not redefine a singleton, or application scope, and in that respect we could simply assume that if the scope is not explicitly declared as:

Singleton
ApplicationScoped
BundleScoped (osgi cdi spec)
SingletonScoped (osgi cdi spec?? not really sure we need to redefine this)

that we automatically assume they should require prototype scoped services in order to satisfy the fact that the scope needs to create and destroy instances at it's own leisure.

😕😲🙄 Hopefully that made some kind of sense!!!

I'm not sure that we have to think about exposing OSGi services the way you do.  I don't see the use case for choosing any CDI bean from an existing application and exposing is over OSGi.  Services are usually well defined interfaces so there is a decision to expose a service in the OSGi registry.  So I'm fine with using custom annotations if needed.
Also, I'm not sure what you describe accomodates with the exposed bean lifecycle having to be tied to its dependencies as I advocate.

So basically I'm fine with the 3 scopes defined in the RFC when exposing beans OSGi services:
  * BundleScoped
  * PrototypeScoped
  * SingletonScoped
We could do some mapping with existing CDI scopes if needed.
But my main concern is certainly not that one.  

My concern is about the lifecycle when you inject services from the OSGi registry into a CDI bean, not exporting services.
 As I indicated in my first email, my concern is about handling OSGi dynamics, not exporting OSGi services which is the easy part, and not about CDI extensions, which I fully agree we need to support.

What I'd like is a real injection framework that we can point OSGi users to.
Blueprint has some deficiencies ; the service damping mechanism is a pain to deal with and also a pain to work around.
DS is very good at handling OSGi dynamics : it supports a great range of use cases and the defaults makes users life easy.  The problem with DS is that it's limited to wiring OSGi services together, it's not pluggable, and can't do anything else.

If I'm understanding things right:
  * if you inject an OSGI service into a bean, the while container lifecycle will be tied to the availability of that bean
  * if you use an optional dependency, a null proxy is injected
That's basically the only 2 scenarios supported by the RFC for injecting services.

My proposal supports:
  * mandatory / optional 
  * greedy / reluctant
  * static / dynamic
  * local / global
Those should not deviate from the fact that a bean will never change during it's lifecycle.  The way to implement that is to make the bean lifecycle boundary defined by the availability of its dependencies.    It means beans injected with OSGi services have to be in a custom CDI scope so that its lifecycle can be managed.  So whenever the dependencies of a CDI bean injected with OSGi services change in a way that the bean needs to be re-injected, we destroy the bean correctly and re-create it with the new dependencies.  IT supports the mandatory / optional and greedy / reluctant DS semantics.
We also have the use case where you have a bean, but you don't want the lifecycle to be modified and you want a proxy to be injected to use service damping.  It's not the default, but it can be supported.  That's the static / dynamic semantic.
There are some use cases where you don't want to change the scope.  For those use cases, the injection point needs to be flagged properly so that the whole container lifecycle will be tied to the dependencies. That's the local / global semantic which does not exist in DS.

On the other side, i.e. exposing a service, there is:
  * bundle / service / prototype service scope
  * immediate / delayed 

A bunch of other things that should be supported:
  * injecting configuration using annotations as in DS (configuration can be mandatory / optional, greedy / reluctant) : an annotation defines the injected config with optional default values, as specified in DS 112.8.2
  * injecting Instance<X> for mutiple cardinality injection
  * filtering using generic filters or attributes (attributes can be used also when exposing services and can hide

So yes, I need a custom scope to support the above use cases.  But that makes things actually useful for OSGi developers imho, and not only simple use cases for EE developers porting applications to OSGi.  Supporting all well known DS semantics ensures a complete usability for all known OSGi use cases.  I think if we go this way, we can end up with something really useful for both OSGi beginners and more seasoned OSGi developers.

Guillaume


- Ray



On Wed, Nov 23, 2016 at 12:48 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:40 GMT+01:00 Raymond Auge <[hidden email]>:


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

And you're ruling out the existence of other scopes or that the spec supports custom scopes.  The prototype scope is the default scope, it does not mean it's the only one. @RequestScope and @SessionScope do handle dynamics very well : the beans are not created until a request or session exist and is destroyed when the request / session is destroyed : if that's not dynamic, I'm not sure what it is.
That's what I'm proposing : having the ability to use a custom scope to support more OSGi dynamics.  
My solution has both a global lifecycle suited to porting JEE applications (where the whole container lifecycle is tied to the global set of dependencies) and one custom scope that can handle specific bean lifecycles, so that OSGi users can benefit from a correct support of OSGi dynamism as in DS.
 

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function. 

I don't see how having extensions is related to scopes and lifecycle.  Supporting extensions is a must-have in CDI.  What you implied is that because you want to support extensions, we can't use custom scopes.  I think I was the one to suggest using generic capabilities to support extension in the RFC years ago.

And to answer your other email, I do not pretend to have a really good knowledge of CDI (really, I don't). I may be missing things in using custom scopes, but I'd like to understand what exactly, if any.
 

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration


Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

David Jencks
Hi Guillaume,

I don’t completely understand what you mean by local/global…. and my knowledge of CDI is much less than either your or Ray’s knowledge.

Lets consider a request-scoped CDI bean A into which we’ve injected a service from a DS component B which has a mandatory reference to service C.

If we start to unregister C, B’s deactivate method will be called.  If A was a DS component, with a mandatory reference to B, first A’s deactivate method would be called.  But iA is a CDI bean.

Should deactivate on B be postponed until A goes out of scope (the request completes)?  This would be somewhat similar to, if A was  DS component, having a read-write lock where all the service methods get a read lock and the DS lifecycle methods get the write lock.

Is this related to what you mean by local/global?  

hoping for more concrete details…
thanks
david jencks

On Nov 23, 2016, at 12:10 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 19:48 GMT+01:00 Raymond Auge <[hidden email]>:
So let's purely focus on scopes then. Because as far as I've observed, in my limited CDI experience, is that there are really only two scopes in CDI, technically:

- singleton
- not-singleton or rather "limited by some boundary"

I'd say those are the same.  The singleton scope is just one scope which uses boundaries equals to the container lifecycle.
 

Take any CDI scope and you can fit it in one of those two buckets:

ApplicationScoped
ConversationScoped
RequestScoped
SessionScoped
Dependent
Singleton
etc.

Enter any custom scope and they should pretty much fall into one of those two buckets.

Yes, they all define a boundary.
 

The instance either lives from the beginning of the application 'til the end OR some "Context" logic instantiates an instance at some point in time, and later releases it. Perhaps multiple threads create their own instance, perhaps the instance lives during the life of a transaction, etc. The business logic around the actual lifetime is irrelevant, but the instantiation and reclamation is important.

The one difference in scopes that exists in OSGi but not in CDI is "osgi bundle scope" vs "osgi singleton scope". However this difference only relates to what CDI can emit or consume from OSGi as services. Internally it would have no meaning because the CDI container is fundamentally scoped to the bundle (at least in terms of the RFC requirements... which I think are sound in this case) and so it need not concern itself to distinguish between a singleton scoped service and a bundle scoped service (but it can certainly force the requirement either way if it really wishes but internally to CDI it makes no difference).

In fact, the bean wrapper we place around OSGi services is really the guardian of how the implementation creates and destroys instances based on the context of the CDI scope.

However, the OSGi service layer very nicely abstracts this for us in a clever way for which we don't necessarily need to concern ourselves over the context, and lifetime (or boundary) of the scope.

If we simply always assume and use of the OSGi prototype API, then we transparently satisfy any boundaries implemented by the CDI scope because the osgi prototype API transparently supports services which are any of singleton, bundle or prototype scope. 

So with a single bean implementation around all osgi services we safely support pretty much any CDI scope. 

What do you mean by "supporting any CDI scope" ?  You mean exposing beans with any CDI scope in the OSGi registry ?
I'm not sure I understand what that would mean exporting a @RequestScoped bean as an OSGi service.
 

The problem then becomes having a mechanism to enforce that a given scope really only allows binding prototype scoped osgi services, but I think this is not a real issue. It sounds reasonable that people would not redefine a singleton, or application scope, and in that respect we could simply assume that if the scope is not explicitly declared as:

Singleton
ApplicationScoped
BundleScoped (osgi cdi spec)
SingletonScoped (osgi cdi spec?? not really sure we need to redefine this) 

that we automatically assume they should require prototype scoped services in order to satisfy the fact that the scope needs to create and destroy instances at it's own leisure.

😕😲🙄 Hopefully that made some kind of sense!!!

I'm not sure that we have to think about exposing OSGi services the way you do.  I don't see the use case for choosing any CDI bean from an existing application and exposing is over OSGi.  Services are usually well defined interfaces so there is a decision to expose a service in the OSGi registry.  So I'm fine with using custom annotations if needed.
Also, I'm not sure what you describe accomodates with the exposed bean lifecycle having to be tied to its dependencies as I advocate.

So basically I'm fine with the 3 scopes defined in the RFC when exposing beans OSGi services:
  * BundleScoped
  * PrototypeScoped
  * SingletonScoped
We could do some mapping with existing CDI scopes if needed.
But my main concern is certainly not that one.  

My concern is about the lifecycle when you inject services from the OSGi registry into a CDI bean, not exporting services.
 As I indicated in my first email, my concern is about handling OSGi dynamics, not exporting OSGi services which is the easy part, and not about CDI extensions, which I fully agree we need to support.

What I'd like is a real injection framework that we can point OSGi users to.
Blueprint has some deficiencies ; the service damping mechanism is a pain to deal with and also a pain to work around.
DS is very good at handling OSGi dynamics : it supports a great range of use cases and the defaults makes users life easy.  The problem with DS is that it's limited to wiring OSGi services together, it's not pluggable, and can't do anything else.

If I'm understanding things right:
  * if you inject an OSGI service into a bean, the while container lifecycle will be tied to the availability of that bean
  * if you use an optional dependency, a null proxy is injected
That's basically the only 2 scenarios supported by the RFC for injecting services.

My proposal supports:
  * mandatory / optional 
  * greedy / reluctant
  * static / dynamic
  * local / global
Those should not deviate from the fact that a bean will never change during it's lifecycle.  The way to implement that is to make the bean lifecycle boundary defined by the availability of its dependencies.    It means beans injected with OSGi services have to be in a custom CDI scope so that its lifecycle can be managed.  So whenever the dependencies of a CDI bean injected with OSGi services change in a way that the bean needs to be re-injected, we destroy the bean correctly and re-create it with the new dependencies.  IT supports the mandatory / optional and greedy / reluctant DS semantics.
We also have the use case where you have a bean, but you don't want the lifecycle to be modified and you want a proxy to be injected to use service damping.  It's not the default, but it can be supported.  That's the static / dynamic semantic.
There are some use cases where you don't want to change the scope.  For those use cases, the injection point needs to be flagged properly so that the whole container lifecycle will be tied to the dependencies. That's the local / global semantic which does not exist in DS.

On the other side, i.e. exposing a service, there is:
  * bundle / service / prototype service scope
  * immediate / delayed 

A bunch of other things that should be supported:
  * injecting configuration using annotations as in DS (configuration can be mandatory / optional, greedy / reluctant) : an annotation defines the injected config with optional default values, as specified in DS 112.8.2
  * injecting Instance<X> for mutiple cardinality injection
  * filtering using generic filters or attributes (attributes can be used also when exposing services and can hide

So yes, I need a custom scope to support the above use cases.  But that makes things actually useful for OSGi developers imho, and not only simple use cases for EE developers porting applications to OSGi.  Supporting all well known DS semantics ensures a complete usability for all known OSGi use cases.  I think if we go this way, we can end up with something really useful for both OSGi beginners and more seasoned OSGi developers.

Guillaume


- Ray



On Wed, Nov 23, 2016 at 12:48 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:40 GMT+01:00 Raymond Auge <[hidden email]>:


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

And you're ruling out the existence of other scopes or that the spec supports custom scopes.  The prototype scope is the default scope, it does not mean it's the only one. @RequestScope and @SessionScope do handle dynamics very well : the beans are not created until a request or session exist and is destroyed when the request / session is destroyed : if that's not dynamic, I'm not sure what it is.
That's what I'm proposing : having the ability to use a custom scope to support more OSGi dynamics.  
My solution has both a global lifecycle suited to porting JEE applications (where the whole container lifecycle is tied to the global set of dependencies) and one custom scope that can handle specific bean lifecycles, so that OSGi users can benefit from a correct support of OSGi dynamism as in DS.
 

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function. 

I don't see how having extensions is related to scopes and lifecycle.  Supporting extensions is a must-have in CDI.  What you implied is that because you want to support extensions, we can't use custom scopes.  I think I was the one to suggest using generic capabilities to support extension in the RFC years ago.

And to answer your other email, I do not pretend to have a really good knowledge of CDI (really, I don't). I may be missing things in using custom scopes, but I'd like to understand what exactly, if any.
 

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration


Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Guillaume Nodet-2
A "global" injection point means:
  * the container will not start until  the dependency is satisfied
  * the container will be destroyed if the dependency is not satisfied anymore
By default, dependencies on OSGi services are "local", i.e. the injected bean lifecycle is tied to the dependency being satisfied or not, and that cascades to other beans (so that inside the same container, if A is injected with B and B is injected with an OSGi service C, if C goes away, B and A will be destroyed ; that's not really supported by DS btw because DS can only inject osgi services, not DS components into another DS component), but it does not affect the cdi application as a whole.  
So that's not postponing anything.
It's merely a side-effect of the fact that handling dynamics require a custom CDI scope, and there may be use cases where you want to use a standard scope.  In those cases, you can use a global dependency, because the bean lifecycle does not have to be managed specifically (the whole container lifecycle is managed instead).


2016-11-23 22:27 GMT+01:00 David Jencks <[hidden email]>:
Hi Guillaume,

I don’t completely understand what you mean by local/global…. and my knowledge of CDI is much less than either your or Ray’s knowledge.

Lets consider a request-scoped CDI bean A into which we’ve injected a service from a DS component B which has a mandatory reference to service C.

If we start to unregister C, B’s deactivate method will be called.  If A was a DS component, with a mandatory reference to B, first A’s deactivate method would be called.  But iA is a CDI bean.

Should deactivate on B be postponed until A goes out of scope (the request completes)?  This would be somewhat similar to, if A was  DS component, having a read-write lock where all the service methods get a read lock and the DS lifecycle methods get the write lock.

Is this related to what you mean by local/global?  

hoping for more concrete details…
thanks
david jencks

On Nov 23, 2016, at 12:10 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 19:48 GMT+01:00 Raymond Auge <[hidden email]>:
So let's purely focus on scopes then. Because as far as I've observed, in my limited CDI experience, is that there are really only two scopes in CDI, technically:

- singleton
- not-singleton or rather "limited by some boundary"

I'd say those are the same.  The singleton scope is just one scope which uses boundaries equals to the container lifecycle.
 

Take any CDI scope and you can fit it in one of those two buckets:

ApplicationScoped
ConversationScoped
RequestScoped
SessionScoped
Dependent
Singleton
etc.

Enter any custom scope and they should pretty much fall into one of those two buckets.

Yes, they all define a boundary.
 

The instance either lives from the beginning of the application 'til the end OR some "Context" logic instantiates an instance at some point in time, and later releases it. Perhaps multiple threads create their own instance, perhaps the instance lives during the life of a transaction, etc. The business logic around the actual lifetime is irrelevant, but the instantiation and reclamation is important.

The one difference in scopes that exists in OSGi but not in CDI is "osgi bundle scope" vs "osgi singleton scope". However this difference only relates to what CDI can emit or consume from OSGi as services. Internally it would have no meaning because the CDI container is fundamentally scoped to the bundle (at least in terms of the RFC requirements... which I think are sound in this case) and so it need not concern itself to distinguish between a singleton scoped service and a bundle scoped service (but it can certainly force the requirement either way if it really wishes but internally to CDI it makes no difference).

In fact, the bean wrapper we place around OSGi services is really the guardian of how the implementation creates and destroys instances based on the context of the CDI scope.

However, the OSGi service layer very nicely abstracts this for us in a clever way for which we don't necessarily need to concern ourselves over the context, and lifetime (or boundary) of the scope.

If we simply always assume and use of the OSGi prototype API, then we transparently satisfy any boundaries implemented by the CDI scope because the osgi prototype API transparently supports services which are any of singleton, bundle or prototype scope. 

So with a single bean implementation around all osgi services we safely support pretty much any CDI scope. 

What do you mean by "supporting any CDI scope" ?  You mean exposing beans with any CDI scope in the OSGi registry ?
I'm not sure I understand what that would mean exporting a @RequestScoped bean as an OSGi service.
 

The problem then becomes having a mechanism to enforce that a given scope really only allows binding prototype scoped osgi services, but I think this is not a real issue. It sounds reasonable that people would not redefine a singleton, or application scope, and in that respect we could simply assume that if the scope is not explicitly declared as:

Singleton
ApplicationScoped
BundleScoped (osgi cdi spec)
SingletonScoped (osgi cdi spec?? not really sure we need to redefine this) 

that we automatically assume they should require prototype scoped services in order to satisfy the fact that the scope needs to create and destroy instances at it's own leisure.

😕😲🙄 Hopefully that made some kind of sense!!!

I'm not sure that we have to think about exposing OSGi services the way you do.  I don't see the use case for choosing any CDI bean from an existing application and exposing is over OSGi.  Services are usually well defined interfaces so there is a decision to expose a service in the OSGi registry.  So I'm fine with using custom annotations if needed.
Also, I'm not sure what you describe accomodates with the exposed bean lifecycle having to be tied to its dependencies as I advocate.

So basically I'm fine with the 3 scopes defined in the RFC when exposing beans OSGi services:
  * BundleScoped
  * PrototypeScoped
  * SingletonScoped
We could do some mapping with existing CDI scopes if needed.
But my main concern is certainly not that one.  

My concern is about the lifecycle when you inject services from the OSGi registry into a CDI bean, not exporting services.
 As I indicated in my first email, my concern is about handling OSGi dynamics, not exporting OSGi services which is the easy part, and not about CDI extensions, which I fully agree we need to support.

What I'd like is a real injection framework that we can point OSGi users to.
Blueprint has some deficiencies ; the service damping mechanism is a pain to deal with and also a pain to work around.
DS is very good at handling OSGi dynamics : it supports a great range of use cases and the defaults makes users life easy.  The problem with DS is that it's limited to wiring OSGi services together, it's not pluggable, and can't do anything else.

If I'm understanding things right:
  * if you inject an OSGI service into a bean, the while container lifecycle will be tied to the availability of that bean
  * if you use an optional dependency, a null proxy is injected
That's basically the only 2 scenarios supported by the RFC for injecting services.

My proposal supports:
  * mandatory / optional 
  * greedy / reluctant
  * static / dynamic
  * local / global
Those should not deviate from the fact that a bean will never change during it's lifecycle.  The way to implement that is to make the bean lifecycle boundary defined by the availability of its dependencies.    It means beans injected with OSGi services have to be in a custom CDI scope so that its lifecycle can be managed.  So whenever the dependencies of a CDI bean injected with OSGi services change in a way that the bean needs to be re-injected, we destroy the bean correctly and re-create it with the new dependencies.  IT supports the mandatory / optional and greedy / reluctant DS semantics.
We also have the use case where you have a bean, but you don't want the lifecycle to be modified and you want a proxy to be injected to use service damping.  It's not the default, but it can be supported.  That's the static / dynamic semantic.
There are some use cases where you don't want to change the scope.  For those use cases, the injection point needs to be flagged properly so that the whole container lifecycle will be tied to the dependencies. That's the local / global semantic which does not exist in DS.

On the other side, i.e. exposing a service, there is:
  * bundle / service / prototype service scope
  * immediate / delayed 

A bunch of other things that should be supported:
  * injecting configuration using annotations as in DS (configuration can be mandatory / optional, greedy / reluctant) : an annotation defines the injected config with optional default values, as specified in DS 112.8.2
  * injecting Instance<X> for mutiple cardinality injection
  * filtering using generic filters or attributes (attributes can be used also when exposing services and can hide

So yes, I need a custom scope to support the above use cases.  But that makes things actually useful for OSGi developers imho, and not only simple use cases for EE developers porting applications to OSGi.  Supporting all well known DS semantics ensures a complete usability for all known OSGi use cases.  I think if we go this way, we can end up with something really useful for both OSGi beginners and more seasoned OSGi developers.

Guillaume


- Ray



On Wed, Nov 23, 2016 at 12:48 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:40 GMT+01:00 Raymond Auge <[hidden email]>:


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

And you're ruling out the existence of other scopes or that the spec supports custom scopes.  The prototype scope is the default scope, it does not mean it's the only one. @RequestScope and @SessionScope do handle dynamics very well : the beans are not created until a request or session exist and is destroyed when the request / session is destroyed : if that's not dynamic, I'm not sure what it is.
That's what I'm proposing : having the ability to use a custom scope to support more OSGi dynamics.  
My solution has both a global lifecycle suited to porting JEE applications (where the whole container lifecycle is tied to the global set of dependencies) and one custom scope that can handle specific bean lifecycles, so that OSGi users can benefit from a correct support of OSGi dynamism as in DS.
 

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function. 

I don't see how having extensions is related to scopes and lifecycle.  Supporting extensions is a must-have in CDI.  What you implied is that because you want to support extensions, we can't use custom scopes.  I think I was the one to suggest using generic capabilities to support extension in the RFC years ago.

And to answer your other email, I do not pretend to have a really good knowledge of CDI (really, I don't). I may be missing things in using custom scopes, but I'd like to understand what exactly, if any.
 

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration


Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Emily Jiang-2
Late on the party...
2 things I must stress:
1. Supporting the current built-in scopes is much more important than introducing any custom scopes. Besides, we should not change their lifecycle. Most of user cases are around "bundlised EE apps containing CDI to run in OSGi".
2. All injections must go through OSGi service registry.

The CDI specification declares clearly on the start/finish of each scope (https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#scopes). @Singleton for EJB is treated same as @ApplicationScoped.

I saw Christine on this thread, which is great. I remind myself to get you involved, Christine, and it is great to know that you are happy to work with Ray. I am willing to answer any questions you might have.
Thanks
Emily

On Wed, Nov 23, 2016 at 11:00 PM, Guillaume Nodet <[hidden email]> wrote:
A "global" injection point means:
  * the container will not start until  the dependency is satisfied
  * the container will be destroyed if the dependency is not satisfied anymore
By default, dependencies on OSGi services are "local", i.e. the injected bean lifecycle is tied to the dependency being satisfied or not, and that cascades to other beans (so that inside the same container, if A is injected with B and B is injected with an OSGi service C, if C goes away, B and A will be destroyed ; that's not really supported by DS btw because DS can only inject osgi services, not DS components into another DS component), but it does not affect the cdi application as a whole.  
So that's not postponing anything.
It's merely a side-effect of the fact that handling dynamics require a custom CDI scope, and there may be use cases where you want to use a standard scope.  In those cases, you can use a global dependency, because the bean lifecycle does not have to be managed specifically (the whole container lifecycle is managed instead).


2016-11-23 22:27 GMT+01:00 David Jencks <[hidden email]>:
Hi Guillaume,

I don’t completely understand what you mean by local/global…. and my knowledge of CDI is much less than either your or Ray’s knowledge.

Lets consider a request-scoped CDI bean A into which we’ve injected a service from a DS component B which has a mandatory reference to service C.

If we start to unregister C, B’s deactivate method will be called.  If A was a DS component, with a mandatory reference to B, first A’s deactivate method would be called.  But iA is a CDI bean.

Should deactivate on B be postponed until A goes out of scope (the request completes)?  This would be somewhat similar to, if A was  DS component, having a read-write lock where all the service methods get a read lock and the DS lifecycle methods get the write lock.

Is this related to what you mean by local/global?  

hoping for more concrete details…
thanks
david jencks

On Nov 23, 2016, at 12:10 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 19:48 GMT+01:00 Raymond Auge <[hidden email]>:
So let's purely focus on scopes then. Because as far as I've observed, in my limited CDI experience, is that there are really only two scopes in CDI, technically:

- singleton
- not-singleton or rather "limited by some boundary"

I'd say those are the same.  The singleton scope is just one scope which uses boundaries equals to the container lifecycle.
 

Take any CDI scope and you can fit it in one of those two buckets:

ApplicationScoped
ConversationScoped
RequestScoped
SessionScoped
Dependent
Singleton
etc.

Enter any custom scope and they should pretty much fall into one of those two buckets.

Yes, they all define a boundary.
 

The instance either lives from the beginning of the application 'til the end OR some "Context" logic instantiates an instance at some point in time, and later releases it. Perhaps multiple threads create their own instance, perhaps the instance lives during the life of a transaction, etc. The business logic around the actual lifetime is irrelevant, but the instantiation and reclamation is important.

The one difference in scopes that exists in OSGi but not in CDI is "osgi bundle scope" vs "osgi singleton scope". However this difference only relates to what CDI can emit or consume from OSGi as services. Internally it would have no meaning because the CDI container is fundamentally scoped to the bundle (at least in terms of the RFC requirements... which I think are sound in this case) and so it need not concern itself to distinguish between a singleton scoped service and a bundle scoped service (but it can certainly force the requirement either way if it really wishes but internally to CDI it makes no difference).

In fact, the bean wrapper we place around OSGi services is really the guardian of how the implementation creates and destroys instances based on the context of the CDI scope.

However, the OSGi service layer very nicely abstracts this for us in a clever way for which we don't necessarily need to concern ourselves over the context, and lifetime (or boundary) of the scope.

If we simply always assume and use of the OSGi prototype API, then we transparently satisfy any boundaries implemented by the CDI scope because the osgi prototype API transparently supports services which are any of singleton, bundle or prototype scope. 

So with a single bean implementation around all osgi services we safely support pretty much any CDI scope. 

What do you mean by "supporting any CDI scope" ?  You mean exposing beans with any CDI scope in the OSGi registry ?
I'm not sure I understand what that would mean exporting a @RequestScoped bean as an OSGi service.
 

The problem then becomes having a mechanism to enforce that a given scope really only allows binding prototype scoped osgi services, but I think this is not a real issue. It sounds reasonable that people would not redefine a singleton, or application scope, and in that respect we could simply assume that if the scope is not explicitly declared as:

Singleton
ApplicationScoped
BundleScoped (osgi cdi spec)
SingletonScoped (osgi cdi spec?? not really sure we need to redefine this) 

that we automatically assume they should require prototype scoped services in order to satisfy the fact that the scope needs to create and destroy instances at it's own leisure.

😕😲🙄 Hopefully that made some kind of sense!!!

I'm not sure that we have to think about exposing OSGi services the way you do.  I don't see the use case for choosing any CDI bean from an existing application and exposing is over OSGi.  Services are usually well defined interfaces so there is a decision to expose a service in the OSGi registry.  So I'm fine with using custom annotations if needed.
Also, I'm not sure what you describe accomodates with the exposed bean lifecycle having to be tied to its dependencies as I advocate.

So basically I'm fine with the 3 scopes defined in the RFC when exposing beans OSGi services:
  * BundleScoped
  * PrototypeScoped
  * SingletonScoped
We could do some mapping with existing CDI scopes if needed.
But my main concern is certainly not that one.  

My concern is about the lifecycle when you inject services from the OSGi registry into a CDI bean, not exporting services.
 As I indicated in my first email, my concern is about handling OSGi dynamics, not exporting OSGi services which is the easy part, and not about CDI extensions, which I fully agree we need to support.

What I'd like is a real injection framework that we can point OSGi users to.
Blueprint has some deficiencies ; the service damping mechanism is a pain to deal with and also a pain to work around.
DS is very good at handling OSGi dynamics : it supports a great range of use cases and the defaults makes users life easy.  The problem with DS is that it's limited to wiring OSGi services together, it's not pluggable, and can't do anything else.

If I'm understanding things right:
  * if you inject an OSGI service into a bean, the while container lifecycle will be tied to the availability of that bean
  * if you use an optional dependency, a null proxy is injected
That's basically the only 2 scenarios supported by the RFC for injecting services.

My proposal supports:
  * mandatory / optional 
  * greedy / reluctant
  * static / dynamic
  * local / global
Those should not deviate from the fact that a bean will never change during it's lifecycle.  The way to implement that is to make the bean lifecycle boundary defined by the availability of its dependencies.    It means beans injected with OSGi services have to be in a custom CDI scope so that its lifecycle can be managed.  So whenever the dependencies of a CDI bean injected with OSGi services change in a way that the bean needs to be re-injected, we destroy the bean correctly and re-create it with the new dependencies.  IT supports the mandatory / optional and greedy / reluctant DS semantics.
We also have the use case where you have a bean, but you don't want the lifecycle to be modified and you want a proxy to be injected to use service damping.  It's not the default, but it can be supported.  That's the static / dynamic semantic.
There are some use cases where you don't want to change the scope.  For those use cases, the injection point needs to be flagged properly so that the whole container lifecycle will be tied to the dependencies. That's the local / global semantic which does not exist in DS.

On the other side, i.e. exposing a service, there is:
  * bundle / service / prototype service scope
  * immediate / delayed 

A bunch of other things that should be supported:
  * injecting configuration using annotations as in DS (configuration can be mandatory / optional, greedy / reluctant) : an annotation defines the injected config with optional default values, as specified in DS 112.8.2
  * injecting Instance<X> for mutiple cardinality injection
  * filtering using generic filters or attributes (attributes can be used also when exposing services and can hide

So yes, I need a custom scope to support the above use cases.  But that makes things actually useful for OSGi developers imho, and not only simple use cases for EE developers porting applications to OSGi.  Supporting all well known DS semantics ensures a complete usability for all known OSGi use cases.  I think if we go this way, we can end up with something really useful for both OSGi beginners and more seasoned OSGi developers.

Guillaume


- Ray



On Wed, Nov 23, 2016 at 12:48 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:40 GMT+01:00 Raymond Auge <[hidden email]>:


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

And you're ruling out the existence of other scopes or that the spec supports custom scopes.  The prototype scope is the default scope, it does not mean it's the only one. @RequestScope and @SessionScope do handle dynamics very well : the beans are not created until a request or session exist and is destroyed when the request / session is destroyed : if that's not dynamic, I'm not sure what it is.
That's what I'm proposing : having the ability to use a custom scope to support more OSGi dynamics.  
My solution has both a global lifecycle suited to porting JEE applications (where the whole container lifecycle is tied to the global set of dependencies) and one custom scope that can handle specific bean lifecycles, so that OSGi users can benefit from a correct support of OSGi dynamism as in DS.
 

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function. 

I don't see how having extensions is related to scopes and lifecycle.  Supporting extensions is a must-have in CDI.  What you implied is that because you want to support extensions, we can't use custom scopes.  I think I was the one to suggest using generic capabilities to support extension in the RFC years ago.

And to answer your other email, I do not pretend to have a really good knowledge of CDI (really, I don't). I may be missing things in using custom scopes, but I'd like to understand what exactly, if any.
 

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <[hidden email]> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Thanks
Emily
=================
Emily Jiang
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Implementation of RFC-193 CDI

Guillaume Nodet-2


Le jeudi 24 novembre 2016, Emily Jiang <[hidden email]> a écrit :
Late on the party...
2 things I must stress:
1. Supporting the current built-in scopes is much more important than introducing any custom scopes. 
What does supporting mean here ?
What does supporting @RequestScope means ? 
Besides, we should not change their lifecycle. Most of user cases are around "bundlised EE apps containing CDI to run in OSGi".
Most ? Maybe you mean most of *your* use cases ? 

2. All injections must go through OSGi service registry. 

I don't see any requirement in the RFC about that.  And I don't see why a limitation should become a requirement. The CDI023 req says inter-bundle  interactions, that's definitely different.
 
The CDI specification declares clearly on the start/finish of each scope (https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#scopes). @Singleton for EJB is treated same as @ApplicationScoped.

Cool, though i haven't suggested redefining existing scopes in a different way...

What about rhe following requirements:
 CDI016 – The specification MUST extend the life-cycle dependency model as provided in CDI, to support the dynamic life-cycle provided by OSGi. For example, it MUST NOT be fatal to deploy a CDI bean that does not have all its dependencies initially satisfied and it MUST be possible to change bean dependencies without requiring the CDI application to be redeployed or restarted.

CDI031 – The specification MUST extend the life-cycle dependency model of CDI to include dynamic OSGi service dependencies.

CDI017 – The specification MUST make it possible to declare a CDI injection point to an OSGi service as optional. 

 


 
I saw Christine on this thread, which is great. I remind myself to get you involved, Christine, and it is great to know that you are happy to work with Ray. I am willing to answer any questions you might have.
Thanks
Emily

On Wed, Nov 23, 2016 at 11:00 PM, Guillaume Nodet <<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;gnodet@apache.org&#39;);" target="_blank">gnodet@...> wrote:
A "global" injection point means:
  * the container will not start until  the dependency is satisfied
  * the container will be destroyed if the dependency is not satisfied anymore
By default, dependencies on OSGi services are "local", i.e. the injected bean lifecycle is tied to the dependency being satisfied or not, and that cascades to other beans (so that inside the same container, if A is injected with B and B is injected with an OSGi service C, if C goes away, B and A will be destroyed ; that's not really supported by DS btw because DS can only inject osgi services, not DS components into another DS component), but it does not affect the cdi application as a whole.  
So that's not postponing anything.
It's merely a side-effect of the fact that handling dynamics require a custom CDI scope, and there may be use cases where you want to use a standard scope.  In those cases, you can use a global dependency, because the bean lifecycle does not have to be managed specifically (the whole container lifecycle is managed instead).


2016-11-23 22:27 GMT+01:00 David Jencks <<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;david_jencks@yahoo.com&#39;);" target="_blank">david_jencks@...>:
Hi Guillaume,

I don’t completely understand what you mean by local/global…. and my knowledge of CDI is much less than either your or Ray’s knowledge.

Lets consider a request-scoped CDI bean A into which we’ve injected a service from a DS component B which has a mandatory reference to service C.

If we start to unregister C, B’s deactivate method will be called.  If A was a DS component, with a mandatory reference to B, first A’s deactivate method would be called.  But iA is a CDI bean.

Should deactivate on B be postponed until A goes out of scope (the request completes)?  This would be somewhat similar to, if A was  DS component, having a read-write lock where all the service methods get a read lock and the DS lifecycle methods get the write lock.

Is this related to what you mean by local/global?  

hoping for more concrete details…
thanks
david jencks

On Nov 23, 2016, at 12:10 PM, Guillaume Nodet <<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;gnodet@apache.org&#39;);" target="_blank">gnodet@...> wrote:


2016-11-23 19:48 GMT+01:00 Raymond Auge <<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;raymond.auge@liferay.com&#39;);" target="_blank">raymond.auge@...>:
So let's purely focus on scopes then. Because as far as I've observed, in my limited CDI experience, is that there are really only two scopes in CDI, technically:

- singleton
- not-singleton or rather "limited by some boundary"

I'd say those are the same.  The singleton scope is just one scope which uses boundaries equals to the container lifecycle.
 

Take any CDI scope and you can fit it in one of those two buckets:

ApplicationScoped
ConversationScoped
RequestScoped
SessionScoped
Dependent
Singleton
etc.

Enter any custom scope and they should pretty much fall into one of those two buckets.

Yes, they all define a boundary.
 

The instance either lives from the beginning of the application 'til the end OR some "Context" logic instantiates an instance at some point in time, and later releases it. Perhaps multiple threads create their own instance, perhaps the instance lives during the life of a transaction, etc. The business logic around the actual lifetime is irrelevant, but the instantiation and reclamation is important.

The one difference in scopes that exists in OSGi but not in CDI is "osgi bundle scope" vs "osgi singleton scope". However this difference only relates to what CDI can emit or consume from OSGi as services. Internally it would have no meaning because the CDI container is fundamentally scoped to the bundle (at least in terms of the RFC requirements... which I think are sound in this case) and so it need not concern itself to distinguish between a singleton scoped service and a bundle scoped service (but it can certainly force the requirement either way if it really wishes but internally to CDI it makes no difference).

In fact, the bean wrapper we place around OSGi services is really the guardian of how the implementation creates and destroys instances based on the context of the CDI scope.

However, the OSGi service layer very nicely abstracts this for us in a clever way for which we don't necessarily need to concern ourselves over the context, and lifetime (or boundary) of the scope.

If we simply always assume and use of the OSGi prototype API, then we transparently satisfy any boundaries implemented by the CDI scope because the osgi prototype API transparently supports services which are any of singleton, bundle or prototype scope. 

So with a single bean implementation around all osgi services we safely support pretty much any CDI scope. 

What do you mean by "supporting any CDI scope" ?  You mean exposing beans with any CDI scope in the OSGi registry ?
I'm not sure I understand what that would mean exporting a @RequestScoped bean as an OSGi service.
 

The problem then becomes having a mechanism to enforce that a given scope really only allows binding prototype scoped osgi services, but I think this is not a real issue. It sounds reasonable that people would not redefine a singleton, or application scope, and in that respect we could simply assume that if the scope is not explicitly declared as:

Singleton
ApplicationScoped
BundleScoped (osgi cdi spec)
SingletonScoped (osgi cdi spec?? not really sure we need to redefine this) 

that we automatically assume they should require prototype scoped services in order to satisfy the fact that the scope needs to create and destroy instances at it's own leisure.

😕😲🙄 Hopefully that made some kind of sense!!!

I'm not sure that we have to think about exposing OSGi services the way you do.  I don't see the use case for choosing any CDI bean from an existing application and exposing is over OSGi.  Services are usually well defined interfaces so there is a decision to expose a service in the OSGi registry.  So I'm fine with using custom annotations if needed.
Also, I'm not sure what you describe accomodates with the exposed bean lifecycle having to be tied to its dependencies as I advocate.

So basically I'm fine with the 3 scopes defined in the RFC when exposing beans OSGi services:
  * BundleScoped
  * PrototypeScoped
  * SingletonScoped
We could do some mapping with existing CDI scopes if needed.
But my main concern is certainly not that one.  

My concern is about the lifecycle when you inject services from the OSGi registry into a CDI bean, not exporting services.
 As I indicated in my first email, my concern is about handling OSGi dynamics, not exporting OSGi services which is the easy part, and not about CDI extensions, which I fully agree we need to support.

What I'd like is a real injection framework that we can point OSGi users to.
Blueprint has some deficiencies ; the service damping mechanism is a pain to deal with and also a pain to work around.
DS is very good at handling OSGi dynamics : it supports a great range of use cases and the defaults makes users life easy.  The problem with DS is that it's limited to wiring OSGi services together, it's not pluggable, and can't do anything else.

If I'm understanding things right:
  * if you inject an OSGI service into a bean, the while container lifecycle will be tied to the availability of that bean
  * if you use an optional dependency, a null proxy is injected
That's basically the only 2 scenarios supported by the RFC for injecting services.

My proposal supports:
  * mandatory / optional 
  * greedy / reluctant
  * static / dynamic
  * local / global
Those should not deviate from the fact that a bean will never change during it's lifecycle.  The way to implement that is to make the bean lifecycle boundary defined by the availability of its dependencies.    It means beans injected with OSGi services have to be in a custom CDI scope so that its lifecycle can be managed.  So whenever the dependencies of a CDI bean injected with OSGi services change in a way that the bean needs to be re-injected, we destroy the bean correctly and re-create it with the new dependencies.  IT supports the mandatory / optional and greedy / reluctant DS semantics.
We also have the use case where you have a bean, but you don't want the lifecycle to be modified and you want a proxy to be injected to use service damping.  It's not the default, but it can be supported.  That's the static / dynamic semantic.
There are some use cases where you don't want to change the scope.  For those use cases, the injection point needs to be flagged properly so that the whole container lifecycle will be tied to the dependencies. That's the local / global semantic which does not exist in DS.

On the other side, i.e. exposing a service, there is:
  * bundle / service / prototype service scope
  * immediate / delayed 

A bunch of other things that should be supported:
  * injecting configuration using annotations as in DS (configuration can be mandatory / optional, greedy / reluctant) : an annotation defines the injected config with optional default values, as specified in DS 112.8.2
  * injecting Instance<X> for mutiple cardinality injection
  * filtering using generic filters or attributes (attributes can be used also when exposing services and can hide

So yes, I need a custom scope to support the above use cases.  But that makes things actually useful for OSGi developers imho, and not only simple use cases for EE developers porting applications to OSGi.  Supporting all well known DS semantics ensures a complete usability for all known OSGi use cases.  I think if we go this way, we can end up with something really useful for both OSGi beginners and more seasoned OSGi developers.

Guillaume


- Ray



On Wed, Nov 23, 2016 at 12:48 PM, Guillaume Nodet <<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;gnodet@apache.org&#39;);" target="_blank">gnodet@...> wrote:


2016-11-23 18:40 GMT+01:00 Raymond Auge <<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;raymond.auge@liferay.com&#39;);" target="_blank">raymond.auge@...>:


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;gnodet@apache.org&#39;);" target="_blank">gnodet@...> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;raymond.auge@liferay.com&#39;);" target="_blank">raymond.auge@...>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

And you're ruling out the existence of other scopes or that the spec supports custom scopes.  The prototype scope is the default scope, it does not mean it's the only one. @RequestScope and @SessionScope do handle dynamics very well : the beans are not created until a request or session exist and is destroyed when the request / session is destroyed : if that's not dynamic, I'm not sure what it is.
That's what I'm proposing : having the ability to use a custom scope to support more OSGi dynamics.  
My solution has both a global lifecycle suited to porting JEE applications (where the whole container lifecycle is tied to the global set of dependencies) and one custom scope that can handle specific bean lifecycles, so that OSGi users can benefit from a correct support of OSGi dynamism as in DS.
 

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function. 

I don't see how having extensions is related to scopes and lifecycle.  Supporting extensions is a must-have in CDI.  What you implied is that because you want to support extensions, we can't use custom scopes.  I think I was the one to suggest using generic capabilities to support extension in the RFC years ago.

And to answer your other email, I do not pretend to have a really good knowledge of CDI (really, I don't). I may be missing things in using custom scopes, but I'd like to understand what exactly, if any.
 

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;chris@die-schneider.net&#39;);" target="_blank">chris@die-schneider.net> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration

Email: <a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;gnodet@redhat.com&#39;);" target="_blank">gnodet@...
Web: http://fusesource.com
Blog: http://gnodet.blogspot.com/




-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration

Email: <a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;gnodet@redhat.com&#39;);" target="_blank">gnodet@...
Web: http://fusesource.com
Blog: http://gnodet.blogspot.com/




-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration

Email: <a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;gnodet@redhat.com&#39;);" target="_blank">gnodet@...
Web: http://fusesource.com
Blog: http://gnodet.blogspot.com/




--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration

Email: <a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;gnodet@redhat.com&#39;);" target="_blank">gnodet@...
Web: http://fusesource.com
Blog: http://gnodet.blogspot.com/




--
Thanks
Emily
=================
Emily Jiang
<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;ejiang@apache.org&#39;);" target="_blank">ejiang@...


--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration



Reply | Threaded
Open this post in threaded view
|

Fwd: Implementation of RFC-193 CDI

Guillaume Nodet-2

2016-11-24 3:21 GMT+01:00 Guillaume Nodet <[hidden email]>:


Le jeudi 24 novembre 2016, Emily Jiang <[hidden email]> a écrit :
Late on the party...
2 things I must stress:
1. Supporting the current built-in scopes is much more important than introducing any custom scopes. 
What does supporting mean here ?
What does supporting @RequestScope means ? 

I think I now understand what Ray said when he talked about "bean wrapping" in an earlier email.  Now, I think I understand what you are both saying is that we should support annotating a CDI bean with @Service in scopes like @ApplicationScoped, @Dependent, or whatever, I don't really have any problem with that.  If we map to my earlier definitions of global / local injection point, then this would be a global service and the lifecycle and instantiations of the beans should be delegated to the scope of the bean and not redefined.
I'm fine with that.
 
Besides, we should not change their lifecycle. Most of user cases are around "bundlised EE apps containing CDI to run in OSGi".
Most ? Maybe you mean most of *your* use cases ? 

2. All injections must go through OSGi service registry. 

I don't see any requirement in the RFC about that.  And I don't see why a limitation should become a requirement. The CDI023 req says inter-bundle  interactions, that's definitely different.
 
The CDI specification declares clearly on the start/finish of each scope (https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#scopes). @Singleton for EJB is treated same as @ApplicationScoped.

Cool, though i haven't suggested redefining existing scopes in a different way...

What about rhe following requirements:
 CDI016 – The specification MUST extend the life-cycle dependency model as provided in CDI, to support the dynamic life-cycle provided by OSGi. For example, it MUST NOT be fatal to deploy a CDI bean that does not have all its dependencies initially satisfied and it MUST be possible to change bean dependencies without requiring the CDI application to be redeployed or restarted.

CDI031 – The specification MUST extend the life-cycle dependency model of CDI to include dynamic OSGi service dependencies.

CDI017 – The specification MUST make it possible to declare a CDI injection point to an OSGi service as optional. 


I don't have any problems with the main use case you want to support, i.e.: 
  * exposing any CDI bean as a an service 
  * being able to inject an OSGi service into any CDI bean
This is the static + greedy + global use case where the whole CDI application lifecycle is affected by dependencies changes.

To summarize, my big objections to the current state of the RFC are:
  * the scope is too limited and only cover a very small number of use cases
  * the fact that dependencies changes affect the whole CDI application should definitely not be the default behavior
  * mandatory dependencies should not be limited to services
  * optional dependencies should not require a proxy to be injected
  * we need to support greedy / reluctant, static / dynamic, global / local, immediate / delayed components, etc...
  * support for configurations

Cheers,
Guillaume 

 


 
I saw Christine on this thread, which is great. I remind myself to get you involved, Christine, and it is great to know that you are happy to work with Ray. I am willing to answer any questions you might have.
Thanks
Emily

On Wed, Nov 23, 2016 at 11:00 PM, Guillaume Nodet <[hidden email]> wrote:
A "global" injection point means:
  * the container will not start until  the dependency is satisfied
  * the container will be destroyed if the dependency is not satisfied anymore
By default, dependencies on OSGi services are "local", i.e. the injected bean lifecycle is tied to the dependency being satisfied or not, and that cascades to other beans (so that inside the same container, if A is injected with B and B is injected with an OSGi service C, if C goes away, B and A will be destroyed ; that's not really supported by DS btw because DS can only inject osgi services, not DS components into another DS component), but it does not affect the cdi application as a whole.  
So that's not postponing anything.
It's merely a side-effect of the fact that handling dynamics require a custom CDI scope, and there may be use cases where you want to use a standard scope.  In those cases, you can use a global dependency, because the bean lifecycle does not have to be managed specifically (the whole container lifecycle is managed instead).


2016-11-23 22:27 GMT+01:00 David Jencks <[hidden email]>:
Hi Guillaume,

I don’t completely understand what you mean by local/global…. and my knowledge of CDI is much less than either your or Ray’s knowledge.

Lets consider a request-scoped CDI bean A into which we’ve injected a service from a DS component B which has a mandatory reference to service C.

If we start to unregister C, B’s deactivate method will be called.  If A was a DS component, with a mandatory reference to B, first A’s deactivate method would be called.  But iA is a CDI bean.

Should deactivate on B be postponed until A goes out of scope (the request completes)?  This would be somewhat similar to, if A was  DS component, having a read-write lock where all the service methods get a read lock and the DS lifecycle methods get the write lock.

Is this related to what you mean by local/global?  

hoping for more concrete details…
thanks
david jencks

On Nov 23, 2016, at 12:10 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 19:48 GMT+01:00 Raymond Auge <[hidden email]>:
So let's purely focus on scopes then. Because as far as I've observed, in my limited CDI experience, is that there are really only two scopes in CDI, technically:

- singleton
- not-singleton or rather "limited by some boundary"

I'd say those are the same.  The singleton scope is just one scope which uses boundaries equals to the container lifecycle.
 

Take any CDI scope and you can fit it in one of those two buckets:

ApplicationScoped
ConversationScoped
RequestScoped
SessionScoped
Dependent
Singleton
etc.

Enter any custom scope and they should pretty much fall into one of those two buckets.

Yes, they all define a boundary.
 

The instance either lives from the beginning of the application 'til the end OR some "Context" logic instantiates an instance at some point in time, and later releases it. Perhaps multiple threads create their own instance, perhaps the instance lives during the life of a transaction, etc. The business logic around the actual lifetime is irrelevant, but the instantiation and reclamation is important.

The one difference in scopes that exists in OSGi but not in CDI is "osgi bundle scope" vs "osgi singleton scope". However this difference only relates to what CDI can emit or consume from OSGi as services. Internally it would have no meaning because the CDI container is fundamentally scoped to the bundle (at least in terms of the RFC requirements... which I think are sound in this case) and so it need not concern itself to distinguish between a singleton scoped service and a bundle scoped service (but it can certainly force the requirement either way if it really wishes but internally to CDI it makes no difference).

In fact, the bean wrapper we place around OSGi services is really the guardian of how the implementation creates and destroys instances based on the context of the CDI scope.

However, the OSGi service layer very nicely abstracts this for us in a clever way for which we don't necessarily need to concern ourselves over the context, and lifetime (or boundary) of the scope.

If we simply always assume and use of the OSGi prototype API, then we transparently satisfy any boundaries implemented by the CDI scope because the osgi prototype API transparently supports services which are any of singleton, bundle or prototype scope. 

So with a single bean implementation around all osgi services we safely support pretty much any CDI scope. 

What do you mean by "supporting any CDI scope" ?  You mean exposing beans with any CDI scope in the OSGi registry ?
I'm not sure I understand what that would mean exporting a @RequestScoped bean as an OSGi service.
 

The problem then becomes having a mechanism to enforce that a given scope really only allows binding prototype scoped osgi services, but I think this is not a real issue. It sounds reasonable that people would not redefine a singleton, or application scope, and in that respect we could simply assume that if the scope is not explicitly declared as:

Singleton
ApplicationScoped
BundleScoped (osgi cdi spec)
SingletonScoped (osgi cdi spec?? not really sure we need to redefine this) 

that we automatically assume they should require prototype scoped services in order to satisfy the fact that the scope needs to create and destroy instances at it's own leisure.

😕😲🙄 Hopefully that made some kind of sense!!!

I'm not sure that we have to think about exposing OSGi services the way you do.  I don't see the use case for choosing any CDI bean from an existing application and exposing is over OSGi.  Services are usually well defined interfaces so there is a decision to expose a service in the OSGi registry.  So I'm fine with using custom annotations if needed.
Also, I'm not sure what you describe accomodates with the exposed bean lifecycle having to be tied to its dependencies as I advocate.

So basically I'm fine with the 3 scopes defined in the RFC when exposing beans OSGi services:
  * BundleScoped
  * PrototypeScoped
  * SingletonScoped
We could do some mapping with existing CDI scopes if needed.
But my main concern is certainly not that one.  

My concern is about the lifecycle when you inject services from the OSGi registry into a CDI bean, not exporting services.
 As I indicated in my first email, my concern is about handling OSGi dynamics, not exporting OSGi services which is the easy part, and not about CDI extensions, which I fully agree we need to support.

What I'd like is a real injection framework that we can point OSGi users to.
Blueprint has some deficiencies ; the service damping mechanism is a pain to deal with and also a pain to work around.
DS is very good at handling OSGi dynamics : it supports a great range of use cases and the defaults makes users life easy.  The problem with DS is that it's limited to wiring OSGi services together, it's not pluggable, and can't do anything else.

If I'm understanding things right:
  * if you inject an OSGI service into a bean, the while container lifecycle will be tied to the availability of that bean
  * if you use an optional dependency, a null proxy is injected
That's basically the only 2 scenarios supported by the RFC for injecting services.

My proposal supports:
  * mandatory / optional 
  * greedy / reluctant
  * static / dynamic
  * local / global
Those should not deviate from the fact that a bean will never change during it's lifecycle.  The way to implement that is to make the bean lifecycle boundary defined by the availability of its dependencies.    It means beans injected with OSGi services have to be in a custom CDI scope so that its lifecycle can be managed.  So whenever the dependencies of a CDI bean injected with OSGi services change in a way that the bean needs to be re-injected, we destroy the bean correctly and re-create it with the new dependencies.  IT supports the mandatory / optional and greedy / reluctant DS semantics.
We also have the use case where you have a bean, but you don't want the lifecycle to be modified and you want a proxy to be injected to use service damping.  It's not the default, but it can be supported.  That's the static / dynamic semantic.
There are some use cases where you don't want to change the scope.  For those use cases, the injection point needs to be flagged properly so that the whole container lifecycle will be tied to the dependencies. That's the local / global semantic which does not exist in DS.

On the other side, i.e. exposing a service, there is:
  * bundle / service / prototype service scope
  * immediate / delayed 

A bunch of other things that should be supported:
  * injecting configuration using annotations as in DS (configuration can be mandatory / optional, greedy / reluctant) : an annotation defines the injected config with optional default values, as specified in DS 112.8.2
  * injecting Instance<X> for mutiple cardinality injection
  * filtering using generic filters or attributes (attributes can be used also when exposing services and can hide

So yes, I need a custom scope to support the above use cases.  But that makes things actually useful for OSGi developers imho, and not only simple use cases for EE developers porting applications to OSGi.  Supporting all well known DS semantics ensures a complete usability for all known OSGi use cases.  I think if we go this way, we can end up with something really useful for both OSGi beginners and more seasoned OSGi developers.

Guillaume


- Ray



On Wed, Nov 23, 2016 at 12:48 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:40 GMT+01:00 Raymond Auge <[hidden email]>:


On Wed, Nov 23, 2016 at 12:34 PM, Guillaume Nodet <[hidden email]> wrote:


2016-11-23 18:22 GMT+01:00 Raymond Auge <[hidden email]>:
Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept. You need a Provider for those beans and an OSGi prototype scope service is the perfect provider including reclamation and destruction.

Finally, we do want to support existing CDI extensions because that's where a lot of the value is (JSF, JPA, JMS, etc.) and we don't want to change their understanding of the lifecycle of CDI beans otherwise they will break and people won't like it and lose faith that it's useful.

My fear is to over-dynamic-fication of things which are not inherently dynamic and fail to produce something useful.

The point here is that people can still assemble modular apps using peer bundles containing extensions, beans, osgi services in as complex or simple a constellation as they need and everything needs very little change; that adding and removing bundles from this constellation will behave as expected in a dynamic environment. In fact existing things should largely work with only slight metadata changes including; extensions and support for OSGi services in existing code work without any code changes.

Lastly, CDI is fundamentally the same as spring in that when the "container" is declared to be done... it's done! It's like you've exited the constructor of an object. It's effectively a static singleton and that behaviour is expected by pretty much everything that uses it. Invariants introduced after the fact such as trying to shoehorn dynamicity on individual beans I believe will simply break peoples understanding and will cause OSGi's impl to diverge too far away from future CDI work, which I feel is WAY too important to risk since CDI is being introduced on other non-Java EE specifications and will soon touch the JRE.

Are you basically taking @RequestScoped and @SessionScoped out of the CDI spec ? Or implying those scopes do not work well with JPA, JMS, JSF etc... ?  
Or is there something I'm not understanding in CDI ?

Hmm, I'm not sure how that got inferred by what I said. What I said was literally:

>Actually, we have a perfect solution in OSGi for the scenario of intermittent scopes like web requests, session scope, etc. That is prototype scope! This is already suggested by the requirements and works very well with the scoped bean concept.

And you're ruling out the existence of other scopes or that the spec supports custom scopes.  The prototype scope is the default scope, it does not mean it's the only one. @RequestScope and @SessionScope do handle dynamics very well : the beans are not created until a request or session exist and is destroyed when the request / session is destroyed : if that's not dynamic, I'm not sure what it is.
That's what I'm proposing : having the ability to use a custom scope to support more OSGi dynamics.  
My solution has both a global lifecycle suited to porting JEE applications (where the whole container lifecycle is tied to the global set of dependencies) and one custom scope that can handle specific bean lifecycles, so that OSGi users can benefit from a correct support of OSGi dynamism as in DS.
 

Furthermore, JPA, JMS, JSF should be implementable as extensions as they pretty much are in CDI already and why CDI can be used without any of those features available. The use of those features in your applications however infer the requirement on an extension capability providing them which should be available so your application can function. 

I don't see how having extensions is related to scopes and lifecycle.  Supporting extensions is a must-have in CDI.  What you implied is that because you want to support extensions, we can't use custom scopes.  I think I was the one to suggest using generic capabilities to support extension in the RFC years ago.

And to answer your other email, I do not pretend to have a really good knowledge of CDI (really, I don't). I may be missing things in using custom scopes, but I'd like to understand what exactly, if any.
 

Does that make sense?
- Ray
 
 

But this is just my opinion,
- Ray


On Wed, Nov 23, 2016 at 11:38 AM, Christian Schneider <chris@die-schneider.net> wrote:
I think it would be great if Guillaume and Ray could work on the impl together. Ray could then feed the experiences back into the RFC.
In any case I would support having Ray as an aries committer.

Christian


On 23.11.2016 17:30, David Bosschaert wrote:
Hi Guillaume,

My understanding is that the technical design of the RFC will be significantly changed to better support the OSGi dynamics - hopefully we'll see an update soon at https://github.com/osgi/design/tree/master/rfcs/rfc0193

If I understand things correctly then Ray's CDI implementation will support the improved design.

Cheers,

David

-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





-- 
Raymond Augé (@rotty3000)
Senior Software Architect Liferay, Inc. (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance (@OSGiAlliance)



-- 
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
Thanks
Emily
=================
Emily Jiang
[hidden email]


--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration






--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration





--
------------------------
Guillaume Nodet
------------------------
Red Hat, Open Source Integration


12