0 Replies Latest reply on Jan 19, 2012 12:13 PM by Eduardo Lopes

    Beans loaded through CDI extensions sometimes not available

    Eduardo  Lopes Newbie

      Hello,


      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>