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.
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.
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(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/seam-dev