8 Replies Latest reply on Aug 4, 2006 11:18 AM by ovidiucn

    Stateless Injection

    ovidiucn

      Hello!

      I encountered a strange behaviour of the stateless components. It seems that, even i'm requesting the container to inject a certain bean, the injection never occurs and, of course the value of the bean is null.

      If i'm removing the @Stateless annotation, it works just fine.

      Can anybody help me with this?

      PS: for this one, i've studied the jboss seam registration example and i followed the same pattern.

        • 1. Re: Stateless Injection

          Show your code.

          • 2. Re: Stateless Injection
            ovidiucn

            Thank you for being so quick.

            /***********************************/

            /* local interface */
            @Local
            public interface UserManagementLocal {
            public Collection getUsers ();
            }

            /***********************************/

            /* business logic */
            @Name("userManagement")
            @Stateless
            public class UserManagement implements UserManagementLocal {

            /* The login context created when a user previously logged-in. */
            @In(value="loginContext", create=false, required=true)
            private LoginContext loginContext;

            @In (value="user", create=true, required=true)
            private User user;

            @In
            Context sessionContext;

            public Collection getUsers() {
            Collection users = new ArrayList ();

            /* user bean is null !!! */
            /* sessionContext is null !!! */
            /* the loginContext is null !!! */

            System.out.println("user: " + user);
            System.out.println("sessionContext: " + sessionContext);
            System.out.println("loginContext: " + loginContext);

            try {
            SecurityDataService sds = SecurityDataServiceFactory.getService(loginContext.getSubject());

            Set attributeNames = new HashSet();
            users.addAll(sds.getAllUsers(attributeNames));
            } catch (SSDataManagementException e) {
            e.printStackTrace();
            users.clear();
            }

            return users;
            }
            }

            /***********************************/
            /* JBoss Seam configuration(s) */

            <!-- web.xml snippet -->



            <listener-class>
            org.jboss.seam.servlet.SeamListener
            </listener-class>




            <!-- faces-config.xml snippet -->
            <!-- using myfaces-1.1.3 -->



            <phase-listener>org.jboss.seam.jsf.SeamPhaseListener</phase-listener>




            <!-- WEB-INF/components.xml -->




            true
            <!-- using myfaces-1.1.3 -->
            false
            emp/#{ejbName}/local






            <!-- WEB-INF/classes/seam.properties exists & is empty -->
            <!-- service-security.jar#!seam.properties exists & is empty -->

            Environment:
            JRE 1.5.0_06
            JBOSS Release ID: JBoss [Zion] 4.0.4.GA (build: CVSTag=JBoss_4_0_4_GA date=200605151000) - installed with JEMS & ejb3 configuration enabled
            JBoss Seam 1.0.1.GA
            MyFaces 1.1.3

            Thanks!

            • 3. Re: Stateless Injection
              gavin.king

              Now please post it all again, but with code tags.

              What is in ejb-jar.xml?

              • 4. Re: Stateless Injection
                ovidiucn

                Ok.

                /* WEB-INF/classes/seam.properties exists & is empty */
                /* service-security.jar#!seam.properties exists & is empty */

                /* ejb-jar.xml */

                <ejb-jar>
                 <assembly-descriptor>
                 <interceptor-binding>
                 <ejb-name>*</ejb-name>
                 <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
                 </interceptor-binding>
                 </assembly-descriptor>
                </ejb-jar>
                


                /* WEB-INF/components.xml */
                <components>
                 <component name="org.jboss.seam.core.init">
                 <property name="debug">true</property>
                 <property name="myFacesLifecycleBug">false</property>
                 <property name="jndiPattern">emp/#{ejbName}/local</property>
                 </component>
                 <component class="org.jboss.seam.core.Microcontainer" installed="false"/>
                </components>
                


                /* faces-config.xml snippet */
                <?xml version='1.1' encoding='UTF-8'?>
                
                <!DOCTYPE faces-config PUBLIC
                 "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
                 "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
                
                <faces-config>
                 <lifecycle>
                 <phase-listener>org.jboss.seam.jsf.SeamPhaseListener</phase-listener>
                 </lifecycle>
                </faces-config>
                


                /* web.xml snippet */
                <?xml version="1.0" encoding="UTF-8"?>
                <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
                
                 <!-- Seam -->
                 <listener>
                 <listener-class>
                 org.jboss.seam.servlet.SeamListener
                 </listener-class>
                 </listener>
                
                 <!-- MyFaces -->
                 <listener>
                 <listener-class>
                 org.apache.myfaces.webapp.StartupServletContextListener
                 </listener-class>
                 </listener>
                
                 <!-- 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>*.xhtml</url-pattern>
                 </servlet-mapping>
                </web-app>
                


                /* code */
                /* local interface */
                @Local
                public interface UserManagementLocal {
                 public Collection getUsers ();
                }
                


                /* business logic */
                @Name("userManagement")
                @Stateless
                public class UserManagement implements UserManagementLocal {
                
                 /* The login context created when a user previously logged-in. */
                 @In(value="loginContext", create=false, required=true)
                 private LoginContext loginContext;
                
                 @In (value="user", create=true, required=true)
                 private User user;
                
                 @In
                 Context sessionContext;
                
                 public Collection getUsers() {
                 Collection users = new ArrayList ();
                
                 /* user bean is null !!! */
                 /* sessionContext is null !!! */
                 /* the loginContext is null !!! */
                
                 System.out.println("user: " + user);
                 System.out.println("sessionContext: " + sessionContext);
                 System.out.println("loginContext: " + loginContext);
                
                 try {
                 SecurityDataService sds = SecurityDataServiceFactory.getService(loginContext.getSub
                ject());
                
                 Set attributeNames = new HashSet();
                 users.addAll(sds.getAllUsers(attributeNames));
                 } catch (SSDataManagementException e) {
                 e.printStackTrace();
                 users.clear();
                 }
                
                 return users;
                 }
                }
                


                Environment:
                JRE 1.5.0_06
                JBOSS Release ID: JBoss [Zion] 4.0.4.GA (build: CVSTag=JBoss_4_0_4_GA date=200605151000) - installed with JEMS & ejb3 configuration enabled
                JBoss Seam 1.0.1.GA
                MyFaces 1.1.3

                Thanks!

                • 5. Re: Stateless Injection

                  Your url-pattern for your faces servlet mapping seems odd to me. Do you really have .jsp files that you get to via an .xhtml extension? foo.xhtml -> foo.jsp? How is userManagement.getUsers() getting called? Please show your view markup.

                  • 6. Re: Stateless Injection
                    ovidiucn

                    Ok... I think i forgot something. I'm using also facelets and i have also overriden the default suffix property in web.xml file; that is:

                     <context-param>
                     <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
                     <param-value>.xhtml</param-value>
                     </context-param>
                    

                    so calling for *.xhtml files works.

                    The part in which i'm calling the local interface looks like this:
                    @Name("userCBTModel")
                    @Scope(ScopeType.SESSION)
                    public class UserCBTModel implements CBTModel {
                    
                     @In(value = "userManagement", create = true, required = true)
                     private UserManagementLocal userManagement;
                    
                     public CBTPage getPage(CBTPageInfo pInfo) {
                     PageImpl page = new PageImpl();
                     PageInfoImpl pInfoImpl = (PageInfoImpl) pInfo;
                     int startIndex = pInfoImpl.getPageNumber() * pInfoImpl.getDefaultPageSize();
                     int count = pInfoImpl.getDefaultPageSize();
                    
                     boolean useFilter = ((pInfo == null) ? false
                     : ((pInfo.getFilter() == null) ? false : true));
                    
                     List<SSUser> users = new ArrayList<SSUser> ();
                     try {
                     users.addAll(userManagement.getUsers());
                     } catch (NullPointerException npe) {
                     logger.error("Userul logat nu are rol pentru a vedea userii:");
                     users.clear();
                     }
                    
                     /* prepare a new page */
                    
                     return page;
                     }
                    }
                    


                    And the presentation markup is as follows:
                    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                    <html xmlns="http://www.w3.org/1999/xhtml"
                     xmlns:ui="http://java.sun.com/jsf/facelets"
                     xmlns:h="http://java.sun.com/jsf/html"
                     xmlns:f="http://java.sun.com/jsf/core">
                    <head>
                    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
                    <link rel="stylesheet" type="text/css" href="css/style.css" />
                    <title>Checkbox table template</title>
                    </head>
                    <body>
                    
                    <ui:composition>
                    <f:view>
                    <h:form id="dataForm" rendered="#{userCBTModel.page.size != 0}">
                     <h:dataTable id="items" value="#{userCBTModel.page.items}" var="item"
                     rowClasses="list-row-odd, list-row-even" styleClass="tData" columnClasses="tData" rows="#{cbtBean.page.size}">
                    
                     <ui:insert name="tColumns">Table columns</ui:insert>
                    
                     </h:dataTable>
                    </h:form>
                    </f:view>
                    </ui:composition>
                    </body>
                    </html>
                    


                    The overall behaviour can be described as:
                    * the userManagement component (either is a stateless bean or just a pojo) it gets injected into userCBTModel bean - always;
                    * if the userManagement component is a stateless bean, its attributes are not injected;
                    * if the userManagement component is not a stateless bean (i.e. done by just removing the @Stateless annotation) works fine - all its attributes are injected; if i'm removing the stateless annotation it is treated as a simple java bean and its scope is EVENT.

                    Thank you.

                    • 7. Re: Stateless Injection
                      gavin.king

                      Use your debugger to find out if SeamInterceptor is *really* wrapping the calls to the stateless bean.

                      • 8. Re: Stateless Injection
                        ovidiucn

                        Hello!
                        It seems i discovered the problem. I was using several ejb jar files and by accident, in the jar which contained the Stateless bean i forgot to put the META-INF/ejb-jar.xml file. Now, everything is OK.

                        Thank you guys for your support,
                        Ovidiu