• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Passing session-like data in Spring w/o sessions

 
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am using Axis, Spring and AspectJ to implement this. There are a few extra requirements: security, auditing, privileged access control.

1. Security is handled by the Axis wss4j plugin. This gets the user from the database and authenticates them. I would like to store the user's data somewhere where the next two steps will have access to it. And make it thread safe.

2. Auditing logs access and actions in the system. We need user data (userId) retrieved during step 1.

3. Each class/method has access privileges set on it. User roles need to be checked before the operation is allowed to continue. Roles are retrieved from the user data from step 1.

This is what the model looks like. For each request two things happen:
1. Axis -> Axis wss4j hander -> Spring (logic) -> dao getUser()
2. Axis -> Spring -> dao... (use user all over the place)

The hard part is since the system backs out all the way back to Axis, there is a kind of disconnect, I think.

The big question is where do I store the user object to pass it from the first lookup to the second? And once I get it into the second, how do I make it available to all beans and yet keep it thread safe?

Spring does not have a session type object that I can do something like session.setAttribute(user). I can put a user bean in the applicationContext, but wouldn't that make the bean not thread safe?

How do I do this? Any ideas?
 
Ranch Hand
Posts: 2713
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The easiest solution that jumps out to me here is to use a ThreadLocal. However, you need to be extremely careful when implementing this, especially since you are storing user information. The ThreadLocal must absolutely, regardless of exceptions, be cleaned at the end of each request to prevent the possibility of users from "leaking" across requests... this could be done using a Servlet Filter or other mechanism.
 
Rusty Enisin
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Is there nothing within Spring that allows for this? For such a large framework, I am surprised that there is nothing like a request object wherein I can store a common object.

Here are the ideas I have found so far:

1. ThreadLocal - This would work. Like you said, there is the extra task of cleanup. This could be handled with a filter very easily and it would be clean. It also should be thread safe considering each http request is put into a new thread. But, before I go off start messing with threads, I would like to explore more to see if there is any build in feature that I do not know about yet.

2. Use the servlet API's request object. Axis is built on Servlets. The wss4j plugin and the servlet endpoints in spring both have access to the servlet context. Using this I can bridge the gap between the two processes. But there is still no elegant way to make that user data available to the rest of spring and keep it thread safe.

What I am looking for is something in spring that looks like this:
<bean id="myThreadBean" singleton="true" threadsafe="true" class="com.company.User"/>

It would be nice to be able to say, true, I want a singleton, but only for this thread.
 
Chris Mathews
Ranch Hand
Posts: 2713
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Rusty Enisin:
It would be nice to be able to say, true, I want a singleton, but only for this thread.


That is exactly the purpose of ThreadLocals. Using a ThreadLocal is not the same as writing threading code... you don't touch the Thread class, you don't implement Runnable, and you aren't actually causing the creation of more threads in the application server. You are just tacking on contextual information for the current request onto the execution thread... very standard use, you just have to be careful that the ThreadLocal is being properly cleaned at the end of each request.
[ April 01, 2006: Message edited by: Chris Mathews ]
 
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi.

I'm trying to learn more about ThreadLocal, as I have a need for the "per-thread singleton" pattern, and so far, the only solution appears to be based on ThreadLocal. I hesitate to use it though, coz googling around on it, I read so many scary caveats about it. However, it certainly seems to fit the bill, so...

To further ensure that the ThreadLocal is "cleaned", couldn't you also set it to null or some such, at (or near) the logical beginning of the servlet (or web service) run?

By "logical beginning", I mean at some logical pinchpoint through which you know the app is going to pass? (i.e. not the init())

Ben
 
Ben Ethridge
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Speaking of googling this, if you google "per-thread singleton", the #1 google result is an article by Brian Goetz, titled "Threading lightly, Part 3: Sometimes it's best not to share":

http://www-128.ibm.com/developerworks/library/j-threads3.html

In it, he does a pretty good job of explaining high-level, what a per-thread singleton is and when/why you'd want to use such, but when I copied in his code:

--------------------------------------------
public class ConnectionDispenser {
private static class ThreadLocalConnection extends ThreadLocal {
public Object initialValue() {
return DriverManager.getConnection(ConfigurationSingleton.getDbUrl());
}
}

private ThreadLocalConnection conn = new ThreadLocalConnection();

public static Connection getConnection() {
return (Connection) conn.get();
}
}
----------------------------------------------

... it wouldn't compile. Never mind about the ConfigurationSingleton compile error. You can just null that out. The REAL compile error is in the conn.get(). Java complains (rightly so, I believe) that you cannot make a static reference to a non-static field.

I could, of course, "fix it up", but, since so many writers are saying to only use ThreadLocal if you really understand its subtleties, I would first need a clear explanation of when/why to use static here and when/why not to (i.e. the static inner classes and static methods).

Having passed the SCJP1.4, I'm somewhat familiar with static's, , but not how to apply them to something as apparently exotic as ThreadLocal. Unfortunately, Sun doesn't give a very good explanation in the api docs either:

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ThreadLocal.html

Of course, if I'm missing something simple about the broken code, please let me know.

Ben
 
Ben Ethridge
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, everyone.

I think I have part of the answer, maybe the whole answer. A google search on "static inner class ThreadLocal" returns a blog thread by Crazy Bob (who ain't so crazy sometimes ), that kind of explains why the inner class needs to be static for ThreadLocal use:

http://crazybob.org/2006/02/threadlocal-memory-leak.html

...basically it's "insurance" against memory leaks caused by strong references to the outer class, if I'm understanding this correctly.

That would mean that Mr. Goetz's code needs to be changed to this, in order to compile correctly:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Test {
private static class ThreadLocalConnection extends ThreadLocal {
public Object initialValue() {
Connection initConn = null;
try {
initConn = DriverManager.getConnection("someURL");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return initConn;
}
}

private static ThreadLocalConnection conn = new ThreadLocalConnection();

public static Connection getConnection() {
return (Connection) conn.get();
}
}

Using the above as a pattern, I created other such "Dispensers" for Spring objects (but not Connections), and they appear to run correctly. I say "appear", because I would still like some confirmation that I'm understanding this correctly from a second source (other that Crazy Bob). I would sure be nice if Sun or someone in authority would state why these need to be static, as I'm still having a bit of trouble visualizing it in relation to ThreadLocal.

In any case, as a side-benefit, using the above, I can do all my Spring stuff programattically, i.e. I'm not having to do anything in the Spring bean xml config files, but am still getting most of the benefit of the Spring classes.

Ben
 
Ben Ethridge
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thinking about this some more, why wouldn't most of the above code need to be sychronized?

Ben
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I found this thread interesting, and I'm trying to understand the meaning of it all. I understand the concept of thread local, and I understand how servlet filters might be used here. Would one of these be used for instance to pass a transaction instance if you started a transaction that would span several dao objects?
Also, does thread local stuff have to be synchronized?
 
Ranch Hand
Posts: 1491
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Rusty einsin, Spring supports security thru acegi. check-out this open source project http://www.acegisecurity.org/
 
Ben Ethridge
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is another forum discussion going on about this subject, that may help, at:

http://forum.springframework.org/showthread.php?t=24569

I pointed that thread to this one earlier, so now I'm pointing this one to that as well. Some of the Spring team have started to weigh in on the discussion now.

Ben
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic