You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Joe Germuska <Jo...@Germuska.com> on 2005/03/11 03:10:30 UTC

Storing current ActionContext in ThreadLocal

So, I was just about to add support for static access to the 
"current" ActionContext using ThreadLocal, and then I realized that 
this approach is more commonly used with classes than with interfaces.

Since ActionContext is an interface, we'd have to do something like this:

public static final ThreadLocal currentInstance = new ThreadLocal();

Is it too weird to have this as a public member?  Is there some 
artful way to hide it more?  Of course, we'd have
public static void setCurrentInstance(ActionContext ctx)
and
public ActionContext getCurrentInstance()

but I'm sketched out at having to leave the member itself public.

That said, I'm still happier with ActionContext as an interface than 
an abstract class.

Any words of wisdome, or should I just go ahead and do this?

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


Best Way to use Custom ActionContext/Storing ActionContext in ThreadLocal

Posted by Joe Germuska <Jo...@Germuska.com>.
Trying to unify these two threads:

"How to provide custom impl of ActionContext" 
http://thread.gmane.org/gmane.comp.jakarta.struts.devel/25876

"Storing current ActionContext in ThreadLocal" 
http://thread.gmane.org/gmane.comp.jakarta.struts.devel/25868

It would be great to get some ideas from people about the right way 
to allow users to use an alternate implementation of the 
ActionContext class.  I am generally ill-disposed to a factory class 
since it seems like so often factories also need configuration which 
makes discovery tedious, but having a factory class which was an 
Abstract class would also give us a convenient place to plug a static 
"currentActionContext" method.

If no configuration is necessary, we could simply stipulate 
"actionContextFactoryClass" as a String Property of ControllerConfig 
and at least move forward with that.  To be honest, for this specific 
case I'm not thinking of any configuration use cases, so maybe I 
shouldn't get hung up on it.

(Defining implementation classes and configuring them all in one 
place is the solution that Spring provides which I think makes so 
many people get so gung-ho about it.)

I think in writing this I've convinced myself to do it this way. 
Will give it a little time for responses but I'm likely to try to do 
this in the next couple of days.

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: Storing current ActionContext in ThreadLocal

Posted by Joe Germuska <Jo...@Germuska.com>.
At 12:11 AM -0500 3/12/05, Paul Speed wrote:
>Joe Germuska wrote:
>
>>So, I was just about to add support for static access to the 
>>"current" ActionContext using ThreadLocal, and then I realized that 
>>...
>>...snip...
>>... member?  Is there some artful way to hide it more?  Of course, we'd have
>>public static void setCurrentInstance(ActionContext ctx)
>
>Why not just put the ThreadLocal the same place you put these 
>methods wrapping it?  Interfaces can't have static methods so you'll 
>have to have it on some concrete class somewhere, yes?
>-Paul

Um. yeah, good point.  I didn't think that through.

Still, if by "these methods wrapping it" you mean the 
ComposableRequestProcessor (which is currently in charge of 
instantiating an ActionContext)... that doesn't seem right.

ActionContext could have an inner class which implements holding 
behavior, reachable as a singleton static field.  This seems a bit 
overwrought too, but it would work.

public interface ActionContext extends Context {

    public static final ContextHolder = new ContextHolder();
    public static final Class ContextHolder {
       private ContextHolder() { }
       public ActionContext getCurrentContext() {}
       public void setCurrentContext(ActionContext) { }
}

If we had an "application-level" counterpart to the ActionContext 
(the app "API bean" which has been discussed here before), I think 
I'd be more willing to make that an abstract class, and then it might 
be a good place to put a static method for this.

I've wanted that API bean for a while, so I think I'm going to 
consider it for a bit, especially because this ThreadLocal idea is 
not something people have been aggressively clamoring for.

>I haven't caught up yet on the chain implementation.  We have
>ActionContext as an interface.  Is there going to be a way to let the
>user provide a different instance, or is extending
>ComposableRequestProcessor the recommended approach?  If a factory is
>created to produce ActionContext instances, the getCurrentContext()
>method can be placed there, reducing the "arbitrary" vibe.

That does solve two problems; right now the way of choosing an 
alternate ActionContext implementation is to extend 
ComposableRequestProcessor and override the "contextInstance()" 
method.  A factory didn't seem necessary, although I think that 
you've just raised a pretty good use case for moving the 
instantiation responsibility out to a Factory which could serve these 
two purposes.  I'm not convinced yet, but I'm definitely interested 
in thinking about it.

In general, I find bootstrapping Factory processes kind of tedious 
when you have to get down to reading properties files in and such; I 
was pursuing it for a while using commons-discovery for day-job 
projects but once I started seeing good IoC containers, I dropped it 
cold.  In this specific case, I don't know that there is much need 
for configuring the factory, so we could just put the factory class 
name as a <controller> attribute (or return to the idea of nesting a 
<request-processor> attribute in the <controller>.

Of course now this all reminds me of some of my general 
dissatisfactions with the current Struts config process -- but I 
don't want to get stuck on that again!  I think the API bean musings 
will bump up against the same question.

But since this isn't a burningly important feature, I'm happy to let 
it bump around for a while and see what people think.

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: Storing current ActionContext in ThreadLocal

Posted by Hubert Rabago <hr...@gmail.com>.
On Fri, 11 Mar 2005 11:22:54 -0600, Joe Germuska <Jo...@germuska.com> wrote:
> At 10:08 AM -0600 3/11/05, Hubert Rabago wrote:
> >What about using a different class to host the ThreadLocal?
> >
<snip/> 
> It seems arbitrary to me, and more of a burden than simply having a
> public static ThreadLocal which most people would ignore -- but if
> others prefer this approach, I wouldn't fight it.
> 

I was actually thinking of "Log log = LogFactory.getLog();", although
I admit there tons more differences than similarities.

Just to be clear, I'm not pushing this approach, just discussing it.  

On the initial idea, where you'd declare the ThreadLocal on the
interface - did you mean the accessors would be on the ActionContext
interface as well?  If so, an implementation may choose a different
way to provide a result, ignoring the ThreadLocal declared on the
interface, right?

I haven't caught up yet on the chain implementation.  We have
ActionContext as an interface.  Is there going to be a way to let the
user provide a different instance, or is extending
ComposableRequestProcessor the recommended approach?  If a factory is
created to produce ActionContext instances, the getCurrentContext()
method can be placed there, reducing the "arbitrary" vibe.

> >The instance would be set by the RequestProcessor at the start of the
> >chain after the context is created.
> 
> Yes, no matter where we store the ActionContext, my intent would be
> to set this in process() right after contextInstance(...).
> 
> 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: Storing current ActionContext in ThreadLocal

Posted by Joe Germuska <Jo...@Germuska.com>.
At 10:08 AM -0600 3/11/05, Hubert Rabago wrote:
>What about using a different class to host the ThreadLocal?
>
>public void pojoActionMethod() {
>
>     ActionContext ctx = ActionContextHolder.getActionContext();
>     if (...) { ctx.setForwardConfig(ctx.getMapping().findForward("a")); }
>     else { ctx.setForwardConfig(ctx.getMapping().findForward("b")); }
>}

It seems arbitrary to me, and more of a burden than simply having a 
public static ThreadLocal which most people would ignore -- but if 
others prefer this approach, I wouldn't fight it.

>The instance would be set by the RequestProcessor at the start of the
>chain after the context is created.

Yes, no matter where we store the ActionContext, my intent would be 
to set this in process() right after contextInstance(...).

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: Storing current ActionContext in ThreadLocal

Posted by Hubert Rabago <hr...@gmail.com>.
What about using a different class to host the ThreadLocal?

public void pojoActionMethod() {

    ActionContext ctx = ActionContextHolder.getActionContext();
    if (...) { ctx.setForwardConfig(ctx.getMapping().findForward("a")); }
    else { ctx.setForwardConfig(ctx.getMapping().findForward("b")); }
}

The instance would be set by the RequestProcessor at the start of the
chain after the context is created.

Hubert

On Fri, 11 Mar 2005 05:48:43 -0600, Joe Germuska <Jo...@germuska.com> wrote:
> At 9:02 PM -0800 3/10/05, Martin Cooper wrote:
> >I would think we should just have the getter and setter in the
> >interface, and leave the actual thread-local part to the
> >implementation. Note that the getter and setter don't tie the impl to
> >the use of thread-locals, so if someone came up with an alternative
> >impl, that would be OK too.
> 
> Isn't the point of the ThreadLocal to make the ActionContext
> statically reachable to a method which might be invoked without
> having an instance passed to it?
> 
> public void pojoActionMethod() {
> 
>     ActionContext ctx = ActionContext.currentInstance();
>     if (...) { ctx.setForwardConfig(ctx.getMapping().findForward("a")); }
>     else { ctx.setForwardConfig(ctx.getMapping().findForward("b")); }
> }
> 
> If we add the methods to the interface, then there's still no way to
> pull yourself up by the bootstraps in a case like this.
> 
> >As far as the actual impl of thread-local, I would think we could
> >define an abstract base class that does that part. Or does that negate
> >part of the reason for having ActionContext be an interface? (I
> >haven't been following along as closely as I should have been...)
> 
> There is the ActionContextBase abstract class, which would be a
> suitable place to put it, except for the question of whether we want
> to put it into the Interface as an instance method at all!
> 
> 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: Storing current ActionContext in ThreadLocal

Posted by Joe Germuska <Jo...@Germuska.com>.
At 9:02 PM -0800 3/10/05, Martin Cooper wrote:
>I would think we should just have the getter and setter in the
>interface, and leave the actual thread-local part to the
>implementation. Note that the getter and setter don't tie the impl to
>the use of thread-locals, so if someone came up with an alternative
>impl, that would be OK too.

Isn't the point of the ThreadLocal to make the ActionContext 
statically reachable to a method which might be invoked without 
having an instance passed to it?

public void pojoActionMethod() {

    ActionContext ctx = ActionContext.currentInstance();
    if (...) { ctx.setForwardConfig(ctx.getMapping().findForward("a")); }
    else { ctx.setForwardConfig(ctx.getMapping().findForward("b")); }
}

If we add the methods to the interface, then there's still no way to 
pull yourself up by the bootstraps in a case like this.

>As far as the actual impl of thread-local, I would think we could
>define an abstract base class that does that part. Or does that negate
>part of the reason for having ActionContext be an interface? (I
>haven't been following along as closely as I should have been...)

There is the ActionContextBase abstract class, which would be a 
suitable place to put it, except for the question of whether we want 
to put it into the Interface as an instance method at all!

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: Storing current ActionContext in ThreadLocal

Posted by Martin Cooper <mf...@gmail.com>.
I would think we should just have the getter and setter in the
interface, and leave the actual thread-local part to the
implementation. Note that the getter and setter don't tie the impl to
the use of thread-locals, so if someone came up with an alternative
impl, that would be OK too.

As far as the actual impl of thread-local, I would think we could
define an abstract base class that does that part. Or does that negate
part of the reason for having ActionContext be an interface? (I
haven't been following along as closely as I should have been...)

--
Martin Cooper


On Thu, 10 Mar 2005 20:10:30 -0600, Joe Germuska <Jo...@germuska.com> wrote:
> So, I was just about to add support for static access to the
> "current" ActionContext using ThreadLocal, and then I realized that
> this approach is more commonly used with classes than with interfaces.
> 
> Since ActionContext is an interface, we'd have to do something like this:
> 
> public static final ThreadLocal currentInstance = new ThreadLocal();
> 
> Is it too weird to have this as a public member?  Is there some
> artful way to hide it more?  Of course, we'd have
> public static void setCurrentInstance(ActionContext ctx)
> and
> public ActionContext getCurrentInstance()
> 
> but I'm sketched out at having to leave the member itself public.
> 
> That said, I'm still happier with ActionContext as an interface than
> an abstract class.
> 
> Any words of wisdome, or should I just go ahead and do this?
> 
> 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
> 
>

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


Re: Storing current ActionContext in ThreadLocal

Posted by Paul Speed <ps...@progeeks.com>.

Joe Germuska wrote:

> So, I was just about to add support for static access to the "current" 
> ActionContext using ThreadLocal, and then I realized that this approach 
> is more commonly used with classes than with interfaces.
> 
> Since ActionContext is an interface, we'd have to do something like this:
> 
> public static final ThreadLocal currentInstance = new ThreadLocal();
> 
> Is it too weird to have this as a public member?  Is there some artful 
> way to hide it more?  Of course, we'd have
> public static void setCurrentInstance(ActionContext ctx)

Why not just put the ThreadLocal the same place you put these methods 
wrapping it?  Interfaces can't have static methods so you'll have to 
have it on some concrete class somewhere, yes?
-Paul

> and
> public ActionContext getCurrentInstance()
> 
> but I'm sketched out at having to leave the member itself public.
> 
> That said, I'm still happier with ActionContext as an interface than an 
> abstract class.
> 
> Any words of wisdome, or should I just go ahead and do this?
> 
> Joe
> 


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