Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Synchronizer Token: for the J2EE pattern book authors ...  RSS feed

 
Dani Mazzuca
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I have a question for the J2EE pattern book authors (I don�t want to be considered for the book promotion, because I already bought the second edition).
It is about Synchronizer Token code (Example 4.4, Check for a valid Token, page 70). I think this code has problems and that it might happen duplicate request submission if the access is not synchronized over, for example, a session object. IMHO, to correct this problem the code should be something like this:


I will appreciate the author comments,
Dani
 
Dan Malks
Author
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Dani,
Your question assumes an atypical use case, which is to say that it assumes concurrent requests on the same session.
While this can certainly happen, it's dependent on some specific browser configurations and layout designs (ie: which browser versions perpetuate same session when a new window is forked, whether frames are used, etc).
As you know the synchronizer token is stored on the server and in the HTML form and typically we haven't seen many enterprise applications with concurrent (ie: multiple threads) invocations that share the same HTTP session.
AFAI can tell, your suggestion is a valid approach in the case where there indeed are multiple threads invocations that share the same session.
Did you have a use case in mind or are you asking from a theoretical standpoint?
BTW, for those who are not familiar with the Synchronizer Token, there are multiple discussions in our book, Core J2EE Patterns, 2nd ed., including a refactoring that discusses how to introduce it into your architecture after things have already taken shape...the core concept is that of using a shared token to control and monitor requests through the application, so that duplicate submissions (such as could occur if the user clicks the browser "back" button and then clicks "submit" multiple times) can be disallowed. It is a common issue and one that is built in to the Struts framework from Apache. The book has lots more coverage for those who want to investigate further.
Thanks for the question,
Dan
www.corej2eepatterns.com
Co-Author of Core J2EE Patterns: Best Practices and Design Strategis
 
Dani Mazzuca
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Dan Malks,
My point of view is just purely practical. Note that it is not
needed to open two browser windows or set a special browser
configuration to simulate multiple threads invocations that
share the same session. In real life, the only thing a user should do is,
instead of simple-click, just double-click an HTML form submit
button of a servlet service that takes some time to process
(simulate that entering a for (int i = 0 ; i < 100000000 ; ++i);
at the beginning of the service method), and voila, you have two threads
fired that share the same session. Double-clicking is a common case for
some real Internet beginner users, when the request takes some time
to process. Moreover, this is exactly the case we should avoid,
"multiple submission", and it is not acceptable
if you are dealing with transactions that debits money, etc.
Also, a similar real life case occurs when, because some network problem,
the first request is delayed, and the user presses the back button,
and resubmits the request, starting two simultaneous threads.
I am actually worried about that, because I found the same code
solution (that comes from the first version of Struts), published
in many learning books, and many readers can be using it without
noting that, IMHO, the code doesn't guaranty a free-double-submission
solution for some real/practical cases.
Again, I will appreciate your comments. Thank you in advance,

Dani
 
Dan Malks
Author
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Dani,
The multi-frame/multi window issue aside, you have a good point.
The original Struts code that we use in our example is dated and does not include the most recent code (from Struts 1.1 RC2 and 1.1 Final version), where the synchronizer token logic has been moved into a utility class called TokenProcessor, with synchronized methods and the ability to remove the attribute during the validity check.
This addresses the concerns wrt the multiple quick click scenario.
Another interesting side note is that apparently the container may return different instances of a session object when multiple threads within the same session do request.getSession(), in which case the sample code you offered would not work as expected. In other words, using the session object as the lock for the synchronization will not work as expected if there are different session instances in play.
We'll be updating this example code to reflect Struts 1.1 Final.
Also, we'll expand a bit more on the discussion of this issue for those building their own mechanisms and certainly appreciate your input.
Thanks again,
Dan Malks
 
Dani Mazzuca
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Dan,
Please, could you clarify the following point?
Another interesting side note is that apparently the container may return different instances of a session object when multiple threads within the same session do request.getSession(),

I think this is not possible. Moreover, I think this is against
the basis of sessions described in the specifications. Even in a
distributed web application, the HttpSession object must be placed
in only one JVM at a time (it may also migrate).
In which cases the container may create different session objects for
requests that "participate in the same session" ?

BTW, I was reading the code of Struts 1.1 final version, and at first
glance, I think it might have severe performance problems, because the
TokenProcessor methods are synchronized over the singleton instance of
itself. This means, that simultaneous requests from different users of
the same Web application, or even from users of different web applications
running on the same JVM, will compete from the same TokenProcessor object
each time they need to process isTokenValid. We should synchronize
request that comes only from the same session, not from different sessions
or even different applications. I found the Struts final 1.1 solution
not an appropriate approach.
Again, I appreciate your help
Dani
 
Dan Malks
Author
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Dani,
In response to your statement:
I think this is not possible. Moreover, I think this is against
the basis of sessions described in the specifications.

Just want to reiterate, the Servlet spec does not mandate that the getSession() method return the same session instance, so your code will not work...ie: the session should not be used as the lock. The session will relate to the same session info of course, but may not be the same instance.
Hope this helps clarify.
Take care.
 
Dani Mazzuca
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Dan,
No problem if there are some rare cases when synchronization
over the session object fails (because we are not guarantied of
the uniqueness of session objects). We can easily correct this
creating an object, say TokenSynchronizer, per session
(maybe with the help of HttpSessionListener), set TokenSynchronizer
object as an attribute of the session, and synchronize over this
object instance in the isTokenValid method.
I insist, although the new Struts final 1.1 token mechanism
implementation works, it is actually synchronizing over only
one object per JVM. This might cause several performance problems
in a big system that might make intensive use of the token facility.
Dani
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!