You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Wolfgang Gehner <ne...@infonoia.com> on 2005/09/23 09:49:57 UTC

Thread-unsafe Command classes

Hi there,

I keep telling people that 1.3 allows out of the box to execute ANY 
ARBITRARY CLASS via command=, catalog= and chain-config, as long as it 
implements the command interface. If those classes have to be 
tread-safe, like old actions had to be, that is not entirely true.

Any idea how to configure non-thread-safe commands (i.e. that have 
instance variables outside methods) in Struts 1.3, even if they are not 
perfect commands (Commons-chain says that catalog.getCommand will reuse 
instances).

How about overriding ExecuteCommand to create new instances if some 
action-mapping parameter is present, and how to (a question to 
commons-chain).

That should also be made VERY evident in the Docs.

We are just deploying a 400 screens application we wrote on Struts 1.3, 
and it works great! of course our commands are all thread-safe.

Kind regards,

Wolfgang Gehner



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: Thread-unsafe Command classes

Posted by Ted Husted <te...@gmail.com>.
On 9/23/05, Joe Germuska <Jo...@germuska.com> wrote:
> I've recently been designing applications so that per-action-path
> commands are retrieved from Spring rather than from the default
> commons-chain CatalogFactory.  This then makes the lifecycle of the
> command an external property (based on the "singleton" attribute of a
> <bean> element in a Spring beans XML file.)

We've been using a C# port of Commons Chain that uses Spring to load
the Catalog and run the Chains, instead of the Digester. Works great!

We're also using Spring.Web to load other objects. By using Spring to
load Commands, we end up with a single set of configuration files that
exposes all the objects we using under one XML schema. The exception
right now is iBATIS.NET. But, I don't see why we couldn't load that
object graph with Spring.Net too, so that we have one configuration to
rule them all.

> Of course this required custom request processing commands, since
> Struts 1.3 doesn't have direct dependencies upon Spring.

I keep thinking that we should be able to make object-graph loading
pluggable, like Shale is starting to do with Spring versus the JSF
bean manager. This is something we could look at in the Struts Core
1.5 series, when we plan to "Consider refactoring for Spring."

* http://struts.apache.org/milestones.html

Here, where we say "Spring", I read it to say "dependency injection",
since if we do this, I think we can do it through pluggable interfaces
so that there is not a hydraulic dependency on Spring per se.

> The best thing I think would be to write a command which instantiated
> this other arbitrary class, extracting properties from the Context to
> pass to the "main" method of the arbitrary class and interpreting the
> return appropriately (possibly modifying the Context as well.)

+1

On 9/24/05, Joe Germuska <Jo...@germuska.com> wrote:
>Those are concerns for  commons-chain.

+1

> What we should do in the Struts core is make sure that things are
> properly designed for easy extensibility.

+1

Personally, I also believe that we should try harder to encourage
people to move as much application logic as possible out of Struts and
into a separate business or application layer.

The point of using Commons Chain as the basis for Struts Core is *not*
to make it easier for us to put more business logic into
Struts-centric Actions or Commands. (And I'm *not* implying that
anyone in this thread is encouraging that practice.)

The point of using Commons Chain is to make the Struts Core easier to
extend and customize so that we can do less work in Actions. As a
framework, an important goal should be to make it easier for us to
draw a firm line between Struts and the rest of our applications.

Just as Struts Core uses Commons Chain to create it's own internal
application layer, we encourage other teams to use Commons Chain -- or
XWork, or POJOs -- to create their own internal application layer --
clearly separate and distinct from Struts. We should not be writing
applications with Struts Core, we should be writing application *into*
Struts Core, so that it's easier to write them into something else as
well. (Like say, a unit testing suite!)

Which I think is my queue to put some volunteer time into improving
MailReader :)

-- HTH, Ted.
http://www.husted.com/poe/

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: Thread-unsafe Command classes

Posted by Joe Germuska <Jo...@Germuska.com>.
The point I was trying to make is that using "command" and "catalog" 
to look up a per-action-path command to execute should leave Struts 
out of any concern for the lifecycle of the Command classes; the 
implication of those attributes is that the command will be looked up 
from a CatalogFactory, and it's not up to Struts how that 
CatalogFactory manages its commands.  Those are concerns for 
commons-chain.

>Re the singleton issue: I think you suggest to override the "bridge" 
>ExecuteCommand class that will do singleton/non-singleton based on 
>an input parameter that could be specified in ActionMapping. 
>Flipping out old ExecuteCommand is a cinch with 1.3 struts-chain.xml

Yes, this is more or less what I have in mind.  I would probably use 
the arbitrary config property feature new in Struts 1.3 to set a 
property on an ActionConfig, and then have ExecuteCommand or another 
command look at that property for a potential class name.  If it 
found one, it would instantiate the class and cast it to Command, and 
then execute it with the active ActionContext.

I'm just not sure that I believe this belongs in Struts right now. 
Struts 1.3 is setting up to be so flexible that it would be possible 
to throw a million different ways of doing things into the core, and 
I think that would just confuse things; however, I believe that its 
flexibility is such that users who want that kind of behavior will 
find it extremely simple to implement it themselves.  For now I think 
we should let that kind of experimentation go on amongst users and 
watch for a while to see which solutions really catch on.  I'm 
particularly hesitant to go adding new details to the DTD while 
things are so fluid and subject to change, but again, those arbitrary 
config properties mean that we don't have to.

What we should do in the Struts core is make sure that things are 
properly designed for easy extensibility.  In this case, 
ExecuteCommand has a protected getCommand(ActionContext) method which 
provides a good place for this kind of customization, roughly as such:

// override base impl
protected Command getCommand(ActionContext ctx) {

   String type = context.getActionConfig().getProperty("COMMAND_CLASS_NAME");
   if (type == null) return super.getCommand(ctx);

   return (Command) ClassUtils.getApplicationInstance(type);

}

I encourage you and lots of other Struts 1.3 explorers to go off and 
do things this.  Where Struts 1.3 will need to be bolstered is not in 
making a lot of specific changes to the core command set, but rather 
in finding where Struts 1.3 makes doing this yourself harder than it 
should be.  It looks like this one is good, but perhaps some other 
commands could be refactored to better expose specific behavior as 
extension points, and I suspect over time people will become a bit 
annoyed at manually maintaining a chain-config.xml which diverges 
from the Struts base distribution.   I'm sure there will be other 
things that I haven't even thought of, and I'm really excited that 
people are starting to build 1.3 apps and will be providing more 
real-world feedback about it.  We've got three in production right 
now and more on the way, but they are all designed in basically the 
same way, so I'm looking forward to seeing where other people go with 
it.

Joe
-- 
Joe Germuska            
Joe@Germuska.com  
http://blog.germuska.com    
"Narrow minds are weapons made for mass destruction"  -The Ex

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: Thread-unsafe Command classes

Posted by Wolfgang Gehner <ne...@infonoia.com>.
If I want to use Spring I use Spring MVC, but I think a lot of drive in 
Struts evolution is to encorporate nice ideas that have come up as 
techniques elswhere over the last years, see Struts TI. So Struts 
developers won't *have to* use Spring on top or instead. (I am not 
convinced that TI should use/depend on Spring).

I think CoR with Chains is great and simple for declaratively linking 
things as of Struts 1.3. I also think CoR is a more beautiful pattern 
than IoC for a lot of people. I also think there is a great bang in 
using the execute(context) interface rather than execute(mapping, req, 
res etc). I have written commands rather than actions for 8 months now 
and I don't miss old actions a bit.

I still  like the behavior of a class inside the class. When you have an 
execute hook you probably need less understanding of the class 
implementation and how possibly inject stuff otherwise. At least not 
YACF (yet another config file) - cf. Ruby on Rails. Also think of 
.execute(context) as an entry comparable to a main method.

If I need to create an adapter class to run particular logic, I could do 
that with plain old actions.
There may still be cases where IoC is really needed, but with Struts 1.3 
as tool I just I don't come across them that often.

Another advantage of using the command interface is if I find that some 
command is generic to an application I can add them to the defautl 
struts chain, rather than wiring through a custom base-command class. 
Which really leverages the new chain architecture of Struts! Finally we 
can change the default behavior of the Struts cycle. It has the 
potential to wire stuff for all kinds of apps, including remote. Now 
that's a great bang!

Could you imagine having rewritten the struts request processor with 
spring IOC?

Re the singleton issue: I think you suggest to override the "bridge" 
ExecuteCommand class that will do singleton/non-singleton based on an 
input parameter that could be specified in ActionMapping. Flipping out 
old ExecuteCommand is a cinch with 1.3 struts-chain.xml

Or add that as a feature as in a type="com.xx.MyCommand@singleton" 
attribute. Right now I think "instance" should be the default attribute.
 From the experience that non-thread-save classic Actions are a typical 
newbie error, which can lead to catastrophic behavior of the application.

Wolfgang


Joe Germuska wrote:

> I've recently been designing applications so that per-action-path 
> commands are retrieved from Spring rather than from the default 
> commons-chain CatalogFactory.  This then makes the lifecycle of the 
> command an external property (based on the "singleton" attribute of a 
> <bean> element in a Spring beans XML file.)
>
> Of course this required custom request processing commands, since 
> Struts 1.3 doesn't have direct dependencies upon Spring.
>
> More to the point, though, I don't think there's really that much 
> "wow" to saying that Chain can "execute any arbitrary class" -- even 
> "executing a class" implies that the class implements Command, and 
> then its not arbitrary any more.
>
> The best thing I think would be to write a command which instantiated 
> this other arbitrary class, extracting properties from the Context to 
> pass to the "main" method of the arbitrary class and interpreting the 
> return appropriately (possibly modifying the Context as well.)
>
> This is basically how the Chain deals with Struts Actions right now; 
> it's an unimportant detail that the Struts Actions are pooled and not 
> created each time, but the point is that rather than modifying Action 
> to implement Command,we wrote a bridge Command.  If your arbitrary 
> class isn't threadsafe, rather than modifying that arbitrary class to 
> implement Command you should write a complementary Command which knows 
> how to use that class in a threadsafe manner.
>
> Make sense?
>
> Joe
>
>
>
> At 9:49 AM +0200 9/23/05, Wolfgang Gehner wrote:
>
>> Hi there,
>>
>> I keep telling people that 1.3 allows out of the box to execute ANY 
>> ARBITRARY CLASS via command=, catalog= and chain-config, as long as 
>> it implements the command interface. If those classes have to be 
>> tread-safe, like old actions had to be, that is not entirely true.
>>
>> Any idea how to configure non-thread-safe commands (i.e. that have 
>> instance variables outside methods) in Struts 1.3, even if they are 
>> not perfect commands (Commons-chain says that catalog.getCommand will 
>> reuse instances).
>>
>> How about overriding ExecuteCommand to create new instances if some 
>> action-mapping parameter is present, and how to (a question to 
>> commons-chain).
>>
>> That should also be made VERY evident in the Docs.
>>
>> We are just deploying a 400 screens application we wrote on Struts 
>> 1.3, and it works great! of course our commands are all thread-safe.
>>
>> Kind regards,
>>
>> Wolfgang Gehner
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
>> For additional commands, e-mail: dev-help@struts.apache.org
>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: Thread-unsafe Command classes

Posted by Joe Germuska <Jo...@Germuska.com>.
I've recently been designing applications so that per-action-path 
commands are retrieved from Spring rather than from the default 
commons-chain CatalogFactory.  This then makes the lifecycle of the 
command an external property (based on the "singleton" attribute of a 
<bean> element in a Spring beans XML file.)

Of course this required custom request processing commands, since 
Struts 1.3 doesn't have direct dependencies upon Spring.

More to the point, though, I don't think there's really that much 
"wow" to saying that Chain can "execute any arbitrary class" -- even 
"executing a class" implies that the class implements Command, and 
then its not arbitrary any more.

The best thing I think would be to write a command which instantiated 
this other arbitrary class, extracting properties from the Context to 
pass to the "main" method of the arbitrary class and interpreting the 
return appropriately (possibly modifying the Context as well.)

This is basically how the Chain deals with Struts Actions right now; 
it's an unimportant detail that the Struts Actions are pooled and not 
created each time, but the point is that rather than modifying Action 
to implement Command,we wrote a bridge Command.  If your arbitrary 
class isn't threadsafe, rather than modifying that arbitrary class to 
implement Command you should write a complementary Command which 
knows how to use that class in a threadsafe manner.

Make sense?

Joe



At 9:49 AM +0200 9/23/05, Wolfgang Gehner wrote:
>Hi there,
>
>I keep telling people that 1.3 allows out of the box to execute ANY 
>ARBITRARY CLASS via command=, catalog= and chain-config, as long as 
>it implements the command interface. If those classes have to be 
>tread-safe, like old actions had to be, that is not entirely true.
>
>Any idea how to configure non-thread-safe commands (i.e. that have 
>instance variables outside methods) in Struts 1.3, even if they are 
>not perfect commands (Commons-chain says that catalog.getCommand 
>will reuse instances).
>
>How about overriding ExecuteCommand to create new instances if some 
>action-mapping parameter is present, and how to (a question to 
>commons-chain).
>
>That should also be made VERY evident in the Docs.
>
>We are just deploying a 400 screens application we wrote on Struts 
>1.3, and it works great! of course our commands are all thread-safe.
>
>Kind regards,
>
>Wolfgang Gehner
>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
>For additional commands, e-mail: dev-help@struts.apache.org


-- 
Joe Germuska            
Joe@Germuska.com  
http://blog.germuska.com    
"Narrow minds are weapons made for mass destruction"  -The Ex

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org