5 Replies Latest reply on Jan 20, 2014 3:36 PM by csa

    Errai CDI Injection Question

    mprk

      I'm having trouble injecting an object to send new events in a GWT widget.

       

      I started with the Errai tutorial, and have modified to use OpenLayers GWT project. I would have to track certain

      map events, sending them to a backend service for processing.

       

      I used what is the standard example from the CDI documentation.

       

      I using the entire Errai stack, defining the following in my gwt.xml file:

       

      <inherits name="org.jboss.errai.enterprise.All" />
      
      

       

      I have a GWT widget with the following mapChanged variable to send events:

       

      public class MapView extends DockPanel {
      
          @Inject
          Event<MapChangedEvent> mapChanged;
      
          public MapView() {
      
              if ( mapChanged == null ){
                  GWT.log("New: mapchanged is null");
              }
            
           }
      
      }
      
      

      where the GWT.log reports that mapChanged is null.

       

      This is trying to communicate with a server side entity, defined like the following:

       

      @ApplicationScoped
      public class MapModelService {
      
          private static Logger log = LoggerFactory.getLogger(MapModelService.class);
        
          public void userChangedMapView( @Observes MapChangedEvent event ){
              log.info("User Changed Map VIew: Event recieved " + event.getEventType() );
          }
        
      }
      
      

       

      with the following event object to transfer the data:

       

      @Portable
      public class MapChangedEvent {
      
          public MapChangedEvent(){
            
          }
      
      }
      
      

       

      I'm not sure why mapChanged continues to be null at startup.

       

      TIA,

       

      Matt

        • 1. Re: Errai CDI Injection Question
          jfuerth

          Hi Matt,

           

          CDI initializes objects in three phases (this is true on the server as well as in Errai's CDI implementation):

          1. Object is created via constructor invocation (the @Inject constructor if there is one; otherwise the no-args constructor)
          2. @Inject fields are populated
          3. @Inject setter methods are called (in no guaranteed order)

           

          So you will always observe @Inject fields as null from the object's constructor.

           

          Try moving your logging statement to a @PostConstruct method, and you should see a non-null Event object in the mapChanged field. PostConstruct methods are guaranteed to be called after all three phases of injection have completed.

           

          -Jonathan

          • 2. Re: Errai CDI Injection Question
            csa

            Hi Matt,

             

            You also need to make sure that MapView is itself a managed bean (i.e. by annotating it with @ApplicationScoped or @Dependent) and that you retrieve an instance of it using the bean manager (as opposed to just calling new MapView()).

             

            You can get a managed instance of MapView either by having it injected into another bean or by using the client-side bean manager for programmatic look-up:

            Client-Side Bean Manager - Errai - Project Documentation Editor

             

            Cheers,

            Christian

            • 3. Re: Errai CDI Injection Question
              mprk

              Jonathan - Tried your suggestion and created a PostConstruct method to check the object. The PostConstruct method was never called.

               

              Christian - Your suggestion fixed the issue.

               

              Thanks each of you for the help!

              • 4. Re: Errai CDI Injection Question
                mprk

                Should the @AfterInitialization annotation work with a bean tagged as @Dependent?

                 

                I have one, and it won't trigger the method.

                • 5. Re: Errai CDI Injection Question
                  csa

                  Yes, it will if your @Dependent bean is injected into another @ApplicationScoped/@Singleton bean or @EntryPoint. Otherwise there will likely not be an instance around when the bus has finished initializing and Errai doesn't create new instances of @Dependent scoped beans to handle events.