I finally made the move to ColdFusion version 10 on my development environment. No, I’m not an early adopter. Early adopters of server software are madcap devil-may-care fellows, with a feather in their cap and a way with the ladies. I’m definitely more of a plodder.
It all went very smoothly – as expected, I was only upgrading from CF9 after all. However, a couple of new things did trip me up.
The onRequestEnd saga
A little while back Mark Mandel and I reported as a bug certain situations where onRequestEnd wouldn’t fire. Specifically, after cflocation and cfabort. The onRequestStart handler would fire for the new request, but not the onRequestEnd for the old request. This made these handlers basically useless for anything doing symmetric setup and teardown of request-specific resources. In my particular app I had to move my setup and teardown code out into a servlet filter to be sure everything would get cleaned up without fail. That worked well, but it did mean deployment involved messing with the J2EE server config, not what you normally expect for a ColdFusion app.
Adobe obligingly fixed the bug, and my app got a lot simpler. All happy, right?
Wrong! A counter bug was filed! There was some ugly namecalling! There was lots of unedifying discussion about the exact definitions of “request” and “end”. And ultimately the change was backed out for CF10. I was completely unaware of all of this of course. I don’t spend my time watching the CF bug list. I’m not sure how I missed the namecalling in the comments on Ben Nadel’s blog. I’m a big fan of Ben’s, but evidently I tuned out for a while. So when I upgraded to CF10, all those old nightmare bugs came back – dangling sessions, polluted threads, real “reboot the server” stuff.
Anyway, all ended well. The Friends of onRequestEnd got back their old sometimes-it-fires-sometimes-it-doesn’t buddy, and the Adobe engineering team gave us the new always-fires onAbort instead. As soon as I figured out that I needed to use onAbort, I was sweet.
The only other issue I had with CF10 was a tiny bit of behaviour change related to the new local scope. Specifically, assigning an undefined value (say, a Java null) to a local variable and then reading it back. When “local” was a struct, you’d get back an undef. Now that “local” is a scope, any attempt to read an undefined variable will cascade through to the variables scope. If there happens to be a variable with the same name in that or any higher scope, you get that value instead of the undef. So, exactly the same code, different result. Still, I don’t think anyone imagined that the introduction of the local scope was going to be a completely non-breaking change, and the old local struct paradigm really was a hack, so I don’t mind taking the pain.