ColdFusion JSON Serialization Changes

Because I've had to search on this three times in the last year, I thought it'd be a good idea to document this here, for myself and others. There were a number of important changes that can trip you up from version to version and, if you know which version the changes came in it can be beneficial.

First is a change that affects JSON output, though it's not specifically about JSON. The ColdFusion 9.01 updater (the current base install, at the time of this post) addressed Bug 82980 by removing ColdFusion Debug Output from direct CFC requests. This was only important if you had debugging output turned on in the Administrator, but caused lots of issues when testing ajax applications in development environments that kept that setting on by default.

Unfortunately, Adobe made some changes to JSON serialization that were not only unpopular, but technically dead wrong. They were trying to resolve the treatment of numbers in JSON serialization. Numbers were being converted to floats (1 became 1.0, 12 became 12.0, and so forth), so Adobe changed that by converting all numbers into strings (11 became "11", 17.24 became "17.24"). This was wrong too, as numbers weren't numeric anymore. At the time it raised quite a stir.

They fixed this (Bug 83638) really quickly, releasingCumulative Hotfix 1 for ColdFusion 9.01, which fixed the issue of integers being converted to float and having them as numeric values (ie: [1,12,true,"this var",17.24]). Hurray! Except....

Enter the improperly titled Cumulative Hotfix 2 for ColdFusion 9.01. I say this because it really isn't 'cumulative'. Most things are straight, from a cumulative standpoint, with the seeming exception of the fix to JSON formatting. If you have not applied CHF 1 prior to installing CHF 2, then you will still have issues with JSON formatting.

Overall, Hotfix 2 is great, fixing many bugs. The install is crazy/scary, and must be followed to the letter to prevent major issues, but it's worth it. As long as you did apply CHF 1 first, that is. Thankfully the hotfix/upgrade install process is much better in ColdFusion 10.

Big thanks to Ray for helping me to realize that I wasn't crazy, and pointing me in the right directions for all of this info. Hopefully this helps someone down the line.

ColdFusion 10 Public Beta

Yes, everyone is talking about it. That's why I waited a day or two to post the info. Adobe has put ColdFusion 10 up on Adobe Labs, opening it's public beta cycle prior to full release. That's right folks, ColdFusion is finally hitting the double digits, and this release just continues to improve this great platform.

There are some big changes. First are some overdue upgrades, like retiring the JRun JEE server, replacing it with Tomcat. Web Services support is upgraded, moving to more current form of Axis, and adding native support for creating RESTful web services. Exchange integration support is now upgraded to support MS Exchange 2010. Java and Solr integrations are improved as well. Finally, we get hotfix notifications and one touch upgrade directly within the administrator. I'm just getting started.

ColdFusion has always been known for making the hard things easy, and it looks like ColdFusion 10 is no exception. Adobe's engineering team listened to customer feedback, giving us a lot of new toys to play with, including some great language enhancements. Highlights include important new array functions, app specific in-memory file system, MIME type checking on file uploads, an implicit CFC constructor, method chaining, and much, much more.

Oh, and closures. Did I mention closures? Not sure how this one will play out, yet, but I look forward to seeing what people come up with. There's also websockets, media player changes, and an entirely new charting to work with. Just scratching the surface here.

Yes, there is a lot of new stuff. And, to top it all off, Adobe placed ColdFusion Builder 2.01 in Beta at the same time. There are a lot of bug fixes in here, along with the CF 10 support and more. Did I mention both the server, and the IDE, have some HTML 5 goodness baked in as well? No? You'll just have to download them and start playing. This'll be fun.

MSOC Part 9: Application Event Handlers, The Rest

So far we've spent a lot of time going over the different Application Event Handlers that relate to specific scope events (application, session, and request). Some ask "How does this relate to MSOC?", to which I have to say "Because it's important to understand application flow and control." We'll be diving into the MSOC specific bits much more in the coming posts. For now, let's wrap this part of our MSOC talk with a brief discussion of our two final Application Event Handlers: onMissingTemplate and onError.

The onMissingTemplate handler kind of does what it says. ALERT: Pay Attention To This Next Statement. This handler will be automatically invoked when a ColdFusion template or component is called but does not exist. Did you catch that? Yes, this only catches requests for templates/files that might be served by the ColdFusion application server. Setup a special mapping for CF to process .inc files? Yes, if the file doesn't exist, then this handler should catch that. A .html page was requested? Unless the server is mapped for CF to handle those requests, then no, your onMissingTemplate method will not catch that error. You get the picture yet?

The basic layout of the onMissingTemplate method is like this:

view plain print about
1/**
2 * FUNCTION onMissingTemplate
3 * Runs when a (CF) template is called that does not exist
4 * @access public
5 * @returnType boolean
6 * @output false
7 */

8function onMissingTemplate(required string targetpage) {
9    // something goes here
10    return true;
11}

As you can see, this method is automatically passed one argument, the page being requested. Here's another catch for you, this will only catch requests for ColdFusion processed files in the same directory as your Application.cfc. So a request for mysite.com/nothere.cfm will be caught, but a request for mysite.com/some/random/path/to/nothere.cfm will not (This surprised me too, and I had to test it over and over again to make sure I wasn't missing something). Weird, huh? Well, that's ok. To be honest, the onMissingTemplate handler is better served by those who don't have access to change their own webserver. The better option is to setup a 404 handler in their web server configuration. In the Apache Web Server you can look for the ErrorDocument line, in your httpd.conf file, and set it to a specific template that you setup for error handling.

view plain print about
1ErrorDocument 404 /errors/404.cfm

Speaking of error handling... You do do error handling, right? You wouldn't just show end users hard errors, would you? Of course not. You've got try/catch, throw and rethrow all over the place, right?

I've never seen an app that was made to handle every possible scenario for what a user could do. Nope, never. And, I've never seen (or written) a perfect app. It's a mythical creature, like the unicorn, or honest politicians.Fortunately, Coldfusion gives us multiple levels of error handling capability, from the block level of try/catch to the server level error handler applied through the CF Administrator. The onError method allows us to apply an application level error handler, that catches anything not previously coded for (through try/catch). It can display (if desired) any error thrown from onApplicationStart through onRequestEnd, including errors thrown through the process of the request itself, but can not display content for errors thrown in the onSessionEnd or onApplicationEnd.

The onError event handler is formed like this:

view plain print about
1/**
2 * FUNCTION onError
3 * This is an application wide error handler. Best practice would be to
4 * write process specific error handling, but this method will help
5 * you trap unexpected errors for custom notification and process
6 * @access public
7 * @returnType void
8 * @output true
9 */

10function onError(required exception, required string eventname) {
11    if(StructKeyExists(APPLICATION.cfc, "errorHandler")){
12        // If the error is thrown in onApplicationEnd or onSessionEnd, the error processor
13        // will still run, but nothing will be displayed to the user
14        WriteOutput(APPLICATION.cfc.errorHandler.process(argumentCollection: ARGUMENTS));
15    } else {
16        WriteDump(var = ARGUMENTS.exception, abort = true);
17    }
18}

The onError method is automatically passed to argments, exception (think CFCATCH) and eventname (the application event that the error was thrown in). In my example, I've used an application wide error handler to process the error, and displayed it's output (if not thrown from onSessionEnd or onApplicationEnd). My handler could do any number of things, from logging to emailing the site admin to generating error code specific text response for output, to all of the above and more.

OK, that's it for the Application Event Handlers. Let's be honest, I really only glossed over them and they still took up a lot of posts. That said, it's time to get back to the core MSOC talk, even as important as understanding all of this might have been. We have things to talk about, like directory structures, shared and specific asset handling, extended application models, and more. Give me your feedback: What are your most pressing questions on running Many Sites with One Codebase?

The Joys of Developing for Internet Explorer

Note: Follow the madness here to it's conclusion, to discover yet another "Really? I didn't know that..." IE moment, that may save you heartache and pain.

Is the sarcasm evident in my title? It should be. While Internet Explorer may have been "groundbreaking" when it was released, it has ever been the bain of the web developer's existance. Why, you ask? Because it refuses to adhere to standards, and just operates differently than everyone else. To be fair, Internet Explorer 10 is in the works, and supposedly closes the gap a fair amount (and even wins out in some of the html 5/css 3 support), and 7, 8 and 9 did progressively improve (if slowly). Unfortunately the fact remains that some companies/organizations/governments are stuck on Internet Explorer 6, or maybe even 7. If you are a web developer, and write cross-browser web applications, chances are Internet Explorer has hit you more than once in your career.

It's the dumbest things that hit you too. The most obscure "WTF!?!" moments that drive you crazy. That is a daily experience for me now.

[More]