Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with:

ColdFusion Implicit Getter Has Incorrect Type For Being Called As A Function

By Ben Nadel on
Tags: ColdFusion

ColdFusion 9 overloaded the CFProperty tag (or just "property" in CFScript) to allow for the definition of implicit, or synthesized, getter and setter methods. Lately, I've been using these implicit setters as a way to provide dependency injection hooks for Sean Corfield's DI/1 Framework. The setters seems to work without fail. And, 99% of the time, the getters work as well. But, under very heavy load, it seems that the getters occasionally fail, causing the current thread to hang for several minutes.

Imagine that I have a component that has a dependency on the singleton, "userService." In order to inject this dependency, DI/1 will call:

setUserService( userService )

... then, internally to the component, in order to access that injected property, I would use something like:

getUserService().getUserByID( 4 )

Notice that internally to the component, I am using the implicit getter to locate the injected property. As I said before, 99% of the time, this works as expected. But, in very rare situations, generally under heavy load, ColdFusion will raise the following exception:

Entity has incorrect type for being called as a function. The symbol you provided getUserService is not the name of a function.

At first, I thought that this was limited to CFThread contexts, as this is where the error first started showing up. But, when we started removing the use of CFThread, the error started popping up in random places that had no relation to parallel processing.

Using Fusion Reactor, we were able to look at the stack trace of these hung requests, which looked something like this:

java.net.SocketInputStream.socketRead0
java.net.SocketInputStream.read
java.io.BufferedInputStream.fill
java.io.BufferedInputStream.read1
java.io.BufferedInputStream.read
jrun.servlet.jrpp.ProxyEndpoint.readFully
jrun.servlet.jrpp.ProxyEndpoint.readFully
jrun.servlet.jrpp.ProxyEndpoint.readInt
jrun.servlet.jrpp.ProxyEndpoint.readString
jrun.servlet.jrpp.ProxyEndpoint.getHeader
javax.servlet.http.HttpServletRequestWrapper.getHeader
javax.servlet.http.HttpServletRequestWrapper.getHeader
javax.servlet.http.HttpServletRequestWrapper.getHeader
coldfusion.runtime.CgiScope.resolve
coldfusion.runtime.CgiScope.containsName
coldfusion.runtime.CgiScope.search
coldfusion.runtime.NeoPageContext.searchScopes
coldfusion.runtime.NeoPageContext.findAttribute
coldfusion.runtime.CfJspPage._get
coldfusion.runtime.CfJspPage._get
coldfusion.runtime.CfJspPage._get
cfScreenService2ecfc850392735$funcGETUSERSERVICE.runFunction

This was completely baffling. Charlie Arehart, however, noticed that the CGI scope was being used as a look-up scope in these requests - something that would not have been expected given the code.

This discovery led Charlie to a bug that Steven Erat filed with Adobe in March, 2012.

ColdFusion 9.0.1 - Bug 3132889

In the bug log, Steven Erat points out that ColdFusion will sometimes fail to locate implicit getters and setters, causing the CGI scope to be searched - which is what we were seeing in our stack traces.

To work around this in our application, we simply stopped using the implicit getters and started referencing the injected properties directly. At this time, I don't have any better advice; I'm simply posting this here in case anyone else is having this problem.




Reader Comments

I've run into a similar problem. Under heavy load,one of my implict getters starts acting strangely but in a different way. I have a DocumentHeaderService Object which gets me a DocumentHeaderID via an implicit getter. I then pass that ID into a generation function which build a header from XML.

Say the DocumentHeader ID I expect is 123456. Under heavy load, the implicit function getDocumentHeaderID will not return the value "123456", it will return the value "DocumentHeader#123456".

Can't really understand why it would return [Object name]#[ID]. Odd behaviour but your post reminded me of it.

Reply to this Comment

@Joe,

Hmm, that sounds really odd. I wonder if that's some sort of threading issue for concurrent code - like you're seeing a partial result that is being prepared by another thread. I've had that happen too many times when I forget to VAR-scope something; or I'm using a Java object that I didn't realize was thread-UNsafe.

@Aladdin,

No problem - hopefully more AngularJS stuff to come!

Reply to this Comment

Just curious why you were using getters and setters by default instead of direct references to the properties? Especially when the result is the same?

It seems like it is a common stylistic choice (dogma?) to always user accessor methods, whether they are really needed or not. But I feel like it's just extra overhead.

Reply to this Comment

@Eric,

It was part team decision, part something that just got slipped in there. I think I prefer the direct object reference, especially internally to a given component.

Reply to this Comment

@Eric,

The generated accessors is generally just a stylistic thing. I like them because you have your injected dependencies "documented" at the top of your CFC (with `property` definitions), there's less characters to read/type (e.g., "getFoo()" vs. "variables.foo"), and in my IDE (IntelliJ IDEA) I get autocompletion for all get/set methods implicitly generated by a CFC's accessors=true.

But most importantly, if you're using any number of dependency injection frameworks or other libraries or tools that might populate properties for you, then they'll generally look for setters, and I'd much rather document properties up top rather than hand-coding a bunch of boilerplate setters. For example, ColdSpring and DI/1 behave this way, for autowiring dependencies.

Reply to this Comment

@Krug ...

I submitted a ticket on you track to have javadoc style comments /** trigger method definitions ...

//youtrack.jetbrains.com/issue/IDEA-104579
\
Hopefully it will get some traction ...

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.