Beans loaded through CDI extensions sometimes not available
eduardocl Jan 19, 2012 12:13 PMHello,
I'm trying to load some beans through a CDI extension, and such beans come from jar files. Sometimes they are available on JSF pages. But, if I reboot jboss (version 6.1) the beans are not available anymore, and I pretty sure that the extension load correctly the bean classes whenever the CDI container initializes. I wrote the CDI extension according to the example available at: http://in.relation.to/Bloggers/AnotherNicePortableExtension
Can anyone tell what I'm missing here?
Below, I list the code:
MyExtension
List<Class<?>> getBeanClasses() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { PluginLoader loader = new PluginLoader(); PluginPathResolver resolver = new WebPathResolver(); File file = new File(resolver.getPluginRepository(). concat("sequi.plugins.projectlog-0.0.1-SNAPSHOT.jar")); PluginBundle bundle = loader.load(file); loader.installView(file, resolver, bundle.getName()); return bundle.getManagedBeans(); } void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { System.out.println("---------- loading the beans -------------"); if(getBeanClasses() == null){ System.out.println("no classes to load."); return; } for ( final Class c: getBeanClasses() ) { //use this to read annotations of the class AnnotatedType at = bm.createAnnotatedType(c); //use this to create the class and inject dependencies final InjectionTarget it = bm.createInjectionTarget(at); abd.addBean( new Bean() { @Override public Class<?> getBeanClass() { return c; } @Override public Set<InjectionPoint> getInjectionPoints() { return it.getInjectionPoints(); } @Override public String getName() { //hardcoded beacause I'll load a known class //for testing the approach return "myDateUtils"; } @Override public Set<Annotation> getQualifiers() { Set<Annotation> qualifiers = new HashSet<Annotation>(); qualifiers.add( new AnnotationLiteral<Default>() {} ); qualifiers.add( new AnnotationLiteral<Any>() {} ); return qualifiers; } @Override public Class<? extends Annotation> getScope() { //return Dependent.class; return SessionScoped.class; } @Override public Set<Class<? extends Annotation>> getStereotypes() { return Collections.emptySet(); } @Override public Set<Type> getTypes() { Set<Type> types = new HashSet<Type>(); types.add(c); types.add(Object.class); return types; } @Override public boolean isAlternative() { return false; } @Override public boolean isNullable() { return false; } @Override public Object create(CreationalContext ctx) { Object instance = it.produce(ctx); it.inject(instance, ctx); it.postConstruct(instance); return instance; } @Override public void destroy(Object instance, CreationalContext ctx) { it.preDestroy(instance); it.dispose(instance); ctx.release(); } } ); } }
Class that should be dynamically load into CDI:
@Named("myDateUtils") public class DateUtils { public String getToday(){ <...> return the date formatted string.. } @PostConstruct public void showMessage(){ System.out.println("Class post construct method!") } }
Simple facelets page using the bean:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" .... .../> <h1>Adicionar diário</h1> <h:outputText value="new.xhtml" /><br/> <h:outputText value="#{myDateUtils.today}"/> </html>