You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Jakob Ericsson <ja...@gmail.com> on 2009/02/26 17:03:44 UTC

session.isNew() not thread safe?

Hello,

We are experiencing some thread/race condition problems with
HttpSession isNew() for Tomcat 6 (specifically for 6.0.18 but we have
seen the problem in prior versions too).
We narrowed it down to a small example.

The flow is quite simple.

1. Request first.jsp
2. Request second.jsp

Randomly we get the text "This should not happen, the session should
not be new on this page" printed out.
We are using jMeter to generate load, running 150 concurrent users.

Page first.jsp:
---------------------
<%
    session.setAttribute("sessionTest", "test");
%>
<html>
  <head><title>Session is New Test</title></head>
  <body>Page one sets a value one the session.</body>
</html>
---------------------

Page second.jsp:
---------------------
<%
    boolean newSession = false;
    if (session.isNew()) {
        if (session.getAttribute("sessionTest") != null) {
            newSession = true;
            System.out.println("This should not happen, the session
should not be new on this page.");
        }
    }
%>
<html>
  <head><title>Session is New Test</title></head>
  <body>Page to two the session should not be new, isNew =
<%=newSession%></body>
</html>
---------------------

Our feeling is that this is a race condition between threads before
tomcat set isNew to false.
A quick workaround is to use request.getSession(false) and null
checks. This seems to get us around our specific application problem.

Could this be a problem in Tomcat?

Regards,
Jakob Ericsson

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: session.isNew() not thread safe?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Chuck,

On 3/2/2009 5:11 PM, Caldarale, Charles R wrote:
>> From: Christopher Schultz [mailto:chris@christopherschultz.net]
>> Subject: Re: session.isNew() not thread safe?
>>
>> You can't even throw an object into the session to be
>> used as a monitor
> 
> Actually you can - you just need to do it with an HttpSessionListener
> when the HttpSession is first created, before any additional threads can
> get their paws on it.

That's a good point. I hadn't really thought of that for some reason.
You could put something in there like SYNCHRONIZATION_MONITOR and then
use it all the time.

If you needed another object for distinct synchronization (say, some
other process that shouldn't be synchronized with the rest of your
stuff), you could use that monitor to safely create another monitor.

Thanks for the suggestion.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEUEARECAAYFAkmsXYIACgkQ9CaO5/Lv0PCLTgCY7MHB6PWOMuM/fg3Ly2YmCJaS
mACgji3UBfSeJQsTsENSUMwCB0P2IHQ=
=itdt
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: session.isNew() not thread safe?

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Christopher Schultz [mailto:chris@christopherschultz.net]
> Subject: Re: session.isNew() not thread safe?
>
> Thus, you cannot guarantee that using the session object itself for
> synchronization (like doing "synchronized(session) { ... }"
> in your code will give you exclusive access to your session object.

Correct, which is another reason why Karl San Gabriel's suggestion was not only nonsense, but dangerous.

> I'm not entirely convinced this exclusive access is necessary,
> since mostly people are doing set/get attribute calls and those
> will be fine.

It's only necessary when you need to take an additional (usually one-time) action based on the presence of some attribute in the session; in that case, synchronization on something else common to the servlets of the webapp is necessary.

> You can't even throw an object into the session to be
> used as a monitor

Actually you can - you just need to do it with an HttpSessionListener when the HttpSession is first created, before any additional threads can get their paws on it.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: session.isNew() not thread safe?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Chuck,

On 3/2/2009 1:54 PM, Caldarale, Charles R wrote:
>> From: Karl San Gabriel [mailto:karl.sangabriel@gmail.com]
>> Subject: Re: Re: session.isNew() not thread safe?
>>
>> Session object is not thread-safe.
> 
> Please don't post false information - do your homework. To quote from
> 7.7.1 of the servlet spec:
> 
> "Multiple servlets executing request threads may have active access
> to the same session object at the same time. The container must ensure that
> manipulation of internal data structures representing the session
> attributes is performed in a thread safe manner."

Interestingly enough, the specification doesn't say that the session
object itself is threadsafe. It just says that the internal structure of
the object has to remain sane under threaded conditions.

That sounds like a stupid distinction, but consider this:

1. setAttribute and getAttribute must certainly be threadsafe (that is,
multiple threads doing get/sets on the attribute hash won't corrupt each
other). Otherwise, webapps would fail all the time.

2. The object returned by Tomcat for a call to
HttpServletRequest.getSession() is a
org.apache.catalina.session.StandardSessionFacade.

3. StandardSession.getSession() is unsynchronized and creates instances
of StandardSessionFascade wrapping 'this' and stores them in a member.

Thus, you cannot guarantee that using the session object itself for
synchronization (like doing "synchronized(session) { ... }" in your code
will give you exclusive access to your session object. I'm not entirely
convinced this exclusive access is necessary, since mostly people are
doing set/get attribute calls and those will be fine.

But, if you wanted exclusive access to the session (say, to increment
the number of requests handled by the session and store that variable in
the session), I don't believe there is a way to ensure that the count is
correct. There is always a race condition because the session itself
cannot be used as a monitor.

You can't even throw an object into the session to be used as a monitor
because you'll have to check to make sure the monitor object is null,
then shove one into the session, and you can't guarantee that all
threads will see the null and then use the new object in the session
attributes.

Of course, all this is pretty much academic, since once the
StandardSessionFacade object has been created (or you stick a monitor
object in the session attributes), everything is fine after that.

But the point is that you can't just say "synchronized(mySession) { ...
}" and expect no surprises at all.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkmsVY8ACgkQ9CaO5/Lv0PCy0QCglTwRqoLZASK51zDLJ49iBcWN
hTEAoLB5TfQcqX5/sBSS9duKQ+ipe6yJ
=zJiq
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: Re: session.isNew() not thread safe?

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Karl San Gabriel [mailto:karl.sangabriel@gmail.com]
> Subject: Re: Re: session.isNew() not thread safe?
>
> Session object is not thread-safe.

Please don't post false information - do your homework.  To quote from 7.7.1 of the servlet spec:

"Multiple servlets executing request threads may have active access to the same session object at the same time. The container must ensure that manipulation of internal data structures representing the session attributes is performed in a thread safe manner."

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Re: session.isNew() not thread safe?

Posted by Karl San Gabriel <ka...@gmail.com>.
Hi Jakob,

Session object is not thread-safe. It's better put the session object in 
a synchronized block.

Regards,
Karl San Gabriel

Tim Funk wrote:
> <div class="moz-text-flowed" style="font-family: -moz-fixed">Sort of 
> (if I read the code correctly)
>
> isNew is set to false after the response is finished. So if you have 2 
> concurrent requests running, isNew is true until the first request 
> finishes sending its response back to the client. Of course isNew 
> could be set to false if the second request finishes its response 
> faster than the first request. In which case, the first request could 
> have isNew set=true only later have it be set to be false.
>
> -Tim
>
>
> Jakob Ericsson wrote:
>  > Our feeling is that this is a race condition between threads before
>> tomcat set isNew to false.
>> A quick workaround is to use request.getSession(false) and null
>> checks. This seems to get us around our specific application problem.
>>
>> Could this be a problem in Tomcat?
>
> </div>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: session.isNew() not thread safe?

Posted by Tim Funk <fu...@joedog.org>.
Sort of (if I read the code correctly)

isNew is set to false after the response is finished. So if you have 2 
concurrent requests running, isNew is true until the first request 
finishes sending its response back to the client. Of course isNew could 
be set to false if the second request finishes its response faster than 
the first request. In which case, the first request could have isNew 
set=true only later have it be set to be false.

-Tim


Jakob Ericsson wrote:
  > Our feeling is that this is a race condition between threads before
> tomcat set isNew to false.
> A quick workaround is to use request.getSession(false) and null
> checks. This seems to get us around our specific application problem.
> 
> Could this be a problem in Tomcat?


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org