1 2 Previous Next 18 Replies Latest reply on Feb 9, 2010 5:40 AM by dan.j.allen

    Help needed with Weld,EJB,JSF

    scaroo

      Hi everybody,


      I am hitting an issue I cannot resolve alone, for which I'd be very glad and thankful getting some help and input.



      I am trying to implement a registration system in JSF using a service exposed via Weld. The service is a staful session bean exposed via CDI to jsf. It has a producer method, producing a new request-scoped User instance, and a register method, persisting the jsf-filled user instance. So far so good (or is it?)


      The thing is that any call from jsf to the register method raises an IllegalStateException. Here is the code


      Bean :




      @Named("registration")
      @SessionScoped
      @Stateful
      public class RegistrationService implements Serializable {
      
          @Inject @Named("newUser")
          User newUser;
      
      
          @Inject @UserDatabase EntityManager em;
      
          @Produces @RequestScoped @Named("newUser")
          public User getNewUser()
          {
              return new User();
          }
      
      
          public String register() {
              em.persist(newUser);
              return null;//"registerConfirmation";
          }
      }





      JSF page snippet :




      <h:form>
                          <h1><h:outputText value="Create/Edit"/></h1>
                          <h:panelGrid columns="3">
                              <h:outputLabel value="Username:" for="username" />
                              <h:inputText id="username" value="#{newUser.username}" title="Username" />
                              <h:message for="username"/>
      
                              <h:outputLabel value="Email:" for="email" />
                              <h:inputText id="email" value="#{newUser.email}" title="Email" />
                               <h:message for="email"/>
      
                              <h:outputLabel value="Password:" for="password" />
                              <h:inputSecret id="password" value="#{newUser.password}" title="Password" />
                               <h:message for="password"/>
      
                              <h:commandButton value="Ok" action="#{registration.register}"/>
      
                          </h:panelGrid>
                      </h:form>
      



      Does anything seems weird to you ?
      What would you advice as best practice (regarding Statefulness, Scoping...) to implement a registration system ?


      Anyway, thanx to ya if you read this far :)

        • 1. Re: Help needed with Weld,EJB,JSF

          Alexandre Mazari wrote on Nov 27, 2009 15:19:


          The thing is that any call from jsf to the register method raises an IllegalStateException. Here is the code



          Please post the full stacktrace.

          • 2. Re: Help needed with Weld,EJB,JSF
            gavin.king

            Right. We need the stack trace.


            BTW, you don't tell us what container you're running in, but two things:



            • stateful beans don't need to implement Serializable

            • unless the container supports EJB 3.1, your bean does need a local interface.


            • 3. Re: Help needed with Weld,EJB,JSF
              scaroo

              Gavin, Francisco,


              Thanks for looking at it.
              I am running a recent nightly build of glassfish 3 using WELD-000900 1.0.0 (SP1).
              As suggested, I removed the Serializable interface from my service.
              I didn't declare a local interface, GF3 being EJB3.1-compliant to my knowledge.


              I resolved my issue by not outjecting a new instance of User, nor injecting it and referencing the bean as a property of the service in the jsf (registration.newUser).



              Anyway, I am still curious about it, so here is the full stacktrace :


              GRAVE: java.lang.RuntimeException: Error invoking method register on class org.scaroo.test.controller.__EJB31_Generated__RegistrationService__Intf____Bean__
              javax.faces.el.EvaluationException: java.lang.RuntimeException: Error invoking method register on class org.scaroo.test.controller.__EJB31_Generated__RegistrationService__Intf____Bean__
                      at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
                      at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
                      at javax.faces.component.UICommand.broadcast(UICommand.java:315)
                      at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:775)
                      at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1267)
                      at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
                      at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
                      at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
                      at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
                      at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
                      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
                      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
                      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
                      at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
                      at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
                      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
                      at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332)
                      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:233)
                      at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
                      at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
                      at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
                      at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
                      at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:168)
                      at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
                      at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
                      at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
                      at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
                      at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
                      at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
                      at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
                      at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
                      at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
                      at java.lang.Thread.run(Thread.java:637)
              Caused by: java.lang.RuntimeException: Error invoking method register on class org.scaroo.test.controller.__EJB31_Generated__RegistrationService__Intf____Bean__
                      at org.jboss.weld.util.Reflections.invokeAndWrap(Reflections.java:529)
                      at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:123)
                      at org.scaroo.test.controller.RegistrationService_$$_javassist_47.register(RegistrationService_$$_javassist_47.java)
                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                      at java.lang.reflect.Method.invoke(Method.java:597)
                      at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:113)
                      at org.scaroo.test.controller.RegistrationService_$$_javassist_67.register(RegistrationService_$$_javassist_67.java)
                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                      at java.lang.reflect.Method.invoke(Method.java:597)
                      at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
                      at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
                      at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:43)
                      at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:72)
                      at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:98)
                      at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
                      ... 32 more
              Caused by: java.lang.reflect.InvocationTargetException
                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                      at java.lang.reflect.Method.invoke(Method.java:597)
                      at org.jboss.weld.util.Reflections.invokeAndWrap(Reflections.java:517)
                      ... 50 more
              Caused by: javax.ejb.EJBException: java.lang.IllegalStateException
                      at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1962)
                      at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1906)
                      at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:198)
                      at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:84)
                      at $Proxy201.register(Unknown Source)
                      at org.scaroo.test.controller.__EJB31_Generated__RegistrationService__Intf____Bean__.register(Unknown Source)
                      ... 55 more
              Caused by: java.lang.IllegalStateException
                      at com.sun.enterprise.container.common.impl.EntityManagerWrapper.close(EntityManagerWrapper.java:826)
                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                      at java.lang.reflect.Method.invoke(Method.java:597)
                      at org.jboss.weld.bean.builtin.CallableMethodHandler.invoke(CallableMethodHandler.java:46)
                      at javax.persistence.EntityManager_$$_javassist_46.close(EntityManager_$$_javassist_46.java)
                      at org.jboss.weld.bean.builtin.ee.PersistenceContextProducerField.defaultDispose(PersistenceContextProducerField.java:58)
                      at org.jboss.weld.bean.builtin.ee.PersistenceContextProducerField.defaultDispose(PersistenceContextProducerField.java:29)
                      at org.jboss.weld.bean.ProducerField$1.dispose(ProducerField.java:88)
                      at org.jboss.weld.bean.ProducerField.destroy(ProducerField.java:113)
                      at org.jboss.weld.context.ForwardingContextual.destroy(ForwardingContextual.java:18)
                      at org.jboss.weld.context.DependentInstancesStore.destroy(DependentInstancesStore.java:79)
                      at org.jboss.weld.context.DependentInstancesStore.destroyDependentInstances(DependentInstancesStore.java:73)
                      at org.jboss.weld.context.CreationalContextImpl.release(CreationalContextImpl.java:79)
                      at org.glassfish.weld.services.JCDIServiceImpl$JCDIInjectionContextImpl.cleanup(JCDIServiceImpl.java:214)
                      at com.sun.ejb.containers.BaseContainer.cleanupInstance(BaseContainer.java:1640)
                      at com.sun.ejb.containers.StatefulSessionContainer.forceDestroyBean(StatefulSessionContainer.java:1064)
                      at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:4964)
                      at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4756)
                      at com.sun.ejb.containers.StatefulSessionContainer.postInvokeTx(StatefulSessionContainer.java:1645)
                      at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1955)
                      ... 60 more




              Thank you !

              • 4. Re: Help needed with Weld,EJB,JSF
                gavin.king

                Looks like a bug in the GlassFish/Weld integration, or in Weld itself. At first guess, I would say that the bug is more likely in Weld, since Weld should not need to call close() itself on a container-managed EM. I would report this bug against both Weld and GlassFish.


                But you have not shown all your code! Especially, you're missing the critical piece of code that defines the @UserDatabase EntityManager. In future, please post everything that is relevant. Thanks. 

                • 5. Re: Help needed with Weld,EJB,JSF
                  scaroo

                  Well, I just didn't want to flood the forum with (even) more stuff.


                  The @UserDatabase qualifier is straightly taken from the Login example in Weld (Chapter 3 of the doc). I presume you wrote it :)


                  Anyway, here it is :



                  @Qualifier
                  @Retention(RUNTIME)
                  @Target({METHOD, PARAMETER, FIELD})
                  public @interface UserDatabase {}



                  and the associated producer :


                  public class UserDatabaseProducer {
                  
                  @Produces @UserDatabase @PersistenceContext EntityManager userDatabase;
                  }



                  Going back to best practices, let me take the occasion of having a very skilled guru at hand :) (if you have some spare time).


                  How would you implement a registration service for a simple website ? Would you make it stateless/stateful ? Request or Session scoped ?


                  How would you outject the request-scoped User entity instance in the JSF life-cycle ? Then Inject it to persist it ?



                  thanks in advance,


                  Alex

                  • 6. Re: Help needed with Weld,EJB,JSF
                    nickarls

                    PersistenceContextProducerField.defaultDispose() appears to do an instance.close() at that point without doing too much checking...

                    • 7. Re: Help needed with Weld,EJB,JSF
                      nickarls

                      PS. I don't think you should need


                      @Inject @Named
                      



                      in fresh, non-legacy code


                      In general, don't keep objects alive longer than needed. Start with request scoped and increase the scope when you notice that your code has amnesia (like requiring you to log in on every request). You might use a SessionScoped @LoggedIn User (like the spec/refdocs use as an example) if you want to start using the regged user immediately...

                      • 8. Re: Help needed with Weld,EJB,JSF
                        gavin.king

                        How would you implement a registration service for a simple website ? Would you make it stateless/stateful ? Request or Session scoped ?

                        Um, it all depends. If the user is going to need to step through multiple pages to register, I suppose it would to keep state in a session scoped (or conversation scoped) bean. However, for a very simple site, we should be able to register in one click, so a request-scoped bean would be fine.



                        How would you outject the request-scoped User entity instance in the JSF life-cycle ? Then Inject it to persist it ?

                        I would stick the user in a @Produces field of a @SessionScoped bean.

                        • 9. Re: Help needed with Weld,EJB,JSF
                          pmuir

                          Nicklas Karlsson wrote on Nov 28, 2009 15:15:


                          PersistenceContextProducerField.defaultDispose() appears to do an instance.close() at that point without doing too much checking...


                          https://jira.jboss.org/jira/browse/WELD-341

                          • 10. Re: Help needed with Weld,EJB,JSF
                            dan.j.allen

                            In the short run you can use this code:


                            @Stateless // or @Stateful
                            public class WidgetRepositoryProducer
                            {
                               // NOTE cannot use producer field because Weld attempts to close EntityManager
                               // https://jira.jboss.org/jira/browse/WELD-341
                               @PersistenceContext EntityManager em;
                            
                               public @Produces @WidgetRepository EntityManager retrieveEntityManager() {
                                  return em;
                               }
                            
                               public void disposeEntityManager(@Disposes @WidgetRepository EntityManager em) {}
                            }

                            • 11. Re: Help needed with Weld,EJB,JSF
                              jpleed3.john.leediii.minitmarkets.com

                              Is there a purpose behind making the producer class an SLSB?

                              • 12. Re: Help needed with Weld,EJB,JSF
                                jpleed3.john.leediii.minitmarkets.com

                                John Leed wrote on Jan 28, 2010 23:16:


                                Is there a purpose behind making the producer class an SLSB?


                                The reason I ask is that when it seems to involve EE resources, the only way I've gotten these producers to work is by using @Stateless. If I leave the class unannotated or use @javax.annotation.ManagedBean, the resources aren't injected.


                                Which leads to the next question, what the hell is @ManagedBean good for?

                                • 13. Re: Help needed with Weld,EJB,JSF
                                  hirowla.ian.rowlands.three.com.au

                                  Here's  one URL that comments on it.


                                  My take is that unless you are running JSF2 in a non-JEE6 container, then it is really no use at all! If you are, then it is useful. But how often will people do that?


                                  To quote a song (and alter the lyrics slightly):


                                  @ManagedBean, huh, yeah
                                  What is it good for
                                  Absolutely nothing
                                  Uh-huh
                                  @ManagedBean, huh, yeah
                                  What is it good for
                                  Absolutely nothing
                                  Say it again, y'all
                                  
                                  @ManagedBean, huh, good God
                                  What is it good for
                                  Absolutely nothing
                                  Listen to me
                                  
                                  Ohhh, @ManagedBean, I despise
                                  Because it means destruction
                                  Of innocent lives
                                  
                                  @ManagedBean means tears
                                  To thousands of mothers eyes
                                  When their sons go to fight
                                  And lose their lives
                                  




                                  • 14. Re: Help needed with Weld,EJB,JSF
                                    jpleed3.john.leediii.minitmarkets.com

                                    Heh, the last comment on that link right now is mine. :)


                                    Are we talking about the same @ManagedBean? Since I'm running Glassfish v3, yes - @javax.faces.bean.ManagedBean is pretty useless. I'm talking about @javax.annotation.ManagedBean, defined in JSR-316:


                                    From Cay's blog:


                                    JSR 316


                                    There is an annotation @javax.annotation.ManagedBean, defined by JSR 316, that attempts to generalize JSF managed beans for use elsewhere in Java EE. There isn't much there. You can use the @PostConstruct and @PreDestroy annotations. You can use @Resource for injecting EE resources. You can use interceptors. For example, if you define



                                    @javax.annotation.ManagedBean(user) public class UserBean ...


                                    then you can construct an instance by making a JNDI lookup for java:module/user. But there is no interaction with an expression language, and there is no notion of scopes. So, perhaps this kind of managed bean isn't going to see a lot of love.

                                    1 2 Previous Next