Here is a quick fix for Transfer on Railo to prevent the stack
overflow error:
In the AOPAdvisor.cfc add the following item to the
__findPointCutsmethod:
var adviseCount = 0;
And modify the ArrayAppend to have the following conditional
statement:
if (isDefined(request.adviseLimit) and adviseCount lt
request.adviseLimit) {
ArrayAppend(pointCuts, item);
adviseCount++;
} else {
ArrayAppend(pointCuts, item);
}
So that it looks like:
<cffunction name="__findPointCuts" hint="builds an array of method
point cuts from a string regex" access="public" returntype="array"
output="false">
<cfargument name="pointcut" hint="a regex for functions to advise"
type="string" required="Yes">
<cfscript>
var pointCuts = ArrayNew(1);
var keys = StructKeyArray(variables);
var key = 0;
var len = ArrayLen(keys);
var counter = 1;
var item = 0;
var adviseCount = 0;
for(; counter lte len; counter = counter + 1)
{
key = keys[counter];
item = variables[key];
if(isCustomFunction(item) AND reFindNoCase(arguments.pointCut,
key))
{
if (isDefined(request.adviseLimit) and adviseCount lt
request.adviseLimit) {
ArrayAppend(pointCuts, item);
adviseCount++;
} else {
ArrayAppend(pointCuts, item);
}
}
}
return pointCuts;
</cfscript>
</cffunction>
In Transaction.cfc add:
<cfargument name="adviseLimit" type="numeric" required="no"
default="0">
<cfif arguments.adviseLimit gt 0>
<cfset request.adviseLimit = arguments.adviseLimit>
</cfif>
So that it looks like:
<cffunction name="advise" hint="wrap transaction advise around a given
method, or regex pattern of methods" access="public" returntype="void"
output="false">
<cfargument name="component" hint="the component to apply the advice
to" type="any" required="Yes">
<cfargument name="pointcut" hint="either a function, or a regex for
functions to advise" type="any" required="Yes">
<cfargument name="debug" hint="when true, cftrace's the method names
that gets adviced" type="boolean" required="No" default="false">
<cfargument name="adviseLimit" type="numeric" required="no"
default="0">
<cfif arguments.adviseLimit gt 0>
<cfset request.adviseLimit = arguments.adviseLimit>
</cfif>
<cfscript>
getAOPManager().advise(arguments.component, arguments.pointcut,
getTransactionAdviceBuilder(), arguments.debug);
</cfscript>
</cffunction>
You can now pass an additional parameter adviseLimit with the value of
1 when calling the AOP advisor:
adviseArgs = structNew();
adviseArgs.component = this;
adviseArgs.pointcut = 'yourmethod';
adviseArgs.adviseLimit = 1;
getPlugin("ioc").getBean("transferTransaction").advise
(argumentCollection=adviseArgs);
This will tell AOP advisor to stop looping through itself after 1
loop. If you do not provide the adviseLimit argument, an infinite loop
happens in Railo. The argument is not needed in CF8, so if you don't
pass it in then it is not set or used.
I haven't tested this extensively, I'm hoping Mark will take a look at
this, but I think we might be pretty close here... :)
As of right now... I'm using Transfer with AOP transactions inside of
Railo with no errors.
I'm hoping I didn't do all of this for nothing and I wasn't missing
some simple concept or had a bad configuration, but I tried passby,
lazy and everything else under the sun but kept getting stack overflow
errors with AOP advice. This fixes that issue.
> ...
>
> read more »