8 Replies Latest reply on Nov 12, 2007 3:22 AM by Marc Lustig

    trouble getting correct SFSB-instance in WAR-deployment

    Marc Lustig Newbie

      We continue having trouble to acquire correct SFLB-instance to the web-deployment (in an EAR on JBoss 4.2.1). It appears the web-session is not identical with the client-session on the EJB-tier, hence JNDI delivers a new instance of that SFLB instead of the one already assigned to this user.

      bean-class:

      @Stateful
      @Name("shopTree")
      @Scope(ScopeType.SESSION)
      @CacheConfig(idleTimeoutSeconds=3600)
      public class ShopTreeBean implements ShopTree {
      
       @PersistenceContext
       private EntityManager em;
      
       @Logger
       private Log log;
      
       @In
       private ApplicationUser applicationUser;



      In the facelet, the correct instance can be addressed via #{shopTree.xxx}
      Now this bean is published to the WEB-deployment by the following code:
      jboss-web.xml:
      <jboss-web>
       <ejb-local-ref>
       <ejb-ref-name>ejb/ShopTree</ejb-ref-name>
       <local-jndi-name>app/ShopTreeBean/local</local-jndi-name>
       </ejb-local-ref>
      </jboss-web>


      web.xml:
      <ejb-local-ref>
       <ejb-ref-name>ejb/ShopTree</ejb-ref-name>
       <ejb-ref-type>Session</ejb-ref-type>
       <local-home>java.lang.Object</local-home>
       <local>pkg.ShopTree</local>
       <ejb-link>app/ShopTreeBean</ejb-link>
       </ejb-local-ref>



      If we lookup this EJB using context "app/ShopTreeBean/local" , we get ANOTHER (new) instance.
      What additional configuration is needed in order to make JBoss EJB deliver the correct SFSB-instance that is already assigned to that user?



        • 1. Re: trouble getting correct SFSB-instance in WAR-deployment
          Andrew Rubinger Master

          Are you looking up the SFSB from JNDI with every HTTP request?

          A new lookup will return a new instance; if you're doing this, best to perform the JNDI lookup once (maybe in a filter in an if(session.isNew()) block) and then place the stub as an attribute into the HttpSession. Subsequent requests to the HttpSession can reference the stub there, and you'll get back the same SFSB instance.

          S,
          ALR

          • 2. Re: trouble getting correct SFSB-instance in WAR-deployment
            Marc Lustig Newbie

            ty for your input.
            yes, now I look up the SFSB with every HTTP-request.
            Before I tried looking it up once and and then having save the instance in HTTP-session, just like you suggest.
            However, the result does not differ as in both cases the instance acquired on the web-tier/WAR-deployment is not the one that is assigned to this client-session on the EJB-tier.
            Seam makes available the correct instance to the JSF-context.

            I wonder if this problem is due to wrong JDNI-configuration.
            Is

            <ejb-ref-type>Session</ejb-ref-type>

            valid for both SLSB and SFSB?
            Regarding attaching the EJB to a client, SLSB and SFSB are completely different things. A SLSB can be assigned to any client. A SFSB needs to be clearly assigned to one client-session.
            There must be some clear architecture to ensure that the WAR-deployment is defininately getting the correct SFSB-instance, and not maybe another one. Anybody has a hint for me at this point?


            • 3. Re: trouble getting correct SFSB-instance in WAR-deployment
              wayne baylor Apprentice

              when you save the sfsb are you using the same attribute name for all clients?

              • 4. Re: trouble getting correct SFSB-instance in WAR-deployment
                Marc Lustig Newbie

                 

                "waynebaylor" wrote:
                when you save the sfsb are you using the same attribute name for all clients?


                yes, I used the same string for saving the SFSB-instance in the HTTP-session.
                This is the job of the web-container to seperate web-sessions against each other and should not be involved in this problem.
                Also, like I pointed out before, even when the web-client is requesting the SFSB-instance (using JNDI-lookup) for the FIRST time, this instance is not the correct one.

                I think I am missing some basic point here.... but I wonder which one ;-)
                I did not find anything in the Wiki and neither in the AS Guide.
                I still suspect that the JNDI configuration/mapping is bad. Can somebody have a look, pls.


                • 5. Re: trouble getting correct SFSB-instance in WAR-deployment
                  Andrew Rubinger Master

                   

                  "axismundi" wrote:
                  Also, like I pointed out before, even when the web-client is requesting the SFSB-instance (using JNDI-lookup) for the FIRST time, this instance is not the correct one.


                  A new JNDI lookup to a SFSB will always result in an reference to invoke on a new, fresh instance. What do you mean by "correct"?

                  I don't think this issue here is your JNDI config. :)

                  Try again with doing one lookup, placing that stub in the HttpSession, and paste your code if you're still having problems?

                  S,
                  ALR

                  • 6. Re: trouble getting correct SFSB-instance in WAR-deployment
                    Marc Lustig Newbie

                     

                    "ALRubinger" wrote:

                    Try again with doing one lookup, placing that stub in the HttpSession, and paste your code if you're still having problems?

                    S,
                    ALR


                    I followed your advise and implemented a filter to retrieve the SFSB-proxy once the HTTP-session is created:

                    public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {
                    
                     HttpSession session = ((HttpServletRequest)request).getSession();
                     ShopTree shopTree;
                     if (session.isNew()) {
                     try {
                     Context context = new InitialContext();
                     shopTree = (ShopTree) context.lookup("app/ShopTreeBean/local");
                     } catch (NamingException e) {
                     throw new ServletException(e);
                     }
                     session.setAttribute("shopTreeBean", shopTree);
                     }
                     chain.doFilter(request, response);
                     }


                    I verified that the filter is working as expected.

                    But the result of the endeavor is just as before. Not surprisingly I can pick up the proxy (local IF) from the session in my ImageServlet successfully.
                    But once I try to access a method, at the first time Seam is complaining like this:

                    Caused by: org.jboss.seam.RequiredException: @In attribute requires non-null value: shopTree.applicationUser
                    


                    However, I have verified that the field applicationUser is available in the Seam context. Moreover, I have debugged the Seam action-method which is implemented in the same SFSB and verified that the field has already been populated on a previous request.

                    At the second request to the ImageServlet, I am getting
                    javax.ejb.NoSuchEJBException: Could not find stateful bean: a4i810-vbn2mr-f8u25ljn-1-f8u49lh5-12


                    My only explanation is that JBoss' JNDI-implementation delivers a serialized instance (copy) of the original instance that is available in the EJB-container. However, AFAIK, this would not fit with the JBoss' specification, which says that JNDI-lookups for local IF's (in the same VM) result in a reference to the instance, not in a serialized copy.

                    Anymore hint for me?

                    • 7. Re: trouble getting correct SFSB-instance in WAR-deployment
                      Andrew Rubinger Master

                       

                      "axismundi" wrote:
                      But the result of the endeavor is just as before. Not surprisingly I can pick up the proxy (local IF) from the session in my ImageServlet successfully.

                      But once I try to access a method, at the first time Seam is complaining like this:

                      Caused by: org.jboss.seam.RequiredException: @In attribute requires non-null value: shopTree.applicationUser
                      



                      I can't speak to the failure of the @In injection; I'm not too familiar with Seam. You might bring this up in the Seam User's Forum.

                      "axismundi" wrote:
                      At the second request to the ImageServlet, I am getting
                      javax.ejb.NoSuchEJBException: Could not find stateful bean: a4i810-vbn2mr-f8u25ljn-1-f8u49lh5-12


                      My only explanation is that JBoss' JNDI-implementation delivers a serialized instance (copy) of the original instance that is available in the EJB-container. However, AFAIK, this would not fit with the JBoss' specification, which says that JNDI-lookups for local IF's (in the same VM) result in a reference to the instance, not in a serialized copy.


                      More accurately, local calls are still passed through a Proxy (which is what you obtain from JNDI) which will directly invoke based on reference. There are conditions, however, based upon the type of Exception thrown and the transactional context of the method you're invoking, where the EJB3 spec dictates that the instance must be discarded. In this case, you'll receive the Exception from Seam, the SFSB instance would be discarded, and then you'd invoke on the same Proxy referencing the discarded instance and receive the error message above. EJB3 Core Spec 14.3.1 Table 14.

                      Maybe try losing the @In annotation and slimming things down to tackle this one problem at a time? If you can get past the Seam exception and make subsequent invocations on the proper SFSB (whose stub you store in the HttpSession), then that'll give us some indication we're on the right track.

                      S,
                      ALR