[ColdBox 3.8.1] Issue with MethodInvocation arguments

I am working with some AOP components and I am having issues working with arguments. What I get from calling getArgs() appears to be a special Railo datatype (“Scope Arguments”) which seems to be a sort of composite key structure/map/array (I am not very familiar with the Java datatypes).

When I call a method with a single argument that is being advised and dump the arguments I get:

1|1|bar

When I call the same method but use a named argument I get:

foo>1|bar 1 |2|bar

This is causing me a bit of consternation. I can’t just use structKeyExists(invocation.getArgs(), “foo”), I have to somehow account for the method also being called without named arguments. And since the same argument shows up as two values within the “array” I can’t rely on the order be the same every time.

Is this an issue with Railo? Does anyone have a workaround?

> I have to somehow account for the method also being called without named arguments

Does the method being advised declare the “foo” argument or does it accept unknown args?

> I can’t rely on the order be the same every time

I’m curious what value you get if you access arguments[1]

It certainly doesn’t seem like the argument should be duplicated in any scenario. Can you confirm in the named argument scenario, you only passed in a single argument. AOP doesn’t “do” anything to the arguments. it just captures the entire structure/array and then passes it straight back when you call getArgs(). What version of Railo are you on?

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

I just created a quick ColdBox 3.8 site using CommandBox to test (Railo 4.2.1).

coldbox create app myApp --installColdBox
start

I activated AOP in config/WireBox.cfc:

listeners = [
{ class=“coldbox.system.aop.Mixer”, name=“”, properties={} }
]

And mapped the method logger advice:

mapAspect( ‘MethodLogger’ ).to( ‘coldbox.system.aop.aspects.MethodLogger’ );

bindAspect(classes=match().mappings(‘test’),methods=match().any(),aspects=“MethodLogger”);

I put this at the top of the method logger:

writeDump( arguments.invocation.getArgs() );abort;

My /model/Test.cfc was just this at first:

component {
function test( ) { }
}

Then I called it two different ways:

getModel( ‘test’ ).test( ‘foo’ );

Scope Arguments
1 1
string foo

getModel( ‘test’ ).test( foo=‘bar’ );

Scope Arguments
foo 1
string bar

Then I updated the test method to this:

function test( foo ) {}

And ran the same two tests:

getModel( ‘test’ ).test( ‘foo’ );

Scope Arguments
1 1
string foo

getModel( ‘test’ ).test( foo=‘bar’ );

Scope Arguments
foo 1
string bar

Everything there seems correct and consistent with how arguments work in CF. Perhaps you are on an old version of Railo?

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Hey Brad,

Yes, the method does declare its arguments. I was able to recreate your results, so as far as the numeric key being reliable things look good. I am still frustrated with the fact that I can’t just refer to the arguments by name all of the time like I could in ColdSpring. After a closer look at what is going on, where I run into issues is when I try to manipulate the values of the arguments. For example, if I try to change the value of the first argument args[1] = prefix & args[1] that is when I end up with the double value.

So I start off with:

function foo(bar) {
}

foo(‘test’); or foo(bar=‘test’);

When I dump the arguments in the advisor I get:

bar | 1 | test

But then I try to change the value. Since I can’t rely on the argument name being available I have to use the index so:

var args = invocation.getArgs();
args[1] = ‘baz’ & args[1];

This works fine for unnamed arguments but if I call the method with named arguments and then dump after the manipulation I get:

bar | 1 | test
1 | 2 | baztest

Essentially it looks like Railo doesn’t like that I am trying to manipulate the values using the index rather than the key. But if I can’t rely on the key being there then I can’t use the key.

If I use the key to manipulate the value when the method is called with named arguments everything works ok too.

foo(bar=‘test’);

var args = invocation.getArgs();
args.key = ‘baz’ & args.key;

bar | 1 | baztest

But this will of course cause an error if the method is called without named arguments.

So I can come up with a solution that either works for named arguments or works for unnamed arguments but not for both.

This is on Railo 4.1.2.005

Essentially Railo is allowing me to read from the Scope Arguments struct using an index but it gets confused when I try to write to the struct using the index. It assumes that the index I am using to write is actually a key.

Have you posted on the Railo list/raised a ticket yet? This sounds like it could be a bug. The issue is probably the nebulous behavior of guessing whether arguments[1] is the item indexed at one OR a key named “1”.

I’m not sure why the argument names aren’t being kept if they’re declared. It totally works in a simple test case:

function func1(){

func2( argumentCollection=arguments );
}

function func2( param1, param2 ){
writeDump(arguments); abort;

}

func1( ‘value1’, ‘value2’ );

In the mean time, this undocumented method on the arguments object will let you set a specific item by index:

arguments.setE(1, ‘test’);

That sets the first argument to ‘test’ regardless of name. You can see these methods by dumping getMetaData(arguments)

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Thanks Brad. No I have not opened a ticket with the Railo team yet.

I’m having this same issue. It’s definitely a Railo bug, as my code is now producing errors where it didn’t before, I suspect after and update. I’m getting errors such as “key [paid] doesn’t exist in argument scope. existing keys are [1, 2, 3, 4, 5, 6, 7, 8]”.

AJ - did you raise a ticket for this?

Tom.