5 Replies Latest reply on Nov 12, 2012 9:37 AM by John Leed

    Returning Null From Non-Dependent Producer Method

    John Leed Newbie

      I have a bean that returns an entity representing the current user if logged in. If  not, the method returns null. It would seem to make sense to have this value request or session scoped, but if the producer even thinks about returning null with @RequestScoped or @SessionScoped, I get (org.jboss.weld.IllegalProductException: WELD-000052 Cannot return null from a non-dependent producer method) on deployment.


      I don't see anything about this in the Weld reference or anything apparent in the spec. What is the reason for this limitation?

        • 1. Re: Returning Null From Non-Dependent Producer Method
          Pete Muir Master

          It's in the spec (see 3.3). The reason is we can't proxy null.


          Anyway, as in your other question, use a session scoped manager bean and the produce the value into dependent scope.

          • 2. Re: Returning Null From Non-Dependent Producer Method
            John Leed Newbie

            Thanks Pete, that's the direction I was going in. I'm caching the value in the bean and making the producer dependent;  I think that will have the same performance.


            I hope the restriction gets added to the documentation.

            • 3. Re: Returning Null From Non-Dependent Producer Method
              Taner Aruk Newbie

              I have the same problem, how did you solve it?

               

              Thanks for your help.

              • 4. Re: Returning Null From Non-Dependent Producer Method
                Marko Lukša Apprentice

                Taner, any of the following solutions should work:

                 

                1. make the producer return a null user object instead of null (see Null Object Pattern - http://en.wikipedia.org/wiki/Null_Object_pattern)

                2. make the producer always return a non-null UserHolder, which contains user (which can be null)

                3. make the producer @Dependent and cache the returned value in another normal-scoped bean (this is what John did)

                • 5. Re: Returning Null From Non-Dependent Producer Method
                  John Leed Newbie

                  Wow... I haven't written any Java for over a year! Still, it's nice to get back into NetBeans for a little while.

                   

                  I followed Pete's suggestion and created a session scoped bean, that, among other things, had a producer method for the user. In my case, the user was an entity class:

                   

                  @Named("intranetContext")
                  @SessionScoped
                  public class IntranetContextManager implements Serializable {
                      @Inject @IntranetDatabase EntityManager em;

                      private static final Logger logger = Logger.getLogger("com.kroger.thmm.producer.IntranetContextManager");

                      public IntranetContextManager() {
                          logger.fine("Creating instance of IntranetContextManager");
                      }

                   

                      /*
                       * Methods for getting current user
                       */

                      private IntranetUser currentUser;
                      private static final Logger currentUserLogger = Logger.getLogger("com.foo.producer.IntranetContextManager.currentUser");

                      @Produces @Named("currentUser") @Dependent
                      public IntranetUser getCurrentUser(HttpServletRequest request) {
                          currentUserLogger.fine("ICM.getCurrentUser: entering");
                          String remoteUser = request.getRemoteUser();
                          if (remoteUser == null || remoteUser.isEmpty()) {
                              currentUserLogger.finer("ICM.getCurrentUser: remote user is empty, clearing cached value");
                              return (currentUser = null);
                          }
                          else if (currentUser == null) {
                              currentUserLogger.finer("ICM.getCurrentUser: currentUser is null, getting value");
                              currentUser = getCurrentUser(remoteUser);
                          }
                          else if (!(remoteUser.equalsIgnoreCase(currentUser.getEnterpriseId()) ||
                              remoteUser.equalsIgnoreCase(currentUser.getUsername()))) {
                              currentUserLogger.finer("ICM.getCurrentUser: cached currentUser does not match remote user, getting new value");
                              currentUser = getCurrentUser(remoteUser);
                          }
                          else {
                              currentUserLogger.finer("ICM.getCurrentUser: returning cached value");
                          }
                          return currentUser;
                      }

                      public IntranetUser getCurrentUser(String login) {
                          if (login != null && !login.isEmpty()) {
                              //...
                          }
                          return null;
                      }
                  }

                   

                  In my site, there was anonymous access as well as authenticated, hence the reason I sometime needed to return null. Because the user could run anonymously, then log in at a later point, when I had the user injected I used an Instance instead:

                       @Inject Instance<IntranetUser> currentUserSource;

                   

                  Hope this helps!