3 Replies Latest reply on Jul 5, 2006 4:45 PM by c_eric_ray

    Misunderstanding of how @In works.

      I'm doing the following and it's just not working for me. I think I don't quite understand how to use the @In annotation. Any suggestions? I apologize for the long post, but I wanted to show the right amount of information. Thanks.

      Here's the error...

      javax.faces.el.EvaluationException: /calculator.xhtml @42,132 action="#{calculate.calculate}": javax.ejb.EJBException: org.jboss.seam.RequiredException: In attribute requires value for component: calculate.cb

      Code looks like this...

      @Name("calculate")
      @Stateful
      public class CaclulateAction implements Calculate {
      
       @In(create=true)
       private CalculatorBean cb;
      
       @DataModel
       private List<CalculatorBean> cbList;
      
       public String calculate() {
       double tmp = Math.pow(1. + cb.getGrowthRate() / 12., 12. * (cb.getEnd() - cb.getStart()) + 1);
       double result = cb.getSaving() * 12. * (tmp - 1) / cb.getGrowthRate();
      
       cb.setResult(result);
       cbList.add(cb);
      
       return "/calculator.jsf";
       }
      }


      simple bean to hold the data...
      @Name("calculator")
      @Scope(ScopeType.CONVERSATION)
      public class CalculatorBean {
      
      getters/setters
      }


      portion of calculator.xhtml file
      <form id="calcform" name="calcform" method="post" jsfc="h:form">
       <table jsfc="h:panelGrid" width="406" border="1" cellpadding="2">
       <tr>
       <td width="140"><div align="right">Start Age </div></td>
       <td width="250"><input name="startage" type="text" id="startage" size="40" jsfc="h:inputText" value="#{calculator.start}"/></td>
       </tr>
       <tr>
       <td><div align="right">End Age </div></td>
       <td><input name="endage" type="text" id="endage" size="40" jsfc="h:inputText" value="#{calculator.end}" /></td>
       </tr>
       <tr>
       <td><div align="right">Growth Rate </div></td>
       <td><input name="growthrate" type="text" id="growthrate" size="40" jsfc="h:inputText" value="#{calculator.growthRate}" /></td>
       </tr>
       <tr>
       <td><div align="right">Monthly Savings </div></td>
       <td><input name="savings" type="text" id="savings" size="40" jsfc="h:inputText" value="#{calculator.saving}" /></td>
       </tr>
       <tr>
       <td><div align="right"></div></td>
       <td><table width="240" border="1">
       <tr>
       <td><div align="left">
       <input type="submit" jsfc="h:commandButton" id="submit" action="#{calculate.calculate}" name="Submit" value="Submit" />
       </div></td>
       <td><div align="right">
       <input name="reset" jsfc="h:commandButton" action="calculator.jsf" type="reset" id="reset" value="Reset" />
       </div></td>
       </tr>
       </table></td>
       </tr>
       </table>
       </form>

      config files and descriptors...
      --- components.xml ---
      <components>
      
       <component name="org.jboss.seam.core.init">
       <property name="jndiPattern">JsfCalculator/#{ejbName}/local</property>
       </component>
      
       <component class="org.jboss.seam.core.Ejb" installed="false" />
      
      </components>
      
      --- faces-config.xml ---
      <faces-config>
      
       <application>
       <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
       </application>
      
       <!-- Phase listener needed for all Seam applications -->
       <lifecycle>
       <phase-listener>
       org.jboss.seam.jsf.SeamPhaseListener
       </phase-listener>
       </lifecycle>
      
      </faces-config>
      
      
      --- web.xml ---
       <!-- Faces Servlet -->
       <servlet>
       <servlet-name>Faces Servlet</servlet-name>
       <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
       <load-on-startup>1</load-on-startup>
       </servlet>
      
       <!-- Faces Servlet Mappings -->
       <servlet-mapping>
       <servlet-name>Faces Servlet</servlet-name>
       <url-pattern>*.jsf</url-pattern>
       </servlet-mapping>
      
       <!-- Seam -->
      
       <listener>
       <listener-class>
       org.jboss.seam.servlet.SeamListener
       </listener-class>
       </listener>
      
       <!-- MyFaces -->
      
       <listener>
       <listener-class>
       org.apache.myfaces.webapp.StartupServletContextListener
       </listener-class>
       </listener>
      
       <context-param>
       <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
       <param-value>client</param-value>
       </context-param>
      
       <!-- Context Parameters -->
       <context-param>
       <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
       <param-value>.xhtml</param-value>
       </context-param>
      
       <context-param>
       <param-name>facelets.DEVELOPMENT</param-name>
       <param-value>true</param-value>
       </context-param>
      
       <context-param>
       <description>Set this to true for strict JSF RI validation</description>
       <param-name>com.sun.faces.validateXml</param-name>
       <param-value>true</param-value>
       </context-param>
      
       <context-param>
       <description>Set this to true to have JSF RI verify all appliation objects</description>
       <param-name>com.sun.faces.verifyObjects</param-name>
       <param-value>true</param-value>
       </context-param>
      
       <context-param>
       <param-name>javax.faces.application.CONFIG_FILES</param-name>
       <param-value>/WEB-INF/faces-config.xml</param-value>
       </context-param>
      
       <!-- Faces Servlet Mapping -->
       <welcome-file-list>
       <welcome-file>calculator.jsf</welcome-file>
       </welcome-file-list>
      
      </web-app>


        • 1. Re: Misunderstanding of how @In works.

          To add some insight...

          I want to use the CalculatorBean to hold the data entered in the form and have it injected into the CalculatorAction. This way the calculate method can access the data in the bean to perform the actual calculations. This makes sense to me and seams (pun intended) logical to me.

          • 2. Re: Misunderstanding of how @In works.
            pmuir

            Try changing

             @In(create=true)
             private CalculatorBean cb;
            


            to

             @In(create=true, value=calculator)
             private CalculatorBean cb;
            


            Seam uses the name of the component variable as the name of the context variable by default; in the code you gave the context variable cb is unknown to Seam.

            • 3. Re: Misunderstanding of how @In works.

              That did the trick. It makes sense too. I don't know why I didn't catch that but I see now how the naming has to line up in order for the injection to work. Very cool.