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