aspose file tools*
The moose likes Struts and the fly likes When / How many of my ActionForm classes and Action classes are instantiated ? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Frameworks » Struts
Bookmark "When / How many of my ActionForm classes and Action classes are instantiated ?" Watch "When / How many of my ActionForm classes and Action classes are instantiated ?" New topic
Author

When / How many of my ActionForm classes and Action classes are instantiated ?

Timothy Toe
Ranch Hand

Joined: Oct 19, 2002
Posts: 156
When (at which point) my ActionForm classes and Action classes are instantiated ?
How many for each are instantiated in the server ?
If I send a request (submit a html page via http) to a server, I understand that, base on the request path, the ActionServlet will refer to the struts-config.xml file to know which ActionForm & Action class to instantiate.
What happens when another request comes in before the 1st one is completed ?
Can anyone help to shed some light on the issue of multithreading in Struts ?
Thanks.
Fabrizio Gianneschi
Ranch Hand

Joined: Nov 29, 2001
Posts: 70
ActionServlet is a servlet, so each request is served by a separate thread (except if you use the SingleThreadModel).
As I know, each thread creates new Action and ActionForm instances, so there're no concurrency problems.
They can occur only if you write unsynchronized static properties or methods on Action classes.
I'm sure the author could be more precise.


Fabrizio Gianneschi<br />SCPJ2, SCWCD, SCBCD
Timothy Toe
Ranch Hand

Joined: Oct 19, 2002
Posts: 156
I appreciate all replies to my question. Fabrizio Gianneschi, thanks. But more input from the others would be nice...
David Hibbs
Ranch Hand

Joined: Dec 19, 2002
Posts: 374
Originally posted by Fabrizio Gianneschi:
ActionServlet is a servlet, so each request is served by a separate thread (except if you use the SingleThreadModel).
As I know, each thread creates new Action and ActionForm instances, so there're no concurrency problems.
They can occur only if you write unsynchronized static properties or methods on Action classes.
I'm sure the author could be more precise.

Some errors in this...
a) SingleThreadModel is deprecated, as few servlet containers handled it properly anyway
b) The action servlet creates action instances as they are requested... but only ONE instance for each path. Thus, Action subclasses MUST be thread-safe or you'll get some very odd results!
c) Form instances are created based on the scope associated with the action.
scope=session: One form instance per session.
scope=request [default]: One form instance per request.

As a result, multithreading rules for struts are pretty simple.
Forms by their nature are not intended to be thread safe.
Keep your actions thread safe. Period.
If you stick to pure MVC, keeping your model out of your actions, you should have little problem keeping to these rules.


"Write beautiful code; then profile that beautiful code and make little bits of it uglier but faster." --The JavaPerformanceTuning.com team, Newsletter 039.
Fabrizio Gianneschi
Ranch Hand

Joined: Nov 29, 2001
Posts: 70
Originally posted by David Hibbs:

b) The action servlet creates action instances as they are requested... but only ONE instance for each path. Thus, Action subclasses MUST be thread-safe or you'll get some very odd results!

Yes, you're right, it was my fault! I did not know that... thanks a lot for the correction!
From Struts Documentation: http://jakarta.apache.org/struts/api/org/apache/struts/action/ActionServlet.html

"The standard version of RequestsProcessor implements the following logic for each incoming HTTP request. You can override some or all of this functionality by subclassing this object and implementing your own version of the processing.
1) Identify, from the incoming request URI, the substring that will be used to select an action procedure.
2) Use this substring to map to the Java class name of the corresponding action class (an implementation of the Action interface).
3) If this is the first request for a particular Action class, instantiate an instance of that class and cache it for future use.
4) Optionally populate the properties of an ActionForm bean associated with this mapping.
5) Call the execute method of this Action class, passing on a reference to the mapping that was used, the relevant form-bean (if any), and the request and the response that were passed to the controller by the servlet container (thereby providing access to any specialized properties of the mapping itself as well as to the ServletContext). "


Now I'm wondering WHY Struts programmers wrote a RequestProcessor with this behaviour , it's for sure an optimization (and a good one, I think) but it complicates the approach to the framework to newbies that don't know anything about threads.
Timothy Toe
Ranch Hand

Joined: Oct 19, 2002
Posts: 156
OK.. with these replies, I now know that the framework instantiates only 1 Action class for all requests. Only 1 Action class instance in the server for each <action> tag like this one below :

So I have only 1 instance of com.learnstruts.helloworld.RegistrationAction in the server to service all requests. This also means that I have to make sure that RegistrationAction is thread safe.
How about the Form class ? How many gets instantiated ? I guess it should be X number of Form instances if there are X number of requests. This is because each form needs to carry different values. Is my guess right ?
Thanks.
Kiran Kumar
Ranch Hand

Joined: May 18, 2001
Posts: 107
Hi,
Abt the Action Class, the RequestProcessor uses Lazy initialization technique wherein it creates an instance of the Action Class when it gets the request for that particular action and uses the same instance for all the subsequent requests. This is the reason why its recommended not to use any Class/Instance level variables in your Action Class. Makes use of only Local variable in your execute method of your action class to make sure that you dont have any Thread Synchronization issues.
Abt the Form, if the scope of the form bean is session, the action servlet(Might be the RequestProcessor here also, not sure, do check it out) creates the instance of the bean and puts the instance into the session for each user and then reuses the same instance for the whole of the session. but if the scope is request then a new instance is created each time a request is given for that particular form and for each user seperately.

hope this helps
[ March 22, 2004: Message edited by: Kiran Kumar ]

Thanks<br /> <br />Kiran <br /> <br />SCEA, SCJP 1.4,<br /> <br />"First they ignore u, then they laugh at u, then they fight u, <br />then u will win<br /> <br />Mahatma Gandhi"
David Hibbs
Ranch Hand

Joined: Dec 19, 2002
Posts: 374
Originally posted by Timothy Toh:
How about the Form class ? How many gets instantiated ? I guess it should be X number of Form instances if there are X number of requests. This is because each form needs to carry different values. Is my guess right ?

You're part right. See my first message...
Originally posted by David Hibbs:
Form instances are created based on the scope associated with the action.
scope=session: One form instance per session.
scope=request [default]: One form instance per request.

So it's either
N copies when scope=request where N is the number of requests
or
M copies when scope=session where M is the number of sessions
David Hibbs
Ranch Hand

Joined: Dec 19, 2002
Posts: 374
Originally posted by Fabrizio Gianneschi:

Now I'm wondering WHY Struts programmers wrote a RequestProcessor with this behaviour , it's for sure an optimization (and a good one, I think) but it complicates the approach to the framework to newbies that don't know anything about threads.

It's no better or worse than a servlet. Individual servlets need to be thread-safe as well; the servlet container creates only one instance of a servlet. Why should Struts try to do something different from what the Servlet Engine or J2EE spec do?
If you understand servlets, moving to actions should be no problem...
Timothy Toe
Ranch Hand

Joined: Oct 19, 2002
Posts: 156
Thanks for the answers guys.
I think many of you will agree with me : No place is better than JavaRanch - where you get to ask questions and get answers and at the same time get chances to win books !
Fabrizio Gianneschi
Ranch Hand

Joined: Nov 29, 2001
Posts: 70
Originally posted by David Hibbs:

Why should Struts try to do something different from what the Servlet Engine or J2EE spec do?

To simplify programmer's work. It's the n.1 reason when using a framework. I think default implementation should be thread safe, even if it's slower than the actual one.
Then, if there're performance problems, I could switch to a better solution (provided by the same framework, or manually)... pools, cache and so on.
...but that's only my opinion.
[ March 23, 2004: Message edited by: Fabrizio Gianneschi ]
Timothy Toe
Ranch Hand

Joined: Oct 19, 2002
Posts: 156
Could I just confirm this once and for all :
Servlet programming - need to make sure code is thread-safe
Struts Action class - need to make sure code is thread-safe also
Struts Form class - it's ok if it is not thread-safe
Thanks.
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4757
    
    7

I might be wrong but I seem to recall reading somewhere that although it is generally the case that you would have only one instance of an Action class, you shouldn't count on this since the web container itself may create more than one instance of a Servlet to improve performance--(does this have anything to do with the deprecation of the SingleThreadModel?). If this is true, there could be more than one instance of the ActionServlet and thus you could have more than one instance of a particular Action class. It would really not be advisable then to have member variables in your Action class as you'll never know which particular instance you'll get from one request to another.
David also mentioned that ActionForms, by their nature, are not meant to be thread-safe. Not exactly sure how to interpret that but it does seems to me that the framework guarantees that an ActionForm will be accessed by only one request thread at a time.


Junilu - [How to Ask Questions] [How to Answer Questions]
Timothy Toe
Ranch Hand

Joined: Oct 19, 2002
Posts: 156
although it is generally the case that you would have only one instance of an Action class, you shouldn't count on this since the web container itself may create more than one instance of a Servlet to improve performance

Also, although we are able to see the source, we should program base on the "contract" and not what we get to know from the code... as with all abstractions/encapsulations, the underlying implementation could change.
From the discussion above, I guess the struts "contract" says the action class must be thread-safe.
I think Junilu Lacar is right when he/she said "you shouldn't count on this".
Thanks for the input Junilu.
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4757
    
    7

Originally posted by Timothy Toh:

I think Junilu Lacar is right when he/she said "you shouldn't count on this".
Thanks for the input Junilu.

He.
[ March 24, 2004: Message edited by: Junilu Lacar ]
roul ravashimka
Ranch Hand

Joined: Mar 16, 2004
Posts: 53
hi,
i'm using a service locator in my Action(Struts)to contact my ejb's. thanks to all the previous posts, i know why the service locator is threadsafe, so why the cache can't be used by multiple requests or actions, thanks you all.
but i still got one question about my service locator in my ejb-layer.
What if in the ejb-container two or more clients use the cache?
Maybe this is not the place to talk about ejb's.
But i've posted this question earlier at :Service Locator
So, if someone here knows the answer, please help me with this problem.
Thanks,
Roul


MSc Electronics, ICT
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: When / How many of my ActionForm classes and Action classes are instantiated ?