« Washing machines and mobile phones | Main | OpenSource contributions on your resume, a good thing? »

June 15, 2005

Don't use ThreadLocal!

I'm seeing some customers complain about the fact that WebSphere doesn't have a consistent ThreadLocal story. Depending on the version of WebSphere, we may or may not clear thread local when a thread is returned to the pool.

This is causing problems as it appears open source software assume that they can use ThreadLocal and this is just not true in a managed environment. ThreadLocal and thread pools just don't mix. You may get away with using ThreadLocal on a thread but as soon as you return and give that thread back to the application server then you can't assume:

  1. You'll get called again on the same thread.
  2. Even if you do get the same thread, it may have different threadlocal values as it may have been used by other applications.

Besides, it's a huge security risk. Suppose an application stores sensitive information on an object held in ThreadLocal. Another customer might send a request which gets processed on a thread just used by a different customer and then one can see the information for the other customer.

So, in a nut shell, don't use ThreadLocal if your code can be used in a managed environment. It appears a lot of open source software in wide use does use it, examples would be Spring and Xerces apparently. If you know of open source software that does then lobby to get it fixed. I can't see application server vendors supporting this type of programming in a managed environment.

When customers use async beans in WebSphere for threading, we recommend keeping the Thread state in the Runnable object rather than ThreadLocal because that'll work always. But, regardless, care has to be taken to make sure that security problems etc are not caused by naive use of ThreadLocal type mechanisms whether in the JDK or using an application specific mechanism.

UPDATE

Juergen in a comment below makes the comment that Spring only uses ThreadLocal during a synchronous call, i.e. it's ok if this state is discarded once the application returns. This will work BUT when Java 2 security is enabled then these APIs are likely to be APIs which are forbidden. Now, developers will need to argue with administrators to exclude spring.jar from these security rules and the result, as always, will be optimizing around the beaureacy, i.e. use software without this hassle.

June 15, 2005 | Permalink Sphere

Comments

Hi Billy,

Actually, Spring does not use ThreadLocals in the way you describe. Spring always just uses ThreadLocals temporarily, while guaranteed to be on the same thread, with proper cleanup at the end (in any case). This applies to transaction ThreadLocals as well as to others.

IMO, this is completely valid: As long as the ThreadLocal is always guaranteed to be cleaned up when returning the thread to the server's pool, I cannot see anything going wrong... So it's not about using ThreadLocals in general, it's about _properly_ using ThreadLocals.

I believe, I mentioned this usage as one that may be tolerated. The issue really is that while this should work, if Java 2 security is enabled then an application may not be able to even invoke these APIs. Then developers need to argue with the cell administrators to be allowed to call the method and I think that this will become a big hassle and will start to discourage the use of software with this kind of dependency.

Juergen

Posted by: Juergen Hoeller | Jun 15, 2005 3:25:32 PM

Hibernate 3.0 (Hibernate.getCurrentContext()) and Webwork..

I don't think it's valid to say "Don't use ThreadLocal's", instead you should write examples of using them properly in Websphere.

Posted by: | Jun 15, 2005 3:32:40 PM

If I'm not mistaken WebSphere has 'WorkArea' API available for developers which essentially based on ThreadLocal, or at least it sounds like it does.
Would it be better if Spring would detect and use it instead of ThreadLocals when running under WebSphere?

Posted by: Dmitri Maximovich | Jun 15, 2005 4:16:15 PM

I've just posted a followup article to this, talking about a design pattern I use to work around this problem. Click on my name below if you're interested.

Posted by: Paul Russell | Jun 15, 2005 4:54:15 PM

In fact, SessionFactory.getCurrentSession() in HB3 is NOT using a ThreadLocal.

Hibernate does not use ThreadLocal anywhere, actually.

Posted by: Gavin King | Jun 15, 2005 5:41:07 PM

The SecurityManager doesn't prevent from using the class ThreadLocal when it's active, even from untrusted code. Exactly what API use does it prevents that is supposed to matter for ThreadLocals?

Posted by: | Jun 15, 2005 10:40:22 PM

"In fact, SessionFactory.getCurrentSession() in HB3 is NOT using a ThreadLocal."

Well, it's not using one directly, but it uses javax.transaction.TransactionManager.getTransaction(). And I really don't see how it's possible to implements this method to the spec without using ThreadLocal or something similar. I know at least Resin's TransactionManager uses them.

Posted by: | Jun 15, 2005 10:52:56 PM

javax.transaction.TransactionManager.getTransaction() is the container provider responsibility though, so it can be implemented in a safe and consistent manner that works with the thread pools to propagate the TX across async calls and get properly cleaned up at the TX boundaries.

Posted by: Jed Wesley-Smith | Jun 16, 2005 8:36:22 PM

I didn't meant to say that Hibernate does something wrong. I wouldn't see a problem if Hibernate used ThreadLocal's, just like I don't see a problem that Spring does. And it can be implemented just as safe in Hibernate, it doesn't need interaction with the thread pool to be done safely, for example Spring's implementation works fine. The only thing access to the thread pool provide is the possibility to cleanup for misuses, like if using DOM4J (which does use ThreadLocals horribly...).

Posted by: | Jun 17, 2005 6:30:52 AM

You are being unfair against open source software by saying "it appears open source software assume".

I'm sure IBM software assume a lot also. Because there is an incredible amount of bugs in the software.

Without naming any specific software, just like I did, makes you look a bit stupid and naive.

Posted by: mr smith | Jun 17, 2005 8:11:03 AM

ThreadLocal is not used to save data between calls but to save it during a call.

However, in one thing you're right. At least one OS software uses it the wrong way: Jakarta messenger.

Posted by: Andreas Mueller | Jun 20, 2005 1:56:20 AM

It seems that org.apache.xml.utils.XMLReaderManager class from Xalan 2.6.0 distribution is using ThreadLocal to save data between calls.

Posted by: Jeff | Jun 30, 2005 12:39:34 AM

At javaone, bea and oracle annouced support for Spring. IBM bought, gluecode, which bundles geranimo, which supports Spring. So, now there is a IBM offering that supports Spring. I think, vendors would have to support a popular framework like spring. As Juergen said, it may be a totally valid way to use ThreadLocal in a managed environment.

Posted by: Prashant Rane | Jul 5, 2005 6:01:04 PM

JSR 237 - "Work Manager for Application Servers" describes multiple threads carrying out tasks in parallel in a managed environment. How can the transcation context get passed to all of them since JTA implicitly uses ThreadLocal? I just can't see how it would be done and it is not in their documentation.

Since this is going to be important in the future, and if the thread-bound nature of transactions are relaxed soon, how much of a headache will this be to re-write all the code that assumes this?

Posted by: Michael Bienstein | Aug 5, 2005 5:02:41 PM

"Depending on the version of WebSphere, we may or may not clear thread local when a thread is returned to the pool." --- Do we know which versions since this will both affect both proper and improper usages of ThreadLocal? Will there be a consistent implementation in Webspher?

Posted by: Fred | Sep 9, 2005 11:33:42 AM

No,
The only thing you can count on is that while you are using a thread, we won't clear it. But, as for the behavior of what happens when the thread reenters the pool, it's undefined and will likely remain so.

Posted by: Billy | Sep 9, 2005 11:36:08 AM

Okay. Okay. Okay.

Efficiency aside, can anyone tell me why I should not use ThreadLocal JUST for the duration of a call, as long as I properly screen it up?

I have a problem I intend to solve using ThreadLocal in WebSphere. The thread entering my servlet will have a ThreadLocal set on it before delegating to processing logic, and i will clean it up before doPost() returns.

What is the problem? Why does it matter if WebSphere and not application code created the thread. A thread is a thread is a thread - managed or otherwise. As long as I leave no evidence of "wrongdoing" aka, slamming a ThreadLocal onto the thread and then dumping it BEFORE WebSphere reclaims it for use to handle a subsequent web request, why should there be any issues?

Posted by: Vintage Freak | Sep 15, 2005 11:22:35 PM

"Depending on the version of WebSphere, we may or may not clear thread local when a thread is returned to the pool"
Do you think we must not use threadlocals to avoid bug in some WebSphere versions? Pool is an optimization, if this optimization has side effects and security flaws then just do not use WebSphere.

Posted by: Juozas | Oct 6, 2005 1:53:23 AM

The problem isn't with WAS itself or even unique to WAS. It's a problem in any managed environment that maintains a pool of threads for dispatching application work on. The problem is that WAS (or any other managed environment) can't know about YOUR threadlocals in order to clear them when the thread is returned to the pool. When the thread is retrieved from the pool for the next dispatch it will still have your threadlocals on it -- because there is no way for WAS to get at them. Thus it has to be the applications responsibility to clear its threadlocals from the thread at the end of the dispatch path.

Perhaps if the JDK provided something like a Thread.removeThreadLocalVars() then WAS and other managed environments could clear ALL the threadlocals, including user-defined ones, when the thread is returned to the pool. But until that's available it remains the app's responsibility to clear all its threadlocals at the appropriate time.

Posted by: Randy Schnier | Oct 10, 2005 10:43:39 AM

Actually the thread holds a list of all threadlocals and it would be possible to access this list via reflection in a managed environment.

Posted by: cm | Dec 6, 2005 8:26:47 AM

Hello Billy,
Here is a question about websphere thread pool arithmetic. I wonder wether it works as below:
I set the min.(MIN) and max.(MAX) number of thread pool of a server.
When a request comes, the server will check wether there is still alive thread in pool, if yes, it will return one, if not, it will create a new thread and return it.
When a response complete, the thread is return to the server, then the server will check the pool's size, if it already bigger than MAX, then it just destory the thread, otherwise, it will return it into the pool.

Another question is if I set the thread timeout for server, how the server deal with the thread which has reached its timeout?
Thank you.

Posted by: | Dec 6, 2005 2:23:58 PM

Hello Billy,
Here is a question about websphere thread pool arithmetic. I wonder wether it works as below:
I set the min.(MIN) and max.(MAX) number of thread pool of a server.
When a request comes, the server will check wether there is still alive thread in pool, if yes, it will return one, if not, it will create a new thread and return it.
When a response complete, the thread is return to the server, then the server will check the pool's size, if it already bigger than MAX, then it just destory the thread, otherwise, it will return it into the pool.

Another question is if I set the thread timeout for server, how the server deal with the thread which has reached its timeout?
Thank you.

Posted by: DAI Jun | Dec 6, 2005 2:25:37 PM

Hi Billy

Is Work Area Service of WAS 6.0 a safer way to implement what Threadlocal does?? Are we safe from Threads not being cleared after it is returned to the Thread pool. Are there any cautions we need to take care while using Work Area Service if my requirement is simply to maintain thread state just like Threadlocal minus the hassle.

Posted by: Ranjit Aneesh | Jan 9, 2007 6:11:53 AM

Tramadol is a Pain killer abused by many, Huraaa for being a pharmacy student.an effective pain reliever (analgesic). Its mode of action resembles that of narcotics, but it has significantly less potential for abuse and addiction than the narcotics.


http://tramadolcom.info





















Tramadol is a Pain killer abused by many, Huraaa for being a pharmacy student.

Posted by: woretes | Jun 2, 2007 6:49:49 AM

[url=http://www.spbgu.ru/blog33831#8]female domination video[/url]
[url=http://www.spbgu.ru/blog33832#3]amp domination submission[/url]
[url=http://www.spbgu.ru/blog33833#6]male foot fetish[/url]
[url=http://www.spbgu.ru/blog33834#8]my friends hot mom mrs vette[/url]

Posted by: derndecc | Jun 3, 2007 4:45:21 PM

Post a comment