2
votes

After login user data stored in the SessionScoped bean. I want to each 5 second get each account stored in the session and send to backend. My timer

@Singleton
@Startup
public class FrontendTimer {

    @Inject
    private UserContext userContext;

    @Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
    @Asynchronous
    public void atSchedule() throws InterruptedException {
        System.out.println("Get Logged user stored in the session each 5 seconds ");
        System.out.println("FR " + userContext.getAccount().toString());
    }

}

Only way to start the scheduler is create @Startup and @Singleton class. Only way to keep user data in the frontend, save account to SessionScoped CDI bean, JSF native beans deprecated.

You will get error like : WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped

Project location here https://github.com/armdev/eap Class by itself https://github.com/armdev/eap/blob/master/eap-web/src/main/java/io/project/app/beans/FrontendTimer.java

Basically I want to have a standard timer who can get data from Session Scope.

1
Sorry, but your question is totally unclear to mee. Care to clarify. Preferably with minimal reproducible example - Kukeltje
Supposing the UserContext is sessionscoped, if there is no active user and the atSchedule() is invoked, which UserContext should it pick up? Or if there are two users active, hence two UserContext are existing - which if both should be picked? The session scope is available in threads processing servlet requests only. There is no user session context in scheduled background jobs. - Selaron
@Selaron: Wow... Reading the post (not the links to code) the question totally not made sense to me. Your comment (questions) made it clear. Compliments you did get it. - Kukeltje
@kukeltje thank you. I think I've only been quickly reading keywords, code and error message instead of trying to understand everything word by word. Sometimes that helps, sometimes it badly fails ._. - Selaron

1 Answers

4
votes

Your current approach will not work as you expect because each scheduler invocation will happen in a context completely isolated from sessions (hence the No active contexts... error message).

I suggest you use a simple inversion here. In your application scoped singleton, add a simple List<String> currentSessions and corresponding methods to void add(String account) and void remove(String account). Then @Inject the singleton into the session scoped bean (and not the other way around). Finally, add a @WebListener to handle session events.

@Singleton
public class SessionManager {

    private List<String> currentSessions;

    @Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
    @Asynchronous
    public void atSchedule() throws InterruptedException {
        //Do something with currentSessions
    }

    public void add(String account){
        currentSessions.add(account);
    }

    public void remove(String account){
        currentSessions.remove(account);
    }

}
@SessionScoped
public class UserContext implements Serializable {

    @Inject
    private SessionManager sessionManager;

    /*
    ...
    */

    public void sessionCreated(){
        sessionManager.add(account.toString());
    }

    public void sessionDestroyed(){
        sessionManager.remove(account.toString());
    }

}
@WebListener
    public class SessionListener implements HttpSessionListener {

        @Override
        public void sessionCreated(HttpSessionEvent se) {
            HttpSession session = se.getSession();

            FacesContext context = FacesContext.getCurrentInstance();
            UserContext userContext = (UserContext) session.getAttribute("userContext");
            userContext.sessionCreated();
        }

        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            HttpSession session = se.getSession();

            FacesContext context = FacesContext.getCurrentInstance();
            UserContext userContext = (UserContext) session.getAttribute("userContext");
            userContext.sessionDestroyed();

        } 
    }