ThreadLocal in Tomcat servlets

Viewed 6946

I'm having a problem where Exceptions are popping up in my production system but I really don't have good information about who is causing them. The person's username is stored as a variable in their tomcat session, which I have access to in my doPost or doGet method obviously, but unless I pass that information down as a parameter to each of my business objects, I don't have access to the session. For obvious reasons, I'd like to tack the username into the logging message so I have an idea of what is going on.

So my solution is to do something like this

public class ExceptionUtil {
    private ExceptionUtil() { } // no instantiation
    private static final ThreadLocal<String> local = new ThreadLocal<String>();
    public static void set(String user) { local.set(user); }
    public static String get() { return local.get(); }
}

Then in my posts/gets, I can do this

String username = request.getSession().getAttribute("username");
ExceptionUtil.set(username);

Then in my exceptions, I might do this (contrived, bad practice example)

catch(SQLException e) {
    logger.error(ExceptionUtil.get() + " did something dumb in sql", e);
    throw e;
}

The only problem I'm concerned about is how Tomcat will manage my threads. What if they keep the threads? Will they persist? Will the ThreadLocal values also persist? If I was storing the entire Session in the ThreadLocal instead of just a String, that would be a serious memory leak potential. It also means if someone forgot to re-set (or forgets to clear when done) the username/session on a thread that persisted for multiple requests, there might be stale data in there.

Call my cynical, but I don't want to have to rely on programmers (even, especially myself!) not forgetting to do things for a program's correctness. If I can idiot-proof my code, I'd like to. And that means getting a better understanding of how Tomcat will use the threads.

So, the question in a single-sentence form:

If I use ThreadLocal in a webapp running on Tomcat (7.0.27), do I run the risk of a Thread being used for multiple requests, and with it data from a previous request being persisted?

I should note that even though they don't answer the exact question of "Tomcat/ThreadLocal shenanigans", I am open to alternative solutions that allow me to elegantly access session variables for logging purposes. I am also open to commentary about potential pitfalls of my solution. I have a business problem to solve, and I'm not married to any one solution. I just want to know who keeps causing the exceptions on my prod system :)

2 Answers
Related