BeforeAdvice, doesn't proceed ??

5 views
Skip to first unread message

jax

unread,
Mar 17, 2008, 11:47:40 AM3/17/08
to ColdSpring-Users
I'm having difficulties getting the beforeAdvice to work properly. It
never proceeds with the actual method but stops right after executing
the advice component... I am probably missing the obvious here but
can't find it..

If any one else can, please let me know.. :-)

CS config:
-----------------------

<?xml version="1.0" encoding="UTF-8"?>
<beans >
<bean id="testAdvice"
class="ColdSpringTest.aspects.testBeforeAdvice" />

<bean id="testAdvisor"
class="coldspring.aop.support.NamedMethodPointcutAdvisor">
<property name="advice">
<ref bean="testAdvice" />
</property>
<property name="mappedName">
<value>testMethod</value>
</property>
</bean>

<bean id="cstestTarget" class="ColdSpringTest.model.test" />

<bean id="cstest" class="coldspring.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="cstestTarget" />
</property>
<property name="interceptorNames">
<list>
<value>testAdvisor</value>
</list>
</property>
</bean>
</beans>

-----------

testBeforeAdvice.cfc:
------------------------------------------
<cfcomponent displayname="testBeforeAdvice"
extends="coldspring.aop.BeforeAdvice" output="false">

<cffunction name="before" access="public" returntype="any"
output="true">
<cfoutput>BeforeAdvice<br></cfoutput>
<cfreturn>
</cffunction>

</cfcomponent>

test.cfc
----------------------------------------------
<cfcomponent displayname="test" output="false">

<cffunction name="testMethod" access="public" output="true"
returntype="void">
<cfoutput>hello</cfoutput>
<cfreturn />
</cffunction>

</cfcomponent>

----------------------------
When I create a cfm with the following lines

<cfset anObject = application.coldSpring.getBean('cstest') />
<cfset anObject.testMethod()>

All that is shown is:

BeforeAdvice

And I expect it to say:

BeforeAdvice
Hello


What am I missing ????


James Holmes

unread,
Mar 17, 2008, 10:02:07 PM3/17/08
to coldspri...@googlegroups.com
From the docs:

To implement a before advice, you must define the following method in
your component:

before(method, args, target)

Argument Type Description

method coldspring.aop.Method The Method object wraps the original
method call. Proceed() will automatically be called for you on the
Method object after your BeforeAdvice executes (to execute the
original method call )

args Struct The argument collection that will be passed to the
method call in the Method object

target Component The target object of the method call in the
Method object (useful if your advice is very generic and needs to
inspect the component that it is being applied to)

You don't have a method argument in your advice, so there's nothing on
which to call proceed().

--
mxAjax / CFAjax docs and other useful articles:
http://www.bifrost.com.au/blog/

Sean Corfield

unread,
Mar 17, 2008, 10:42:01 PM3/17/08
to coldspri...@googlegroups.com
On Mon, Mar 17, 2008 at 8:47 AM, jax <rea...@gmail.com> wrote:
> I'm having difficulties getting the beforeAdvice to work properly.

The generated proxy - like all good CFCs - has output="false" so your
test.cfc output is suppressed.

If you make the method return something, you'll see it gets correctly
returned (and the code is working)

It's generally considered not good practice to have CFCs outputting HTML.
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Sean Corfield

unread,
Mar 17, 2008, 10:43:05 PM3/17/08
to coldspri...@googlegroups.com
On Mon, Mar 17, 2008 at 7:02 PM, James Holmes <james....@gmail.com> wrote:
> You don't have a method argument in your advice

Yes he does. Here's is his advice:

testBeforeAdvice.cfc:
------------------------------------------
<cfcomponent displayname="testBeforeAdvice"
extends="coldspring.aop.BeforeAdvice" output="false">

<cffunction name="before" access="public" returntype="any"
output="true">
<cfoutput>BeforeAdvice<br></cfoutput>
<cfreturn>
</cffunction>

</cfcomponent>

There's a before() method defined.

James Holmes

unread,
Mar 17, 2008, 11:10:32 PM3/17/08
to coldspri...@googlegroups.com
Yes, the before() method is there, but doesn't it need a "method"
argument of the type coldspring.aop.Method so that there's something
on which to call Proceed()? Or does that get passed in and used
automatically anyway (even if it's not defined, since arbitrary
arguments can be passed to a CF method anyway)?

--

Chris Scott

unread,
Mar 17, 2008, 11:38:52 PM3/17/08
to coldspri...@googlegroups.com
The arguments to both before and afterReturning advice types are both optional. The theory there is, you only need to define what you are interested in working with. I always use the full method signature myself, but you certainly don't need to. With around advice, you DO need to define MethodInvocation as a parameter, because you are responsible for calling proceed on the chain of interceptors.

Chris

James Holmes

unread,
Mar 17, 2008, 11:41:20 PM3/17/08
to coldspri...@googlegroups.com
Yes, while writing the question it dawned on me that this would most
likely be the situation.

Regardless, Sean is right about the output attribute of course.

On Tue, Mar 18, 2008 at 12:38 PM, Chris Scott <chris.s...@gmail.com> wrote:
> The arguments to both before and afterReturning advice types are both
> optional. The theory there is, you only need to define what you are
> interested in working with. I always use the full method signature myself,
> but you certainly don't need to. With around advice, you DO need to define
> MethodInvocation as a parameter, because you are responsible for calling
> proceed on the chain of interceptors.
>
> Chris
>
>
> On Mon, Mar 17, 2008 at 9:10 PM, James Holmes <james....@gmail.com>
> wrote:
> >
> >
> > Yes, the before() method is there, but doesn't it need a "method"
> > argument of the type coldspring.aop.Method so that there's something
> > on which to call Proceed()? Or does that get passed in and used
> > automatically anyway (even if it's not defined, since arbitrary
> > arguments can be passed to a CF method anyway)?

--

jax

unread,
Mar 18, 2008, 4:03:15 AM3/18/08
to ColdSpring-Users

> The generated proxy - like all good CFCs - has output="false" so your
> test.cfc output is suppressed.
>
> If you make the method return something, you'll see it gets correctly
> returned (and the code is working)

You were right, when it returns something it works ok.

Which is weird. :-)

Have a look at the beforeAdvice component en de test component. Both
have an output=false attribute set on the component level,
and both have an output=true set on the method executed ( 'before' and
'test'). But only the before method produced output...

I know having a CFC output HTML is not good practice, and when I would
not have created a simple test like this I probably would never have
even encountered this problem...

James Holmes

unread,
Mar 18, 2008, 4:13:13 AM3/18/08
to coldspri...@googlegroups.com
Yes, but it's the proxy that's actually being called.

On Tue, Mar 18, 2008 at 5:03 PM, jax <rea...@gmail.com> wrote:
> Have a look at the beforeAdvice component en de test component. Both
> have an output=false attribute set on the component level,
> and both have an output=true set on the method executed ( 'before' and
> 'test'). But only the before method produced output...

--

jax

unread,
Mar 18, 2008, 4:19:52 AM3/18/08
to ColdSpring-Users
Can you elaborate on this ? What is the proxy in this case? the
BeforeAdvice?
How does that explain the behaviour?

please forgive my ignorance.. I'm (obviously) a newby in the
ColdSpring world :-)

On Mar 18, 9:13 am, "James Holmes" <james.hol...@gmail.com> wrote:
> Yes, but it's the proxy that's actually being called.
>

James Holmes

unread,
Mar 18, 2008, 4:34:40 AM3/18/08
to coldspri...@googlegroups.com
Caveat - I'm also a noob at ColdSpring, but I like to hack.

ColdSpring creates an internal proxy bean on the fly that pretends to
be your component. When you call getBean(), you get this instead of
your real component. In your case, it looks like this:

<cfcomponent name="coldspring.aop.framework.tmp.bean_C102FFAD188B1169E6325F2105ADF039"
displayname="AopProxyBean"
extends="ColdSpringTest.model.test"
hint="Abstract Base Class for Aop Proxy Beans"
output="false">

<cffunction name="init" access="public"
returntype="ColdSpringTest.model.test" output="false">
<cfargument name="target" type="any" required="true" />
<cfset variables.target = arguments.target />
<cfreturn this />
</cffunction>

<cffunction name="setAdviceChains" access="public" returntype="void"
output="false">
<cfargument name="adviceChains" type="struct" required="true" />
<cfset variables.adviceChains = arguments.adviceChains />
</cffunction>

<cffunction name="getAdviceChains" access="public"
returntype="struct" output="false">
<cfreturn variables.adviceChains />
</cffunction>

<cffunction name="callMethod" access="public" returntype="any">
<cfargument name="methodName" type="string" required="true" />
<cfargument name="args" type="struct" required="true" />
<cfset var adviceChain = 0 />
<cfset var methodInvocation = 0 />
<cfset var rtn = 0 />
<cfset var method = 0 />

<!--- if an advice chain was created for this method, retrieve a
methodInvocation chain from it and proceed --->
<cfif StructKeyExists(variables.adviceChains, arguments.methodName)>
<cfset method =
CreateObject('component','coldspring.aop.Method').init(variables.target,
arguments.methodName, arguments.args) />
<cfset adviceChain = variables.adviceChains[arguments.methodName] />
<cfset methodInvocation = adviceChain.getMethodInvocation(method,
arguments.args, variables.target) />
<cfreturn methodInvocation.proceed() />
<cfelse>
<!--- if there's no advice chains to execute, just call the method --->
<cfinvoke component="#variables.target#"
method="#arguments.methodName#"
argumentcollection="#arguments.args#"
returnvariable="rtn">
</cfinvoke>
<cfif isDefined('rtn')>
<cfreturn rtn />
</cfif>
</cfif>

</cffunction>

</cfcomponent>


On Tue, Mar 18, 2008 at 5:19 PM, jax <rea...@gmail.com> wrote:
>
> Can you elaborate on this ? What is the proxy in this case? the
> BeforeAdvice?
> How does that explain the behaviour?
>
> please forgive my ignorance.. I'm (obviously) a newby in the
> ColdSpring world :-)
>
>
> On Mar 18, 9:13 am, "James Holmes" <james.hol...@gmail.com> wrote:
> > Yes, but it's the proxy that's actually being called.

--

jax

unread,
Mar 18, 2008, 5:55:23 AM3/18/08
to ColdSpring-Users
Thnx for that!

Nevertheless, I still dont understand why the output of testMethod()
is never shown.... :-)

James Holmes

unread,
Mar 18, 2008, 8:33:01 AM3/18/08
to coldspri...@googlegroups.com
It's the way the proxy calls your method. It does it via method.cfc,
which has the following code:

<cffunction name="proceed" access="public" returntype="any" output="false"
hint="Executes captured method on target object">



<cfset var rtn = 0 />

<cfif isRunnable()>
<cfinvoke component="#variables.target#"
method="#variables.method#"
argumentcollection="#variables.args#"
returnvariable="rtn">
</cfinvoke>
<cfset variables.runnable = false />


<cfif isDefined('rtn')>
<cfreturn rtn />
</cfif>
</cfif>

</cffunction>

This proceed() method is how the proxy runs your method after the
beforeAdvice is run. Notice that it has output="false" - this prevents
the output from showing.

To prove this, take ColdSpring out of the equation completely and make
up a simple test based on the code in proceed():

test1.cfc:

<cfcomponent output="no">
<cffunction name="proceed" access="public" returntype="any"
output="false" hint="Executes captured method on target object">


<cfset var rtn = 0 />

<cfinvoke component="test2"
method="doit"


returnvariable="rtn">
</cfinvoke>
<cfif isDefined('rtn')>
<cfreturn rtn />
</cfif>

</cffunction>
</cfcomponent>

test2.cfc:

<cfcomponent output="no">
<cffunction name="doit" access="public" returntype="string" output="yes">
<cfoutput>HELLO OUTPUT</cfoutput>
<cfset myResult="foo">
<cfreturn myResult>
</cffunction>
</cfcomponent>

test.cfm:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
<cfset myobj = createobject("component","test1")>
<cfset ret = myobj.proceed()>

<cfset myobj2 = createobject("component","test2")>
<cfset ret2 = myobj2.doit()>
</body>
</html>

So the first bit, myobj, calls the doit() method via proceed(). The
second one calls it directly. You will see only one output of "HELLO
OUTPUT."

jax

unread,
Mar 18, 2008, 8:53:15 AM3/18/08
to ColdSpring-Users
Thanks once again James!

More clear now.
So.. unless I hack into Coldsprings code and change the Proceed()
method to default to output=true
I can no longer use cfdump in the proxied component?
Well. that is.. I can allright, it just produces no output.
.

patw...@gmail.com

unread,
Mar 18, 2008, 10:08:25 AM3/18/08
to coldspri...@googlegroups.com
I am sending this from my phone so forgive me if I am missing something (can't see the whole thread). But in regards to using cfdump; if you are simply using that for debuging and you are on cf8 then you can use the following syntax with cfdump and it will output to the console regardless to if any of the methods have output set to false. It will keep you from having to touch the inner workings of coldspring and give you vital debug info you may need..

<cfdump var="#var#" output="console" format="text" />

I do this all the time when I need vital information and have such constraints in front of me.

Note: you will need to start cf in console mode.
Sent via BlackBerry by AT&T

-----Original Message-----
From: jax <rea...@gmail.com>

Date: Tue, 18 Mar 2008 05:53:15
To:ColdSpring-Users <coldspri...@googlegroups.com>
Subject: [coldspring-users] Re: BeforeAdvice, doesn't proceed ??

Tom Chiverton

unread,
Mar 18, 2008, 11:01:21 AM3/18/08
to coldspri...@googlegroups.com
> <cfdump var="#var#" output="console" format="text" />

I've got the following snippit saved in CFEclipse:
<cfsavecontent variable="t">
<cfdump var="#$${Variable}#">
</cfsavecontent>
<cffile action="write" file="/tmp/a.html" output="#t#">

--
Tom

Patrick Santora

unread,
Mar 18, 2008, 11:10:53 AM3/18/08
to coldspri...@googlegroups.com
Interesting work around. Have you tried the console approach? It will save you the hassle of pushing in such code as you have below. You will also be able to stack dumps as one will just push out after another against the console.

Just my two cents.

Tom Chiverton

unread,
Mar 19, 2008, 7:37:55 AM3/19/08
to coldspri...@googlegroups.com
On 18/03/2008, Patrick Santora <patw...@gmail.com> wrote:
> Interesting work around. Have you tried the console approach? It will save
> you the hassle of pushing in such code as you have below. You will also be
> able to stack dumps as one will just push out after another against the
> console.

The cfdump to console is interesting, giving you things like
==> /opt/coldfusion8/logs/cfserver.log <==
struct

SEARCHVALUE: tron
USERNAME: erg

Handy for simple things I suppose, but if you are looking at something
fairly complicated, having the full HTML dump on a file can be
handier.

--
Tom

jax

unread,
Mar 19, 2008, 7:39:17 AM3/19/08
to ColdSpring-Users
Maybe it is an idea to have a debugmode for ColdSpring that enables
output ??



On Mar 19, 12:37 pm, "Tom Chiverton" <tom.chiver...@gmail.com> wrote:

Tom Chiverton

unread,
Mar 19, 2008, 7:47:07 AM3/19/08
to coldspri...@googlegroups.com
On 19/03/2008, jax <rea...@gmail.com> wrote:
> Maybe it is an idea to have a debugmode for ColdSpring that enables
> output ??

I would never expect screen output from a proxied component.
It sounds like your use case is for the (rare, hopefully !) case when
something isn't working, in which case that's what debuggers are for.
I don't find it a bind to go in and add dumps to a file (or cflog
statements) where I need to either.
I've never had a need to debug the internals of ColdSpring either.

--
Tom

Patrick Santora

unread,
Mar 19, 2008, 10:32:15 AM3/19/08
to coldspri...@googlegroups.com
Tom: I guess it is more personal preference on how you choose to debug (HTML vs Console) as well as purpose. Both HTML and Console show pros/cons.

Jax: Are you using CFEclipse? Have you checked out the debugger? If not, you may want to look into using it. If your application is lightweight it could be quite handy in regards to handling your debugging needs. Check it out. Below is a step-through type article talking about the debugger.
http://www.adobe.com/devnet/coldfusion/articles/debugger.html

-Pat

jax

unread,
Mar 19, 2008, 10:58:05 AM3/19/08
to ColdSpring-Users
Tom: It's like this: I don't need a car to get to work, I can get
there by train as well.
I just like the car better, and fortunately no one tells me I should
take the train simply because he/she feels that is how one is supposed
to commute ;-)

Pat: Thanks, that is of course an option. However, our company has not
upgraded to CF8 yet.. ( I know.. sucks royally)


On Mar 19, 3:32 pm, "Patrick Santora" <patwe...@gmail.com> wrote:
> Tom: I guess it is more personal preference on how you choose to debug (HTML
> vs Console) as well as purpose. Both HTML and Console show pros/cons.
>
> Jax: Are you using CFEclipse? Have you checked out the debugger? If not, you
> may want to look into using it. If your application is lightweight it could
> be quite handy in regards to handling your debugging needs. Check it out.
> Below is a step-through type article talking about the debugger.http://www.adobe.com/devnet/coldfusion/articles/debugger.html
>
> -Pat
>
> On Wed, Mar 19, 2008 at 4:37 AM, Tom Chiverton <tom.chiver...@gmail.com>

Patrick Santora

unread,
Mar 19, 2008, 11:08:21 AM3/19/08
to coldspri...@googlegroups.com
Gotcha! Well if/when your company upgrades to 8 you can use the debugger :-).

But are you using CFEclipse? There are other options if you are. For instance you can piggy back on the use of cflog. Just install LogWatcher into CFEclipse, hook it to the log file that cflog is using and see realtime logging through CFEclipse as the application is running. It will not provide you with complex results, but will give you simple string logging capabilities.

Here is the logwatcher plugin if you want to go down that path:
http://graysky.sourceforge.net/

James Holmes

unread,
Mar 19, 2008, 11:28:24 AM3/19/08
to coldspri...@googlegroups.com
You should take the train; it's more environmentally friendly :-)

On Wed, Mar 19, 2008 at 11:58 PM, jax <rea...@gmail.com> wrote:
>
> Tom: It's like this: I don't need a car to get to work, I can get
> there by train as well.
> I just like the car better, and fortunately no one tells me I should
> take the train simply because he/she feels that is how one is supposed
> to commute ;-)

--

jax

unread,
Mar 19, 2008, 11:56:28 AM3/19/08
to ColdSpring-Users
> You should take the train; it's more environmentally friendly :-)

I drive an electric car.

:-)

Tom Chiverton

unread,
Mar 19, 2008, 12:57:45 PM3/19/08
to coldspri...@googlegroups.com
On 19/03/2008, jax <rea...@gmail.com> wrote:
> > You should take the train; it's more environmentally friendly :-)
> I drive an electric car.

Where do all those electrons come from ?

--
Tom

jax

unread,
Mar 19, 2008, 6:31:02 PM3/19/08
to ColdSpring-Users
> > I drive an electric car.
>
> Where do all those electrons come from ?

Small portable nuclear fusion reactor at home. Runs on helium3 atoms
which are not very abundant on earth, but plentiful available at the
moon.


Nonsense of course. ...
I haven't been to the moon in ages.

:-)

http://journey.cedar.tincan.co.uk/?lid=57044

Tom Chiverton

unread,
Mar 20, 2008, 7:43:29 AM3/20/08
to coldspri...@googlegroups.com
On 19/03/2008, jax <rea...@gmail.com> wrote:
> Small portable nuclear fusion reactor at home. Runs on helium3 atoms

Ahh, Mr Fusion :-)
http://zedomax.com/blog/wp-content/uploads/2007/09/mr_fusion.jpg
--
Tom

Matt Williams

unread,
Mar 20, 2008, 11:40:36 AM3/20/08
to coldspri...@googlegroups.com
> On 19/03/2008, jax <rea...@gmail.com> wrote:
>
> > Small portable nuclear fusion reactor at home. Runs on helium3 atoms

What? Nuclear Fusion? Haven't you upgraded to Cold Fusion yet? I hear
Cold Fusion is the new Nuclear Fusion.

(and now, we return to our regularly scheduled relevant emails....)
--
Matt Williams
"It's the question that drives us."

Reply all
Reply to author
Forward
0 new messages