ColdFusion Implicit Getter Has Incorrect Type For Being Called As A Function
Posted April 1, 2013 at 10:11 AM by Ben Nadel
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:
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.
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.
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.
unhappy with your posts about CF, I'm Yii and angular guy.
Looking forward to your next angular post :)
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.
No problem - hopefully more AngularJS stuff to come!
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.
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.
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.
I submitted a ticket on you track to have javadoc style comments /** trigger method definitions ...
Hopefully it will get some traction ...