Search code examples
jsfjakarta-eecdiwildfly-8

Cannot inject CDI @SessionScoped in HttpSessionListener


I have a stateful, session scoped (CDI) EJB that holds the info about the user session.

@Stateful
@SessionScoped
public class GestorSesion implements IGestorSesionLocal, Serializable {

  private final static long serialVersionUID = 1L;

  private static final Logger log = Logger.getLogger(GestorSesion.class.getName());

  @PostConstruct
  private void init() {
    log.info("Configurando información de usuario");
    log.info("****************************************************************************");
  }

  @Override
  public void cerrarSesion() {
  }

  @Override
  public ISessionInfo getSesionInfo() {
    return null;
  }
}

Now, I want to call cerrarSesion() (closeSession()) from an HttpSessionListener

public class GestorSesionWeb implements HttpSessionListener {


  private static final Logger log = Logger.getLogger(GestorSesionWeb.class.getName());

  @Inject
  private Instance<IGestorSesionLocal> gestorSesion;

  @Override
  public void sessionCreated(HttpSessionEvent se) {
    if (log.isLoggable(Level.FINE)) {
      log.fine("Iniciada sesión web");
    }
    gestorSesion.get().getSesionInfo();
  }

  @Override
  public void sessionDestroyed(HttpSessionEvent se) {
    if (log.isLoggable(Level.FINE)) {
      log.fine("Limpiando sesión al salir");
    }
    try {
      this.gestorSesion.get().cerrarSesion();
      if (log.isLoggable(Level.FINE)) {
        log.fine("Sesión limpiada sin problemas");
      }
    } catch (Exception e) {
      log.log(Level.WARNING, "Excepción limpiando sesión", e);
    }
  }
}

And I access the EJB from the webapp, directly (injecting using @EJB) into the beans that I use for JSF (they are also CDI managed beans).

The issue that I face is that it seems that the HttpSessionListener seems to be in a different "session scope" than the JSF beans. Two instances of GestorSession are created; one instantiated from the JSF and other instantiated from the HttpSessionListener.

I have tried injecting the bean via @Inject Instance<IGestorSesionLocal>, @Inject IGestorSesionLocal and BeanManager, with identical results.

This bug report suggests that it should to work correctly (the bug is solved for my version), but I still cannot get around it. I have looked around, but what I find are Q&A relating to JSF managed beans (yes, I could try to wrap a reference to the EJB in a JSF managed bean, but I would like to try it "correctly" first).

Working with WilFly 8.1.0 and JDK 7

Any ideas?


Solution

  • I think your pb comes from here:

    And I access the EJB from the webapp, directly (injecting using @EJB) into the JSF beans.

    When use CDI with EJB (by putting a @Sessionscoped on it for instance) you got an CDI bean that also has an EJB nature but not the other way around. In other word CDI is aware of the EJB nature but EJB is not aware of CDI.

    So if you want to inject an EJB as a CDI bean in your code use @Inject and not @EJB. From Java EE 6 the admitted good practice is to always use @Inject except for EJB remote.

    Also be sure to only use CDI managed bean and not a mix of CDI and JSF managed bean.