I am in the process of converting a Flex application currently backed by Adobe ColdFusion 8 and LiveCycle Data Services to one that is backed by Railo 3.1.2 and BlazeDS. In so doing, I ran into an interesting issue that I thought might be helpful to record in case anyone else runs up against it.

The conversion from ColdFusion to Railo was, mostly, seamless. However, when I began connecting the Flex UI to Railo/BlazeDS, I hit a snag.

The problem I encountered was with remote calls that passed one or more parameters to the server. In every such instance, Railo responded with an error that went a little something like this: 

FaultEvent fault=[RPC Fault faultString="flex.messaging.MessageException: invalid call of the function MYFUNCTIONNAME (/path/to/my/remote/cfc/remoteservice.cfc), first Argument (ARG) is of invalid type, can't cast Object type 
[Struct] to a value of type [numeric|string|etc.]." faultCode="Server.Processing" faultDetail="null"] 
messageId="DDCBCF4C-90AC-E431-6195-3020C9C24765" type="fault" bubbles=false cancelable=true eventPhase=2]

The issue turned out to be a key difference in how ColdFusion and Railo (or LCDS and BlazeDS) handle named parameters passed to the remote method as an object. Consider the following remote method invocation from our Flex application:

remoteBlogObject.getBlog(   {     blog_id:_blogID,      start:_start,      end:_end   } );

Our Flex developers create an object with a key/value pair for each parameter the remote CFC method requires and send that along with the call.

ColdFusion 8/LCDS takes this object and converts it, in the case of the example above, to three distinct parameters (blog_id, start, end) which then get passed to the CFC's method.

Railo, on the other hand, receives this same object and converts it to a java.util.Map; the Java object on which a CFML struct is based. As a result, Railo sends a single parameter, typed as a struct, to the CFC's method. The struct sent to the method by Railo/BlazeDS does, in fact, contain the right keys (blog_id, start, and end) and values, just not as separate parameters.

While there are certainly more options, we opted to tackle this issue in one of two ways: (1) Change all the remote CFC methods to expect a single parameter (type="struct") or (2) Update the remote calls from Flex to not pass an object; rather, just pass in the parameters.

Thankfully, our team decided to go with option 2 as this approach required less overall code refactoring than option 1 and, more importantly, makes our Flex remoting calls consistent and usable with ColdFusion 8, ColdFusion 9 and Railo (maybe OpenBD, too?).

Side note: While the automagic conversion employed by ColdFusion seems helpful on the surface, I can't help but think it's more detrimental than good. If I'm passing a generic object ( {giggity:_giggity} )from a remote method, I would expect this same object to be an object (or struct in CFML) when it gets to my CFML server. I'd certainly be interested to know what other people think of this sort of "assistance", especially given the increasing interest in both a standardized CFML and open-source CFML engines.

Posted via web from Craig Kaminsky's posterous

Comments

cpt_pete
Thanks for posting this! I'm trying to convert from CF to railo and have hit the same problem (albeit with flashremoting service and NetConnection).

Think it's also worth noting that railo (and maybe CF, havn't tried) requires the cfargument tag to be able to parse your values when your passing paramaters like this.

It might be obvious but I was just passing the argumentsCollection to a subsequent function and was getting fustrated to see my arguments were not present.

Cheers!
jason olmsted
It seems that the problem of pre-setting up the object/struct in Flex is that you lose typing information on the actionscript side of things anyway. So, since you aren't strongly typed in the strongly-typed environment, what's wrong with a bit of duck-typing on the CF side? If you are ok with that, the way to do it, I would think, is to just get rid of named parameter passing in the cfc function definition and then the singular object call ought to be referenced by the "arguments" object. The behavior ought to be consistent between CF and Railo (though I don't have any flex-railo as of yet; rectifying that very shortly)

For what it's worth, when calling cfc from Flex, I usually skip explicitly referencing the named parameters and just specify them by position. It seems to do the trick and ought to not suffer from compatibility iddues.