[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