How to make a Singleton-Scoped Object Thread-safe (Guice + Owasp ESAPI)
-
25-10-2019 - |
Question
I am currently using the Owasp ESAPI to manage authentication in my java web application, and I am injecting the Singleton MyAuthenticator with guice.injectMembers(this). I would like to step away from this approach and use a guice-created Singleton-Scoped object. I liked the thread-safety of the ESAPI singleton, and the safety of singletons in general, using Double-Checked Locking, IODH Idiom, or Bloch's Enum INSTANCE style.
What do I need to do to my Guicified Singleton-Scoped Authenticator to make it thread-safe, as well as the ThreadLocal field I am using to get and set my current User?
I would like to make the entire application work with dependency-injection, but don't want it to break upon web-app concurrent access. Any suggestions or common pitfalls?
The ThreadLocal object I am using looks like the code below:
private final ThreadLocalUser currentUser = new ThreadLocalUser();
private class ThreadLocalUser extends InheritableThreadLocal<User> {
@Override
public User initialValue() {
return User.ANONYMOUS;
}
public User getUser() {
return super.get();
}
public void setUser(User newUser) {
super.set(newUser);
}
}
Solution
Unfortunately I don't know enough about Owasp ESAPI to give a specific answer, but you may have some luck looking into Guice's AOP support. You can intercept all method invocations on the class and provide whatever concurrency behavior you like.
OTHER TIPS
Beware using the "Double-Check Locking" pattern in Java. This design pattern doesn't reliably work in Java (for instance, see http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html) unless you declare the singleton instance as "volatile".