11 Replies Latest reply on Aug 20, 2009 5:16 PM by Arbi Sookazian

    problem injecting JavaBean into another JavaBean

    Arbi Sookazian Master

      I have two Seam components, both JavaBeans, both conversation-scoped.


      When I inject as follows in one of them:


      @In(required=false) 
      private EquipmentProcessingAction equipmentProcessing;



      I get:



      Caused by: java.lang.IllegalArgumentException: value of context variable is not an instance of the component bound to the context variable: equipmentProcessing

      What does this mean exactly and how to fix?


      The EquipmentProcessingAction instance should be available (i.e. not null) at injection time.


      Here's some code:


      @Name("equipmentProcessingView")
      @Scope(ScopeType.CONVERSATION)
      @Transactional
      public class EquipmentProcessingViewAction implements Serializable {
                
           private static final long serialVersionUID = 6236269337814791874L;
      
           @In     
           private EntityManager entityManager;
           
           @In(required=false) 
           private EquipmentProcessingAction equipmentProcessing;
      ...
      }



      @Name("equipmentProcessing")
      @Scope(ScopeType.CONVERSATION)
      @Transactional
      public class EquipmentProcessingAction {...}

        • 1. Re: problem injecting JavaBean into another JavaBean
          Arbi Sookazian Master

          And now that I'm looking at the source for org.jboss.seam.Component, it seems a little bloated at 2600+ lines, no?


          Wasn't (isn't) there a bloated session bean anti-pattern that is basically applicable in this context as well?


          In any event, here is the method of interest:


          private static Object getInstance(String name, boolean create, Object result) {
                Component component = Component.forName(name);
          
                create = create || Init.instance().isAutocreateVariable(name);
          
                if (result==null && create)
                {
                  result = getInstanceFromFactory(name);
                  if (result==null)
                  {
                     if (component==null)
                     {
                        //needed when this method is called by JSF
                        if ( log.isDebugEnabled() ) log.debug("seam component not found: " + name);
                     }
                     else if ( component.getScope().isContextActive() )
                     {
                        result = component.newInstance();
                     }
                  }
                }
          
                if (result!=null)
                {
                   if (component!=null)
                   {
                      if ( !component.isInstance(result) )
                      {
                         if ( component.hasUnwrapMethod() ) return result; ///best way???
                         throw new IllegalArgumentException( "value of context variable is not an instance of the component bound to the context variable: " + name );
                      }
                      result = component.unwrap(result);
                   }
                }
          
                return result;
          
             }



          so in my case, does the exception indicate that equipmentProcessing, which is the @Name of the Seam component, is not an instance of this class: EquipmentProcessingAction ?  And if yes, why?  There is no typo in the injection code AFAIK.


          I've never had that problem before with EJB injection using @In but you use the local interface instead of the class name to inject, so it's a little different...

          • 2. Re: problem injecting JavaBean into another JavaBean
            Arbi Sookazian Master

            Out of curiosity, I tried the following and it works (no more excpetion!):


            @Name("equipmentProcessing")
            @Scope(ScopeType.CONVERSATION)
            @Transactional
            public class EquipmentProcessingAction {
                 
                 //testing
                 @In(required=false) 
                 private EquipmentProcessingViewAction equipmentProcessingView;
                 //end
            ...
            }



            So why does that work?  Do you really need to inject each JavaBean into each other?  It's weird b/c the above reference will never be used b/c it's not needed in this component...

            • 3. Re: problem injecting JavaBean into another JavaBean
              Arbi Sookazian Master

              it's back:



              value of context variable is not an instance of the component bound to the context variable: equipmentProcessingView
              • 4. Re: problem injecting JavaBean into another JavaBean
                Arbi Sookazian Master

                well it seems ok now:


                @In(value="equipmentProcessing", required=false) 
                private EquipmentProcessingAction equipmentProcessing;



                but I don't see how adding an explicit value changes anything as I always thought it defaults to the instance variable name...


                this is fun!

                • 5. Re: problem injecting JavaBean into another JavaBean
                  Arbi Sookazian Master

                  Now this:


                  09:39:02,676 WARN  [Component] Exception calling component @Destroy method: equipmentProcessing
                  java.lang.IllegalArgumentException: value of context variable is not an instance of the component bound to the context variable: equipmentProcessingView



                  Btw, I know that SFSB requires a @Remove method but what are the rules with conversation-scoped JavaBean components?  Is the @Destroy optional?

                  • 6. Re: problem injecting JavaBean into another JavaBean
                    Arbi Sookazian Master

                    Should I simply outject only the variables I need to the conversation context and then inject those variables instead of injecting the entire JavaBean?


                    I was trying to avoid the excessive oujtection that was un-recommending recently on this forum.  Plus, it's easier to inject one instance than multiple instances, no?

                    • 7. Re: problem injecting JavaBean into another JavaBean
                      Arbi Sookazian Master

                      Got it again:


                      Caused by: java.lang.IllegalArgumentException: value of context variable is not an instance of the component bound to the context variable: equipmentProcessingView



                      I am using incremental hot deployment (src/action --> WEB-INF/dev) of JavaBeans in this app so this seems to reproduce after I run 'ant explode'.  Seam 2.0.2-FP.  Not happening consistently apparently.


                      Is this a known issue/bug?

                      • 8. Re: problem injecting JavaBean into another JavaBean
                        Stuart Douglas Master

                        This is caused by hot deployment. The classes you get after you redeploy are differenet to the ones you had before as the classloader is different. If you have an old version of a class sitting around in a context you will not be able to inject it. Or something like that.

                        • 9. Re: problem injecting JavaBean into another JavaBean
                          Arbi Sookazian Master

                          Stuart Douglas wrote on Aug 19, 2009 23:46:


                          This is caused by hot deployment. The classes you get after you redeploy are differenet to the ones you had before as the classloader is different. If you have an old version of a class sitting around in a context you will not be able to inject it. Or something like that.


                          So what is the recommended course of action here?  I already had to move a DTO class out of the src/action folder b/c Hibernate could not see it (classpath/classloader issue as well).

                          • 10. Re: problem injecting JavaBean into another JavaBean
                            Stuart Douglas Master

                            If you log out and log back in that should fix most of the issues, unless you are trying to hot deploy application scoped components.

                            • 11. Re: problem injecting JavaBean into another JavaBean
                              Arbi Sookazian Master

                              Stuart Douglas wrote on Aug 20, 2009 01:23:


                              If you log out and log back in that should fix most of the issues, unless you are trying to hot deploy application scoped components.


                              By log out and log back in do you mean either click a logout link and manually login or in our case, since we're using NTLM silent auth, start a new session?  I am not hot deploying application-scoped components, they are either converation- or session-scoped.