1 2 Previous Next 28 Replies Latest reply on Mar 2, 2011 3:28 AM by ssachtleben.ssachtleben.gmail.com

    Injection not working in face converter

    yangju.richard.yang.pearson.com
      According to Seam 3 faces documentation, you can inject a managed bean into face converter. However, I tried seam faces 3.0.0.Beta2, the injected object is null. Here is the converter:



      `

      @SessionScoped
      @FacesConverter("convert.TestAdmin")
      public class TestAdminConverter implements Converter, Serializable {

          @Inject
          private List<TestAdmin> admins;

          @Override
          public Object getAsObject(FacesContext context, UIComponent component, String value) {
              Long id = Long.valueOf(value);
              for (TestAdmin admin : admins) {
                  if (admin.getId().longValue() == id.longValue()) {
                      return admin;
                  }
              }
              return null;
          }

          @Override
          public String getAsString(FacesContext context, UIComponent component, Object value) {
              return ((TestAdmin) value).getId().toString();
          }
      `


      The injected List<TestAdmin> admins is produced by application scoped producer and does exist.
      Is this a bug?

        • 1. Re: Injection not working in face converter
          yangju.richard.yang.pearson.com

          BTY, I am using jboss 6 final.

          • 2. Re: Injection not working in face converter
            bleathem

            That indeed is unexpected behaviour.  Can you confirm your @Inject works in a class other than the converter?  For instance in one of you JSF backing beans?

            • 3. Re: Injection not working in face converter
              yangju.richard.yang.pearson.com

              Yes, the injection of the producer's output works in other weld managed beans.

              • 4. Re: Injection not working in face converter
                ssachtleben.ssachtleben.gmail.com

                Its definitly not a global injection bug for converters. Here is a working example which runs fine on my webapp. The list contains 10 items. Everthing is fine!!!


                @RequestScoped
                @FacesConverter(forClass = Inseration.class)
                public class InserationConverter implements Converter {
                     
                     @Inject @StaticData List<Inseration> inserations;
                     
                     public Object getAsObject(FacesContext context, UIComponent component, String newValue) {
                          for (Inseration inseration : inserations) {
                               if (Long.toString(inseration.getId()).equals(newValue)) {
                                    return inseration;
                               }
                          }
                          return null;
                     }
                
                     public String getAsString(FacesContext context, UIComponent component, Object value) {
                          String name = "";
                          try {
                               Inseration inseration = (Inseration) value;
                               name = Long.toString(inseration.getId());
                          } catch (Throwable e) {
                          }          
                          return name;
                     }
                
                }



                @ApplicationScoped
                public class StaticDataProducer implements Serializable {
                
                     private Logger log = Logger.getLogger(StaticDataProducer.class);
                     
                     @Inject StaticDataService service;
                      
                     @Produces @StaticData List<Inseration> inserations;
                     
                     ///////// METHODS /////////
                     
                  public void onStartup(@Observes @Started WebApplication webapp) {
                       log.info("onStartup()");
                       long start = System.currentTimeMillis();
                       try {
                            loadStartupValues();
                          } catch (Exception e) {
                               log.error("Exception occured:", e);
                          }
                       log.info("Static data preload completed in " + (System.currentTimeMillis() - start) + " ms");
                  }
                  
                  public void observeCreatedInseration(@Observes InserationCreatedEvent event) {
                       inserations.add(event.getInseration());
                  }
                  
                  public void observeRemovedInseration(@Observes InserationRemovedEvent event) {
                       inserations.remove(event.getInseration());
                  }
                  
                  private void loadStartupValues() throws Exception {
                       inserations = service.getInserations();
                  }
                     
                }



                public class StaticDataService {
                
                     Logger log = Logger.getLogger(StaticDataService.class);
                     
                     @PersistenceContext EntityManager em;
                     
                     ///////// METHODS /////////
                     
                  public List<Inseration> getInserations() {
                       CriteriaBuilder builder = em.getCriteriaBuilder();
                          CriteriaQuery<Inseration> inserationQuery = builder.createQuery(Inseration.class);
                          Root<Inseration> inserationMetaModel = inserationQuery.from(Inseration.class);
                          inserationQuery.select(inserationMetaModel).orderBy(builder.asc(inserationMetaModel.get("id")));
                          return em.createQuery(inserationQuery).getResultList();            
                  }     
                }



                @Qualifier
                @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
                @Retention(RetentionPolicy.RUNTIME)
                public @interface StaticData { }





                • 5. Re: Injection not working in face converter
                  yangju.richard.yang.pearson.com

                  I made my code almost identical to yours, but yet everything I injected to the converter is null. What version of seam 3 faces you are running? How about posting your xhtml file?


                  Here is my converter code:



                  package com.pearson.epen.managedBean.converter;
                  
                  import java.io.Serializable;
                  import java.util.List;
                  
                  import javax.enterprise.context.SessionScoped;
                  import javax.faces.component.UIComponent;
                  import javax.faces.context.FacesContext;
                  import javax.faces.convert.Converter;
                  import javax.faces.convert.FacesConverter;
                  import javax.inject.Inject;
                  
                  import org.slf4j.Logger;
                  
                  import com.pearson.epen.account.model.api.TestAdmin;
                  import com.pearson.epen.cdi.qualifier.StaticData;
                  
                  @SessionScoped
                  @FacesConverter(forClass = TestAdmin.class)
                  public class TestAdminConverter implements Converter, Serializable {
                  
                      private static final long serialVersionUID = 5629350597308157422L;
                      @Inject
                      private @StaticData
                      List<TestAdmin> admins;
                  
                      @Inject
                      private Logger log;
                  
                      @Override
                      public Object getAsObject(FacesContext context, UIComponent component, String value) {
                          try {
                              Long id = Long.valueOf(value);
                              for (TestAdmin admin : admins) {
                                  if (admin.getId().longValue() == id.longValue()) {
                                      return admin;
                                  }
                              }
                  
                          } catch (Throwable t) {
                              log.error("got exception", t);
                          }
                  
                          return null;
                      }
                  
                      @Override
                      public String getAsString(FacesContext context, UIComponent component, Object value) {
                          TestAdmin testAdmin = (TestAdmin) value;
                          return Long.toString(testAdmin.getId());
                  
                      }
                  
                  }
                  



                  Producer:



                  package com.pearson.epen.cdi.producer;
                  
                  import java.util.List;
                  
                  import javax.ejb.Startup;
                  import javax.enterprise.context.ApplicationScoped;
                  import javax.enterprise.inject.Produces;
                  import javax.inject.Inject;
                  import javax.inject.Named;
                  import javax.persistence.EntityManager;
                  import javax.persistence.Query;
                  
                  import com.pearson.epen.account.model.api.TestAdmin;
                  import com.pearson.epen.cdi.qualifier.CentralRepo;
                  import com.pearson.epen.cdi.qualifier.StaticData;
                  
                  @ApplicationScoped
                  @Startup
                  public class TestAdminProducer {
                  
                      @Inject
                      @CentralRepo
                      EntityManager centralEm;
                  
                      @Produces
                      @ApplicationScoped
                      @StaticData
                      @Named("testAdmins")
                      List<TestAdmin> getAllAdmins() {
                          return findAllAdmins();
                      }
                  
                      @SuppressWarnings("unchecked")
                      private List<TestAdmin> findAllAdmins() {
                          String queryString = "from TestAdminImpl a where a.active=1";
                          Query query = centralEm.createQuery(queryString);
                          //query.setHint("org.hibernate.cacheable", true);
                          return (List<TestAdmin>) query.getResultList();
                      }
                  
                  }
                  



                  view file;



                  <?xml version="1.0" encoding="UTF-8"?>
                  <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                       xmlns:ui="http://java.sun.com/jsf/facelets"
                       xmlns:f="http://java.sun.com/jsf/core"
                       xmlns:h="http://java.sun.com/jsf/html"
                       xmlns:p="http://primefaces.prime.com.tr/ui"
                       xmlns:a4j="http://richfaces.org/a4j"
                       xmlns:rich="http://richfaces.org/rich"
                       template="/WEB-INF/templates/template.xhtml">
                       <ui:define name="content">
                  
                            <h1>Common Item Search</h1>
                            <h:form id="common_item_search">
                                 
                                 <h:panelGrid>
                                      <h:outputText value="Hello" />
                                      <h:selectOneMenu value="#{commonItemSearch.selectedTestAdmin}"
                                           id="selector_testAdmin">
                                           <f:selectItems value="#{commonItemSearch.testAdmins}"
                                                id="id_admins" var="admin" itemLabel="#{admin.name}" />
                                           <f:ajax event="valueChange" execute="@form"
                                                listener="#{commonItemSearch.adminSelected}"></f:ajax>
                                      </h:selectOneMenu>
                  
                                 </h:panelGrid>
                  
                            </h:form>
                  
                  
                  
                  
                  
                       </ui:define>
                  </ui:composition>







                  • 6. Re: Injection not working in face converter
                    yangju.richard.yang.pearson.com

                    Even the Logger I injected to the converter is null, which tells me that some config, not my code, is wrong.

                    • 7. Re: Injection not working in face converter
                      ssachtleben.ssachtleben.gmail.com

                      Really strange. Did you try @RequestScoped instead of @SessionScoped?


                      Cant see any mistake in your code...

                      • 8. Re: Injection not working in face converter
                        asiandub

                        To ask the obvious:


                        Are you 1000% sure that bean.xml is at its place and that everything is correctly recognized as ManagedBean?


                        You can also query the BeanManager in order to see which ManagedBeans are provided. I doubt that TestAdminConverter is among those ;-)


                        Cheers,
                        Jan


                        • 9. Re: Injection not working in face converter
                          yangju.richard.yang.pearson.com

                          Requestscoped is tried and did not work either. I just checked, the beans.xml is in my jar's meta-inf folder. I have a war and there are a few jars (our own libraries) in the web-inf lib. I put this converter in one of the jar, as this converter needs to be shared by several web applications. Maybe this is my problem? Maybe I have to move the converter to the war's web-inf's classes dir?


                          I have seam 3 security, faces, internationalization, persistence and solder modules jars in each of the wars. Maybe they don't work with each other?


                          What version of faces module is yours?


                          The thing that bothers me is that if the injection fails, why did not jboss throw an exception?


                          I wonder if I can use EL to refer to the bean (as my static data is marked as @Named) in java code? Do you know how?

                          • 10. Re: Injection not working in face converter
                            yangju.richard.yang.pearson.com

                            Sebastian:


                            Could you upload your whole war so that I can take a look what jars are on your lib?


                            Thanks.

                            • 11. Re: Injection not working in face converter
                              ssachtleben.ssachtleben.gmail.com

                              Try to put the converter to web-inf classes at least my converter is there. Not sure about using that @Produces values on lib jars seems like it doesnt work.


                              Sorry I cant provide war file just using it in a full project.

                              • 12. Re: Injection not working in face converter
                                yangju.richard.yang.pearson.com

                                I moved the converter put into the war's classes, and it does not work.
                                I even tried to inject seam's own component like @Inject
                                    ExternalContext externalContext; it is null.
                                Also, I notice that the @PostConstruct of my converter is not invoked at all, this tells me that it could be a bug triggered by the interactions among several seam 3 modules.


                                What version of seam faces of yours and how many seam modules in your war?


                                Thanks.

                                • 13. Re: Injection not working in face converter
                                  ssachtleben.ssachtleben.gmail.com

                                  It works for me with faces Beta2 and snapshot. Currently I'm using most of them as snapshot until the next release in some days.


                                  But your methods getAsObject and getAsString are called? Did you set up the converter in faces-config?

                                  • 14. Re: Injection not working in face converter
                                    lightguard

                                    You're running on JBoss AS6? You could try jarring up your application classes and putting them in the lib directory and see what happens.

                                    1 2 Previous Next