8 Replies Latest reply on Feb 26, 2010 2:32 AM by pppoole

    Not injecting Stateful EJB dependencies

    pppoole

      I am a noob working with Seam, so I am sure I am just doing something stupid.  Any help anyone can give me would be greatly appreciated... I have wasted hours and gotten nowhere.  I used the jboss tools to generate a seam project in eclipse.  The tool took pre-created JPA entities and created a basic webapp.  My first step was to add a registration page so that I can create some users and login using database authentication (I set this up, but will test it once the registration page works).  I used the seam-booking example to guide me (basically integrating the form stuff plus additional fields into the view of the seam-gen app).  When I test the registration page, I get NullPointerExceptions for all of the injected fields.  I have looked through the entire seam-booking example, scoured the web looking at examples, and quickly read through some sections of a book and I do not see where there is any additional configuration information needed.  What in the world am I doing wrong? Please help!!!


      If you need any more information than what I am posting, please let me know.  Thanks to all ahead of time for your help!!


      @Stateful
      @Scope(EVENT)
      @Name("register")
      public class RegisterAction implements Register {
           @In
           private User user;
           
           @PersistenceContext
           private EntityManager entityManager;
      
           @In 
           private FacesMessages facesMessages;
      
           private String verify = null;
      
           private boolean registered = false;
      
           public void registerUser() {
                if (user.getPassword().equals(verify)) {
                     List existing = entityManager
                               .createQuery(
                                         "select u.userName from User u where u.userName=#{user.userName}")
                               .getResultList();
                     if (existing.size() == 0) {
                          entityManager.persist(user);
                          facesMessages
                                    .add("Successfully registered as #{user.userName}");
                          registered = true;
                     } else {
                          facesMessages.addToControl("userName",
                                    "Username #{user.userName} already exists");
                     }
                } else {
                     facesMessages.addToControl("verify", "Re-enter your password");
                     verify = null;
                }
           }
      
           public void invalid() {
                facesMessages.add("Please try again");
           }
      
           public boolean isRegistered() {
                return registered;
           }
      
           public String getVerify() {
                return verify;
           }
      
           public void setVerify(String verify) {
                this.verify = verify;
           }
      
           @Remove
           @Destroy
           public void destroy() {
           }
      }





      @Local
      public interface Register
      {
         public void registerUser();
         public void invalid();
         public String getVerify();
         public void setVerify(String verify);
         public boolean isRegistered();
         
         public void destroy();
      }




      <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
           xmlns:s="http://jboss.com/products/seam/taglib"
           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:a="http://richfaces.org/a4j"
           xmlns:rich="http://richfaces.org/rich" template="layout/template.xhtml">
      
           <ui:define name="body">
                <rich:panel>
                     <f:facet name="header">Register</f:facet>
                     <h:form id="registration">
                          <fieldset><s:decorate id="firstNameDecorate"
                               template="layout/edit.xhtml">
                               <ui:define name="label">First Name:</ui:define>
                               <h:inputText id="firstName" value="#{user.firstName}"
                                    required="true">
                                    <a:support id="onblur" event="onblur" reRender="firstNameDecorate" />
                               </h:inputText>
                          </s:decorate> <s:decorate id="lastNameDecorate" template="layout/edit.xhtml">
                               <ui:define name="label">Last Name:</ui:define>
                               <h:inputText id="lastName" value="#{user.lastName}" required="true">
                                    <a:support id="onblur" event="onblur" reRender="lastNameDecorate" />
                               </h:inputText>
                          </s:decorate> <s:decorate id="emailDecorate" template="layout/edit.xhtml">
                               <ui:define name="label">Email:</ui:define>
                               <h:inputText id="emailAddress" value="#{user.emailAddress}"
                                    required="true">
                                    <a:support id="onblur" event="onblur" reRender="emailDecorate" />
                               </h:inputText>
                          </s:decorate> <s:decorate id="usernameDecorate" template="layout/edit.xhtml">
                               <ui:define name="label">Username:</ui:define>
                               <h:inputText id="username" value="#{user.userName}" required="true">
                                    <a:support id="onblur" event="onblur" reRender="usernameDecorate" />
                               </h:inputText>
                          </s:decorate> <s:decorate id="passwordDecorate" template="layout/edit.xhtml">
                               <ui:define name="label">Password:</ui:define>
                               <h:inputSecret id="password" value="#{user.password}"
                                    required="true" />
                          </s:decorate> <s:decorate id="verifyDecorate" template="layout/edit.xhtml">
                               <ui:define name="label">Verify Password:</ui:define>
                               <h:inputSecret id="verify" value="#{register.verify}"
                                    required="true" />
                          </s:decorate>
      
                          <div class="buttonBox"><h:commandButton id="register"
                               value="Register" action="#{register.registerUser}" /> &#160; <s:button
                               id="cancel" value="Cancel" view="/index.xhtml" /></div>
                     </fieldset>
                     </h:form>
                </rich:panel>
           </ui:define>
      </ui:composition>
      



      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <f:view 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:a="http://richfaces.org/a4j"
         xmlns:s="http://jboss.com/products/seam/taglib"
         contentType="text/html">
      <html>
         <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
            <title>MyApp</title>
            <link rel="shortcut icon" href="#{request.contextPath}/favicon.ico"/>
            <a:loadStyle src="resource:///stylesheet/theme.xcss"/>
            <a:loadStyle src="/stylesheet/theme.css"/>
            <ui:insert name="head"/>
         </head>
         <body>
            <ui:include src="menu.xhtml">
               <ui:param name="projectName" value="MyApp"/>
            </ui:include>
            <div class="body">
               <h:messages id="messages" globalOnly="true" styleClass="message"
                  errorClass="errormsg" infoClass="infomsg" warnClass="warnmsg"
                  rendered="#{showGlobalMessages != 'false'}"/>
               <ui:insert name="body"/>
            </div>
            <div class="footer">
               <p>Powered by <a href="http://seamframework.org">Seam</a> #{org.jboss.seam.version} and <a href="http://www.jboss.org/jbossrichfaces">RichFaces</a>. Generated by seam-gen.</p>
               <s:fragment rendered="#{init.debug}">
               <a:log hotkey="D"/>
               <p style="margin-top: -0.5em;">
                  Conversation: id = #{conversation.id}, #{conversation.longRunning ? 'long running' : 'temporary'}#{conversation.nested ? ', nested, parent id = '.concat(conversation.parentId) : ''}
                  #{' - '}
                  Ajax4jsf Log (Ctrl+Shift+D)
                  #{' - '}
                  <s:link id="debugConsole" view="/debug.xhtml" value="Debug console" target="debugConsole"/>
                  #{' - '}
                  <s:link id="resetSession" view="/home.xhtml" action="#{org.jboss.seam.web.session.invalidate}" propagation="none" value="Terminate session"/>
               </p>
               </s:fragment>
            </div>
         </body>
      </html>
      </f:view>




      <?xml version="1.0" encoding="UTF-8"?>
      <components xmlns="http://jboss.com/products/seam/components"
                  xmlns:core="http://jboss.com/products/seam/core"
                  xmlns:persistence="http://jboss.com/products/seam/persistence"
                  xmlns:drools="http://jboss.com/products/seam/drools"
                  xmlns:bpm="http://jboss.com/products/seam/bpm"
                  xmlns:security="http://jboss.com/products/seam/security"
                  xmlns:mail="http://jboss.com/products/seam/mail"
                  xmlns:web="http://jboss.com/products/seam/web"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation=
                      "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.2.xsd
                       http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.2.xsd
                       http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.2.xsd
                       http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.2.xsd
                       http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.2.xsd
                       http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.2.xsd
                       http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.2.xsd
                       http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">
      
         <core:init debug="true" jndi-pattern="@jndiPattern@"/>
      
         <core:manager concurrent-request-timeout="500"
                       conversation-timeout="120000"
                       conversation-id-parameter="cid"
                       parent-conversation-id-parameter="pid"/>
      
         <!-- Make sure this URL pattern is the same as that used by the Faces Servlet -->
         <web:hot-deploy-filter url-pattern="*.seam"/>
      
         <persistence:managed-persistence-context name="entityManager" auto-create="true"
                            persistence-unit-jndi-name="java:/MyAppEntityManagerFactory"/>
      
         <drools:rule-base name="securityRules">
            <drools:rule-files>
               <value>/security.drl</value>
            </drools:rule-files>
         </drools:rule-base>
      
         <security:rule-based-permission-resolver security-rules="#{securityRules}"/>
         
           <security:identity-manager identity-store="#{jpaIdentityStore}" />
      
           <security:jpa-identity-store
                entity-manager="#{entityManager}" user-class="my.app.path.dao.profiles.User"
                role-class="my.app.path.dao.profiles.Role" />
      
         <event type="org.jboss.seam.security.notLoggedIn">
            <action execute="#{redirect.captureCurrentView}"/>
         </event>
         <event type="org.jboss.seam.security.loginSuccessful">
            <action execute="#{redirect.returnToCapturedView}"/>
         </event>
      
         <mail:mail-session host="localhost" port="25"/>
      
         <!-- For use with jBPM pageflow or process management -->
         <!--
         <bpm:jbpm>
            <bpm:process-definitions></bpm:process-definitions>
            <bpm:pageflow-definitions></bpm:pageflow-definitions>
         </bpm:jbpm>
         -->
      
      </components>

        • 1. Re: Not injecting Stateful EJB dependencies
          pppoole

          I forgot to mention... I am using JBoss Server (community edition) 5.1.0GA.

          • 2. Re: Not injecting Stateful EJB dependencies
            pppoole

            I also forgot to mention... I am using Seam 2.2.0GA. 


            Does no one have any ideas?


            Thanks.

            • 3. Re: Not injecting Stateful EJB dependencies
              jeanluc

              Hmm... having a stateful bean scoped as an EVENT (the equivalent of a servlet request) doesn't make much sense. I wonder if that doesn't cause problems indirectly. Try scoping your component to something more sensible, like Conversation (which is default, anyway).


              Also, verify if there is any component which can actually supply an injected value for @In User

              • 4. Re: Not injecting Stateful EJB dependencies
                pppoole

                Hmm... having a stateful bean scoped as an EVENT (the equivalent of a servlet request) doesn't make much sense. I wonder if that doesn't cause problems indirectly. Try scoping your component to something more sensible, like Conversation (which is default, anyway).


                I thought this too... The scope is the same as what the booking example uses.  One of the first things I did was try a different scope type.




                Also, verify if there is any component which can actually supply an injected value for @In User

                My understanding is that the User instance will be created from the data on the registration page.  I tried setting create to true, but that didn't work either.  Is there something I am missing with regards to this?


                Thanks for your help.

                • 5. Re: Not injecting Stateful EJB dependencies
                  samdoyle
                  Are you sure it is all fields?
                  What is the exception you are getting?
                  Is it a NPE or is it that @In requires a non-null value?

                  Since you don't have required = false or create = true then Seam would have thrown an exception if it could not resolve any of the injected parameters.
                  On a side note you should probably be allowing Seam to manage the PeristenceContext so replace @PersistenceContext with @In.
                  • 6. Re: Not injecting Stateful EJB dependencies
                    pppoole
                    <blockquote>
                    Are you sure it is all fields?
                    What is the exception you are getting?
                    Is it a NPE or is it that @In requires a non-null value?
                    </blockquote>
                    Yes, there are only the two injected fields (besides PersistenceContext)... FaceMessages and User - both throw NullPointerExceptions. Validation is failing and it attempts to add a message to the faceMessages variable and an NPE is thrown.  If I comment that out (and replace with a println), then when I hit submit, the NPE is thrown in registerUser on this line: if (user.getPassword().equals(verify)) (specifically user.getPassword). 


                    <blockquote>
                    Since you don't have "required = false" or "create = true" then Seam would have thrown an exception if it could not resolve any of the injected parameters.
                    On a side note you should probably be allowing Seam to manage the PeristenceContext so replace @PersistenceContext with @In.
                    </blockquote>
                    Yeah, I am not seeing Seam throw an exception that it couldn't resolve anything... I have also debugged and when I am in the RegisterAction object, facesMessages and user are null, but the PersistenceContext is not (so this is being injected).
                    I will change up to the @In on the PersistenceContext... I am still trying to figure out the nuances, which would be easier if I could get past this issue.
                    • 7. Re: Not injecting Stateful EJB dependencies
                      pppoole

                      They need an edit feature, I accidentally clicked the Let me type some plain text box... sorry for the formatting problem. Here is a clean repost:



                      Are you sure it is all fields?
                      What is the exception you are getting?
                      Is it a NPE or is it that @In requires a non-null value?

                      Yes, there are only the two injected fields (besides PersistenceContext)... FaceMessages and User - both throw NullPointerExceptions. Validation is failing and it attempts to add a message to the faceMessages variable and an NPE is thrown. If I comment that out (and replace with a println), then when I hit submit, the NPE is thrown in registerUser on this line: if (user.getPassword().equals(verify)) (specifically user.getPassword).




                      Since you don't have required = false or create = true then Seam would have thrown an exception if it could not resolve any of the injected parameters.
                      On a side note you should probably be allowing Seam to manage the PeristenceContext so replace @PersistenceContext with @In.

                      Yeah, I am not seeing Seam throw an exception that it couldn't resolve anything... I have also debugged and when I am in the RegisterAction object, facesMessages and user are null, but the PersistenceContext is not (so this is being injected).
                      I will change up to the @In on the PersistenceContext... I am still trying to figure out the nuances, which would be easier if I could get past this issue.

                      • 8. Re: Not injecting Stateful EJB dependencies
                        pppoole

                        I am beyond frustrated with Seam.  I am trying to evaluate this framework for a new project at a big company... with the way things are going so far, I will likely suggest Spring.  I am disappointed by this b/c from what I have seen, I like what seam does better... unfortunately I can't seem to make it work (no pun intended).