[seam-dev] Postconstruct issue when registering a Bean in an extension
Antoine Sabot-Durand
antoine at sabot-durand.net
Tue Aug 2 09:21:02 EDT 2011
Thanks to your remark I resolved the issue by having only one Postconstruct in my hierarchy. I do a chained call for the ancestor initialization.
I'll give a try to Generic Beans, but I'll need a bit of refactoring before using them.
Thanks,
Antoine SABOT-DURAND
Le 2 août 2011 à 14:27, Antoine Sabot-Durand a écrit :
> Hi Pete,
> Le 2 août 2011 à 12:43, Pete Muir a écrit :
>
>>
>> On 2 Aug 2011, at 10:05, Antoine Sabot-Durand wrote:
>>
>>> Hi All,
>>>
>>> In Seam Social, in order to support polymorphism I need the service beans to be qualified with the name of the service. For instance :
>>>
>>> @RelatedTo("LinkedIn")
>>> public class LinkedInJackson extends OAuthServiceBase implements LinkedIn
>>>
>>> It allows users to inject a service bean like that
>>>
>>> @Inject @RelatedTo("LinkedIn")
>>> OAuthService service;
>>>
>>> As I want to ease user life I also need to support this kind of injection (same results as above)
>>>
>>> @Inject
>>> LinkedIn service;
>>
>> Have you considered using generic beans for this? It seems like a good fit.
>>
>
> I'm not sure to completely understand Generic Beans, but I'll dig in them
>
>
>>>
>>> As LinkedIn interface has only one implementation, using a qualifier when I use its specific type is useless and could be confusing.
>>>
>>> Until now I registered the second version of the bean (without a qualifier) thru a producer, but as each service bean will have both registration (with and without qualifier) I decided to simplify this bi-registration with an extension (it will also ease the writing of new service bean for third party developers).
>>>
>>> My extension works in 2 steps :
>>> First it collects in a Map all the annotated type which are OAuthService children and have a @RelatedTo qualifier :
>>>
>>> public void processServicesBeans(@Observes ProcessManagedBean<OAuthService> pbean) {
>>> Annotated annotated = pbean.getAnnotated();
>>> if (annotated.isAnnotationPresent(RelatedTo.class)) {
>>> RelatedTo related = annotated.getAnnotation(RelatedTo.class);
>>> String name = related.value();
>>> servicesBean.put(name, pbean.getAnnotatedBeanClass());
>>> }
>>> }
>>>
>>> Then, after the bean discovery, it register a new version of each Qualified bean without the qualifier (thanks to solder !).
>>>
>>> public void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) {
>>> for (String type : servicesBean.keySet()) {
>>> AnnotatedType<? extends OAuthService> annotatedType = servicesBean.get(type);
>>> AnnotatedTypeBuilder annoBuilder = new AnnotatedTypeBuilder().readFromType(annotatedType).removeFromClass(
>>> RelatedTo.class);
>>> AnnotatedType myAnnotatedType = annoBuilder.create();
>>> BeanBuilder beanBuilder = new BeanBuilder(bm).readFromType(myAnnotatedType);
>>> abd.addBean(beanBuilder.create());
>>> }
>>> }
>>>
>>> This seems to work quite well except that my service Beans have a @Postconstruct method and at initialization Weld throws the following exception
>>>
>>> org.jboss.weld.exceptions.DefinitionException: WELD-000805 Cannot have more than one post construct method annotated with @PostConstruct for public class org.jboss.seam.social.linkedin.LinkedInJackson
>>
>> I don't think we have enough information about the classes involved to be able to comment much on this scenario? Are there really two @PostConstruct methods? I would guess that what happens is that Solder is somehow collapsing multiple levels of classes into one or something.
>
> Yes there are Postconstructs in ancestors of the class and you're right Solder seems to collapse them. So I'll try to create my bean without solder :-(... if the generic bean don't fit my needs.
>
> Thanks for your quick answer.
>
>>
>>>
>>>
>>> If I remove the @Postconstuct in the AnnotatedTypeBuilder by changing its declaration by :
>>>
>>> AnnotatedTypeBuilder annoBuilder = new AnnotatedTypeBuilder().readFromType(annotatedType).removeFromClass(
>>> RelatedTo.class).removeFromAll(PostConstruct.class);
>>>
>>> Initialization works, I have my 2 beans, but the one I registered without qualifier won't execute the @PostConstruct method (since I had to remove it). I guess I'm missing something in the CDI meta-meta-maze :-). Any help or suggestion would be nice.
>>>
>>> Thanks,
>>>
>>> Antoine SABOT-DURAND
>>> _______________________________________________
>>> seam-dev mailing list
>>> seam-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/seam-dev
>>
>
More information about the seam-dev
mailing list