Writing static utility class in Java EE system

ejb, jakarta-ee, java, jsp, servlets

Solution

Make use of `ThreadLocal`. You should only not store the `HttpSession` directly in there. The service layer should not have any dependency on `javax.servlet` API. Instead, extract the desired information from the `HttpSession` directly and store it there.

E.g. when you want to expose `User` attribute of the `HttpSession` as a thread local variable:

public class SomeContext {

    private static ThreadLocal<SomeContext> instance = new ThreadLocal<SomeContext>();
    private User user;

    private SomeContext(User user) {
        this.user = user;
    }

    public static SomeContext getCurrentInstance() {
        return instance.get();
    }

    public static SomeContext newInstance(User user) {
        SomeContext someContext = new SomeContext(user);
        instance.set(someContext);
        return someContext;
    }

    public void release() {
        instance.remove();
    }

    public User getUser() {
        return user;
    }

}

and this in `doFilter()` of a servlet filter:

User user = (User) request.getSession().getAttribute("user");
SomeContext someContext = SomeContext.newInstance(user);

try {
    chain.doFilter(request, response);
} finally {
    // It's very important to do this in finally!
    // Threads are namely pooled by the container.
    someContext.release();
}

in any code which is running in the very same thread after the particular filter, including EJBs, you can get the `User` as follows:

User user = SomeContext.getCurrentInstance().getUser();
// ...

Problem

I want to develop a utility class, that can be used in a static manner (static methods), for an enterprise Java system (JSP, Servlets, EJBs). It'd contain some methods that is capable to access the `HttpSession` object of the user and retrieves some useful info that is already stored as attributes (such as the current user id). Some of you may wonder why do I need such thing, while I can simply passing the `HttpSession` object to anywhere. Actually, I am working on a legacy Java EE 5.0 system and some of the utility classes (not Servlets, JSPs, nor EJBs) have no access to the `HttpSession` object. Is it possible to implement such utility class? Some constraints I/you should consider here: - The servlets/JSPs are hosted on machines that are different from what host EJBs. - The system is running on Weblogic 10.3.0. - On weblogic, there are many servers (that host servlets/JSPs) and they are under the same cluster. The same thing is with EJBs servers. - If I declare some static `Collection` inside the utility class, is it going to work? or maybe there will be more than one copy of it because of the multiple class loaders and multiple JVMs? - Maybe I should use a shared file or shared database to implement it? How even could I track which user invokes the utility class? Maybe tracking the thread? or maybe something related to the transaction?

Original source