[cdi-dev] CDI EG requires feedback

Mark Struberg struberg at yahoo.de
Wed Aug 15 12:26:44 EDT 2012


Hi Stu!

> I think that this is actually a feature, and a feature that 

> Seam XML relied on. If this becomes spec ...

Well, I guess there are 2 stories. 


a.) Although a good approach, SeamXML is not 100% portable. One of the portability issues comes from having to do a lot of workarounds because the spec is not exactly clear whether an AnnotatedType added via BeforeBeanDiscovery#addAnnoatatedType() should replace the existing AnnotatedType for that type or if it shall be treated as new one. Containers did that different, and some of the functionality you mention work only with Weld. So there is no spec backward compat problem - because there never was spec compatibility with this handling ;)

b.) If you are talking about 'other Extensions cannot modify it', well, then what are the real use cases? Imo it's absolutely clear that there might be people that like to achieve exactly that: If I explicitly define my 'annotations' via XML, then I don't like any Extension changing them wildly again - otherwise I can just add it to my XML as well. Those are 2 flavours and both are valid.


Let's sum up the main problem which we face spec wise. There are quite a few distinct use cases:

1.) _enabling_ CDI handling for classes which are not in a BDA (bean archive = jar with beans.xml)

2.) _modifying_ CDI behaviour for classes which are in a BDA, _without_ adding a new AnnotatedType in addition
3.) adding an _additional_ AnnotatedType for a class which is in a BDA. The original bean will not get changed and still be available for injection.

For all 3 cases you additionally need to distinguish whether you like to get your XML/whatever configured beans additionally sent through the extension chain or whether it shall be treated as 'final' bean configuration.


With the new handling (1:1mapping between class and AnnotatedType) you would just loose the 3rd point. And this was actually completely undefined behaviour anyway. This _never_ worked on anything else than a few selected (not even all) Weld versions.

Thus people would be perfectly able to implement the use case you explained in your post. It would just require a slightly different handling to actually get n different Beans serving the same type. But we faced this problem already in DeltaSpike and you can perfectly implement this with the WrappingBeanBuilder (that's the stuff which was called 'NarrowingBeanBuilder' in Seam3).

LieGrue,
strub


----- Original Message -----
> From: Stuart Douglas <sdouglas at redhat.com>
> To: deltaspike-dev at incubator.apache.org
> Cc: cdi-dev <cdi-dev at lists.jboss.org>
> Sent: Wednesday, August 15, 2012 5:23 PM
> Subject: Re: CDI EG requires feedback
> 
> 
> On 16/08/2012, at 12:41 AM, Pete Muir <pmuir at redhat.com> wrote:
> 
>> 
>>  On 15 Aug 2012, at 15:30, Stuart Douglas wrote:
>> 
>>> 
>>>  On 15/08/2012, at 11:20 PM, Pete Muir <pmuir at redhat.com> wrote:
>>> 
>>>>  All, the CDI EG requires feedback on an item in the spec which is 
> not clear, and has been implemented differently between implementations, and is 
> not TCK tested. As Deltaspike contains lots of extensions authors, requesting 
> feedback. Please either send direct to me, or post to cdi-dev at lists.jboss.org 
> :-)
>>>> 
>>>> 
> ------------------------------------------------------------------------------------------------------------------------------------------------
>>>> 
>>>>  Multiple Annotated Types
>>>>  ====================
>>>> 
>>>>  https://issues.jboss.org/browse/CDI-58
>>>> 
>>>>  This concerns whether there can be greater than one annotated type 
> per class instance in the JVM. Gavin intended there should be, principally to 
> support an XML configuration dialect, which could introduce multiple versions of 
> a class, each with a different qualifier. However, this is not TCK tested, and 
> implementations vary in how they support this. 
>>>> 
>>>>  We discussed that this makes an implementation considerably more 
> complex (as there is no easy way to uniquely identify an annotated type e.g. for 
> serialization), and also is pretty confusing for a user (as you now get multiple 
> ProcessAnnotatedType events for each class, making it hard to know which one you 
> want to change).
>>>> 
>>>>  We looked at alternative solutions, and concluded that if all use 
> cases can be satisfied by adding a new bean, rather than a new annotated type, 
> we would like to explicitly specify that there is only one annotated type per 
> class instance. In CDI 1.1 it is already much easier to add and manipulate beans 
> from annotated types, so we believe that the correct thing here is take this 
> route.
>>>> 
>>> 
>>> 
>>>  I think there are some issues here. In order to get consistent 
> behaviour the XML extension relied upon PAT being fired for every class it 
> defined, so other extension could then modify the annotated type in a consistent 
> manner.
>> 
>>  IOW this would prevent XML defined class from then being modified by 
> another extension.
> 
> Yes, which is very non-intutive considering the way the existing XML syntax. I 
> know is is not a standard, but it has seen wide adoption, and people expect that 
> applying an annotation via XML is the same as applying it to the class itself.  
> 
>> 
>>> 
>>>  Later on Weld changed its behaviour so that PAT was not fired when 
> annotated types were added through the SPI, in order to work around this I made 
> the XML extension fire PAT for these type itself in order to provide backwards 
> compatibility, which is a horrible hack that is now causing problems for Delta 
> Spike. 
>>> 
>>>  If we make this change to the specification I don't think that it 
> will be possible to implement a viable XML extension. 
>> 
>>  The XML would work but couldn't have it's behaviour changed by 
> other extensions.
> 
> Kind of, but it also becomes a lot more complex to implement, you definitely 
> could not just take the old Seam XML extension and expect it to work. there is 
> not a 1:1 relationship between beans and annotated types, because annotated 
> types can have producer methods. 
> 
> I think that this is actually a feature, and a feature that Seam XML relied on. 
> If this becomes spec I think that a lot of legacy apps will stop working. 
> Sometimes breaking backwards compatibility is necessary, but in this case I 
> don't really see any advantage too it. 
> 
> 
>> 
>>> 
>>>  I am aware that this present challenges for serialisation and 
> clustering, however I worked around this in Weld when I was writing the XML 
> extension by creating a class that creates a deterministic bean id based on the 
> annotations on the class 
> (https://github.com/weld/core/blob/master/impl/src/main/java/org/jboss/weld/util/AnnotatedTypes.java#L185), 
> I wrote this code before I was working for Red Hat an I am quite happy to 
> license it under Apache or any other license. 
>> 
>>  Weld is Apache licensed anyway. I think it's fair to define this 
> approach of creating a type id as "not easy".
> 
> I would consider it a 'solved problem'. AFAIK the same code should work 
> for any CDI impl that needs to generate a deterministic type id.
> 
> Stuart
> 
> 
>> 
>>> 
>>>  Stuart
>>> 
>>> 
>>>> 
> ------------------------------------------------------------------------------------------------------------------------------------------------
>>>> 
>>>>  Does anyone create multiple AnnotatedTypes per class instance? If 
> so, can you please describe:
>>>> 
>>>>  a) why you need to do this
>>>>  b) whether you could reimplement by directly creating beans (given 
> that CDI 1.1 allows you to [1])
>>>>  c) how much effort it would be to reimplement/how much of your 
> codebase this would affect
>>>> 
>>>>  Thanks!
>>>> 
>>>>  Pete
>>>> 
>>>>  [1]
>>>> 
>>>>  BeanAttributes ba = 
> beanManager.cerateBeanAttributes(annotatedType);
>>>>  InjectionTarget it = 
> beanmanager.createInjectionTarget(annotatedType);
>>>>  Bean b = beanManager.createBean(ba, clazz, it);
>>>> 
>>>>  or
>>>> 
>>>>  BeanAttributes ba = 
> beanManager.cerateBeanAttributes(annotatedFieldOrMethod);
>>>>  Producer p = beanmanager.createProducer(annotatedFieldOrMethod);
>>>>  Bean b = beanManager.createBean(ba, clazz, p);
>>>> 
>>>>  The Bean can then be registered using 
>>>> 
>>>>  afterBeanDiscovery.addBean(b);
>>>> 
>>>> 
>>> 
>> 
> 



More information about the cdi-dev mailing list