Slides from "Making Your ColdFusion Apps Highly Available"

Attached to this post are my slides from my presentation at NCDevCon 2012: Making Your ColdFusion Apps Highly Available. While I do talk a bit about ColdFusion code changes that are necessitated by moving from a single server to a cluster, all of the content applies to making any web application highly available, no matter if it's written in ColdFusion, PHP, or Ruby. In future iterations, I suppose I should rename the talk to "Making Your Web Apps Highly Available."

The presentation also wound up covering a lot more about Amazon Web Services than I had originally planned, but there's so many powerful tools in AWS to make applications highly available that I felt I needed to give a solid architectural foundation for attendees to work from.

In any case, enjoy the slides. The last few slides are reference slides that have links to the services and tools mentioned in the presentation. If you have any feedback about the presentation, I'd love to hear it!

How to Get Code Completion and Assist for Mach-II XML Config files in ColdFusion Builder 2

When we were putting together the MachBuilder extension for ColdFusion Builder 2, Kurt Wiersma and I ran into a major roadblock: we couldn't add any features to the extension that operated on Mach-II configuration files because ColdFusion Builder 2 extensions only work on CFC and CFM files. If you want to see ColdFusion Builder extensions work on XML files in future releases of ColdFusion Builder, please vote for this feature. However, if you install the Eclipse Web Tools Project (WTP) XML editor and correctly point to the DTD for the Mach-II XML configuration file, you'll get code completion and assist in your configuration files.

While simply pointing to the correct DTD should work in pretty much any XML editor that you add to Eclipse, the standalone version of ColdFusion Builder 2 (and ColdFusion Builder 1) incudes Aptana Studio's XML editor, which doesn't provide code completion or assist. If you installed ColdFusion Builder 1 or 2 into an existing Eclipse install, you may already have an XML editor which you can use. Even so, a lot of people speak highly of the features of the WTP XML editor.

Note that this works for ColdFusion Builder 1, ColdFusion Builder 2, and CFEclipse.

ColdFusion Builder 2 is built upon the Helios release of Eclipse. You'll first need to add the generic Helios update site to your install in order to get the correct files. (If you're using the Galileo release of Eclipse (which is what ColdFusion Builder 1 was built upon), you'll need to add the Galileo update site instead.)

Here's how you get it all working:

  1. From the "Help" menu, select "Install New Software..."
  2. Add the top of the "Available Software" window that appears, click "Add" next to "Work with:"
  3. In the "Add" window, enter "Helios Update Site" for the name and http://download.eclipse.org/releases/helios/ as the URL.
  4. Click OK
  5. Eclipse will now make a remote call to the Helios Update Site and present you with a list of software that's available.
  6. Open the disclosure triangle next to "Web, XML, and Java EE Development"
  7. Select "Eclipse XML Editors and Tools"
  8. Click "Next" at the bottom of the "Available Software" window, "Next" again to get past the details page, and finally "Finish" once you accept the license agreement.

One the install has finished and you've restarted ColdFusion Builder/Eclipse, you need to open your Mach-II XML configuration file and make sure you're pointing to the correct DTD to actually get code completion and assist working. There are details on how to do this on the Mach-II Trac.

Essentially you just need to put the correct DTD at the top of your Mach-II XML configuration file, right after the opening XML tag. If you're using Mach-II 1.8.1 (the latest stable release), that declaration would be:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mach-ii PUBLIC
"-//Mach-II//DTD Mach-II Configuration 1.8.1//EN" "http://www.mach-ii.com/dtds/mach-ii_1_8_1.dtd">

One final and very important step: you have to open the Mach-II config XML file with the WST XML editor, not the default ColdFusion Builder XML editor. If you double-click the XML file, it opens in the default ColdFusion Builder XML editor. To do this, right-click on the file and select "Open With..." and then "XML Editor" (which is the Eclipse WST XML Editor).

The WST XML Editor has two modes: design and source. When you open an XML file, it defaults in to the design view. You more than likely want to click the tab at the bottom of the XML code editor window that switches to the source view. Once in that view, you can get code assist by hovering over items in the XML file and code completion by simply typing.

Thanks to Peter J. Farrell and Kurt Wiersma for pointing me in the right direction to get this working.

Book Review: Spring Recipes

I'm a really big fan of ColdSpring. I'd say that it is one of the key enablers for enterprise-class, object-oriented software development using ColdFusion. I can't imagine building a CF app without it now.

ColdSpring took its inspiration from the much larger, much more powerful Spring framework. ColdSpring represents but a mere subset of everything that Spring can do. That's not a knock against ColdSpring — Chris Scott was very clear about his intentions when he originally developed the framework. As I've tried to expand my knowledge of software development, and, more specifically, Groovy and Hibernate in particular, the Spring framework has come up again and again. I decided it was time to move beyond my ColdSpring-based understanding of Spring and try to learn about Spring itself.

The first stop on this journey has been "Spring Recipies: A Problem-Solution Approach," by Gary Mak. This is an intensive, though not exhaustive, look at what Spring has to offer. It covers all of the major components of Spring, above and beyond its very robust Dependency Injection framework.

The book covers numerous aspects of the larger Spring framework, including:

  • The Basic and Advanced Spring Dependency Injection Container
  • AoP in Spring: Classic, 2.0x and the AspectJ
  • Spring JDBC templating
  • Spring Transactions Framework (for database transactions)
  • Spring + Hibernate
  • Spring MVC
  • Spring Testing Support for JUnit and TestNG
  • Spring Security
  • Integrating Spring with Portals and Portlets
  • Spring Web Flow (of particular interest to me)
  • Spring "Remoting"
  • Spring support for scheduling and email

There are a few other topics covered as well, but the point of listing all that is covered in the book is to give you an idea of the depth and complexity of the Spring framework. Dependency injection is just one part of this ginormous (and some say needlessly complex) framework. One of the nice things about Spring is that although it's large and complex, you can use just the pieces you want: you don't have to utilize the _entire_ framework in building your Java application.

Each one of the above topics is given fairly good coverage in the book. Some topics are relatively straightforward and so don't get a lot of pages, while the more complex topics get many more pages. The writing is clear and the examples quite good, even for someone like me who isn't exactly an expert in Java development. It was very clear to me, after completing each major section, why I would or would not want to use a particular feature of the larger Spring framework. The examples, which are numerous, demonstrate Spring's power at templating otherwise duplicate code throughout whatever application development needs you may have. Yes, this results in more and more XML, though annotations go a long way to reducing the amount of XML in the configuration files.

One flaw in the book — and it's more a limitation of the printing industry than anything else — is that once the basic examples are out of the way, the author refers you to the online documentation for additional examples or much of an in-depth coverage of a particular aspect of the framework. This isn't entirely surprising, though. There are many books written about the individual parts of the larger Spring framework, so it's doubtful that one, single book could cover everything in depth and detail.

The book's clarity and intelligence has inspired me to learn more about some of what Spring can do. Spring Web Flow is really interesting to me, as a developer of Web applications, and I plan on learning more about it and figuring out how I can implement some adaptation of it in my own applications. I suppose that I should go and try to build a Spring-based application as well, but I like to bring things back to ColdFusion whenever possible.

Be Part of the Solution

A blog post over on Vitamin (a fine resource for Web application development articles) got me reading a commentary by Virginia Hefferman at the New York Times Magazine about the knee-jerk reflexivism so rampant in online "commenting" tools. It's a worthy read (even if she fails to make the distinction between generalist sites (ie; newspapers) and specific, targeted communities).

It got me thinking, though, about something I'm making a conscious effort to do in my everyday Web application development work: be part of the solution to a problem and encourage others to be the same.

Here's the crux of the matter: You can't just say that a Web application or framework or library is terrible. You have to be willing to say how to make it better. It's easy to dump in 140 characters or less, but how about you try to figure out a way to make it better? Here's a classic example of this, refracted through the lens of my day job:

Faculty member: This is the worst application I've ever had to deal with.

Me: If you have suggestions on improving or fixing the application, I'd love to hear them.

Faculty member: [Silence]

Now this may just be a case of a user feeling that they have vastly more important things to do than figure out how to solve someone else's problems, or that we should be good enough at what we do to just get it right the first time out. They'd be partly right on both fronts. But it's so easy, so trivial to dump all over the work of others, particularly when enabled with the commenting power found in blogs, Facebook, Twitter, and elsewhere, that we forget that if we know how to do it better, we should ourselves up to the same possibility of negative attack and offer how to do it better.

I'm not saying that you then have to go out and implement every feature request or idea someone comes up with (and a single feature request should rarely turn in to an implemented feature), but you can — should — demand that they who complain be part of the solution.

I'd argue that the same should go for movies, literature, and politics, but that's a whole other post.

JK Rowling on the Power of Failure and Imagination

I tweeted about this earlier today, but JK Rowling's 2008 Harvard commencement speech on the twin pillars of failure and imagination was an awfully good read (though not good enough to topple Steve Jobs' Stanford commencement address as the best I've read).

The speech was timely for me as I've recently been dealing with the issue of failure in relation to a product we rolled out at the beginning of the year which was, ultimately, deeply flawed and brought upon my head the wrath of many, many users.

The product didn't fail to meet the feature requests and needs of the users. It had all the features they had requested and then some. Where it failed, miserably, was in implementation. From the overall UI direction, to security, to QA testing, there were failures large and small which, when driven home through extensive use of the product, made many in our user base not just dislike the product, but hate it. I've now come to look at it as the Word 6.0 of our product development history.

There's a silver lining, though. Through failure, we've gone hat-in-hand to our users to ask how we can do things better and have gotten some really great ideas on how to fix things in return. We've taken a look at our overall development process and tweaked it to improve visibility earlier in the product development cycle. We've reviewed QA and testing practices and empowered that team to speak up earlier and hold releases if evaluative criteria have been met.

Failure is a powerful tool in the software development arsenal. It's scary, sure, but a superb teaching tool because it forces you to imagine how to do things better and then to actually do better the next time around.

A Small SVN/Eclipse Pointer

I'm sure that this is well documented and common practice, but I'd never run in to a problem submitting my Eclipse .project files to a Subversion repository before. I mean, why not, right? The .project file is included when you first try to commit, it's in the same folder as the rest of the files versioned by Subversion, so what could possibly be wrong with doing that?

When I went to check out a project using Subclipse in to a fresh install of Eclipse, I found out why. The new project wizard won't let you check out a Subversion-controlled project if there's a .project file in the contents you are trying to check out. Oops!

The moral of the story: don't put your .project file in to the repository. Not that it needs to be there anyway, but that was my noob mistake.

As I couldn't delete the .project file using Subclipse, I fired up the lovely and handy Versions to take care of that for me. Once the .project file was deleted from the repository (along with a note about my foolishness in the commit log), I was good to check out using the new project wizard in Eclipse.

IE Caching Wastes Hours of My Life

I should have known better. I should have remembered. I've seen it before, but it bit me again: IE's abusive caching destroys the quiet peace of developing with JavaScript libraries like Prototype.

Here's the issue: I was updating the content of a <div> on a page via a form field on the same page. Very simple stuff. It worked flawlessly on Safari and Firefox (no surprises there), but failed on IE7. I tried the same code on a different machine running the exact same version of IE7 down to the xxx.xxx.xx.xxxx build, and it worked just fine. I tried it on a third machine and it failed. WTF?

The culprit, as I should have remembered from reading endless blog posts every day, was IE's overly aggressive caching strategy. Now on the Web application in question, we're setting HTTP headers to "No-Cache" to avoid these kinds of issues, and that works well for full page reloads. It does not, however, always work for XMLHttpRequest calls.

The default setting for IE is to "Automatically" check for new versions of Web pages when requests are made. If you look under "Tools" -> "Internet Options" -> "Browsing History" -> "Settings," the default is to check for new versions of Web pages "Automatically." However, IE's idea of "Automatically" doesn't take in to account XMLHttpRequests.

The solution is simple: append a random value to each AJAX request and the problem vanishes because now each URL being requested is "unique" and IE's default, aggressive, abusive caching strategy is foiled.

JavaScript example:

var cfcURL = 'myService.cfc';
var randomizer = Math.floor(Math.random()*50000);
var params = 'method=getContent&differentiator=' + differentiator;   
var myAjax = new Ajax.Request(cfcURL, {method:'get',parameters:params,onComplete:udpateSomeDiv});

Hours of my life wasted on something that should just work.

Oh, that's right, that's Apple's motto, not Microsoft's.

How Do You Stop Users from Creating Duplicate Accounts?

I'm prepping to build out a consolidated registration site for a couple of the services that we provide at my place of work. Instead of replicating a registration process across a couple systems, we're building a centralized registration system and users can then take those credentials and log in to the services that they need. (We're not replacing existing user accounts with OpenID and OAuth or anything like that — sorry!)

There's a lot of work we'll be doing to make the process simpler and more elegant than the current set of processes. One major hurdle remains, however: how to prevent users from creating duplicate accounts.

When users register for a site — any site — and if they don't access the site right away or within the next couple days, they often forget their account information. If they wait long enough, they'll even forget the email address with which they registered. This is particularly problematic in online education, as someone may take a class, then not take another for a year or two, but return to take another class at some distant point in the future when their email (or physical) address may have changed. We don't want them to make new accounts because then we don't have a unified history of their activity (and this can cause problems with things like prerequisite courses).

A common approach I've seen and we've used in the past is to check against the provided email address. If there's already an account in the system with the given email address, then you let the user know that they already have an account and provide them a link to retrieve that information.

However, if the user is trying to register with a different email address, they're going to make a duplicate account. The system isn't going to know that bsimpson@hotmail.com and santoslhalper@gmail.com are the same person. So what to do?

I'm considering the following, but am very open to suggestions:

  • Check the first and last name: if there's a match to the first and last name, suggest display a list of email addresses that match and say "Hey, if one of these is your email address, go ahead and retrieve your account info."

  • Check the first and last name and city and state or country: It's very unlikely that there are two Janet Halzipools in Buffalo, New York, but one never knows. (In parts of South India, for example, a name like Omar Khan is very common, though less so in Reno, Nevada so maybe this approach won't work particularly well.)

  • Check another unique identifier: We don't/won't/never will store Social Security Numbers, but if you have another unique identifier, you can always check against that. The University that I work for distributes unique identifiers to some, but not all, of our user base (hence the need for a separate set of authentication data). This would work pretty well, but if the user no longer has access to the email address which is associated in the system with this unique identifier, how do they retrieve their account information? Do you ask them to engage in the manual task of contacting support and then waiting for a response from support to get information updated in the system?

Once of my key considerations about any of the above strategies is this: if you find what you think is a match, how do you prompt the user to see if this is them without making them think their account security is at risk?

Again, any suggestions are welcome. Even if I can't remove duplicate account creation, if I can significantly reduce it with one or more of the above strategies, I'll be happy.

Considering Mate and Swiz

I have a confession: I don't get to do much Flex development. I read up on it. I've attended trainings. I go to classes. I watch webcasts and screencasts. I don't, however, have a lot of opportunities (or time) to build Flex apps. A lot of what I do mixes rich media and lots of text, and I'm not sure that Flex (or Flash) is the best environment for lots of text. Feel free to argue or disagree in comments below.

One thing I do know is that I don't like to work without frameworks, regardless of the language in which I'm working. Frameworks and standard libraries can take a lot of work out of developing applications, and can often help you organize your application according to best practices. In ColdFusion, I don't build applications without Mach-II (or Model-Glue, but I'm mostly a Mach-II developer).

In my Flex development experience thus far, I've been working without additional frameworks (because Flex is a framework, after all). I've played with Cairngorm and understand how applications need to be laid out using that micro-architecture. It's a bit unwieldily for me. PureMVC is powerful as well, but, again, requires all sorts of extra classes and overhead that I'm not a fan of. (And, honestly, I'm not making AS3 apps, I'm making Flex apps, so the advantages of a "framework not tied to Flex" don't really work for me.) I really like the XML-based configuration that Mach-II, Spring/ColdSpring, and other frameworks provide. I know that some people hate coding in XML, and it does have its downsides, but I think that the simplicity and clarity it brings to the process outweigh the large XML files.

As fortune would have it, there are two good options that have made their way from private alpha in to public beta: Mate and Swiz. Mate is from the team at ASFusion, who brought us some really cool Flash tips and tricks as Flash, Flash Remoting and Flex began to be integrated with ColdFusion. Swiz is the brainchild of the very smart Chris Scott, who brought us the excellent ColdSpring framework (a requirement for anyone building CF apps these days).

In my initial explorations of these frameworks, I think the strength of each is as follows:

  • Mate uses an event map to describe the flow of events/actions within the application. I really like that and it makes a ton of sense, especially coming from an XML-based framework like Mach-II.
  • Swiz uses Inversion of Control and beautiful and handy things like annotations to significantly reduce coding and elegantly manage dependencies within your application.

Mate also offers all sorts of nicely encapsulated helpers for remoting and binding and dependency injection which make it pretty attractive. I don't know enough about Swiz at this point to say if it has all the same helpers and conveniences (and honestly, the documentation for Mate helps me understand a lot more about that framework that Swiz as Swiz currently lacks an equal amount of documentation). So given those conveniences and my comfort with the XML-based configuration/"event map," I think Mate is the way for me to go, for now.

I'll blog about my experiences using Mate as I build apps with the framework. I'm personally very thankful that such smart people have provided the developer community at large with these great, powerful, time-saving tools.

Designing the Obvious Moment

Robert Hoekman Jr. has written two quite excellent books on user interface and interaction design. I read these books earlier this year, but thought I'd finally get to blogging about them as part of my ongoing book reviews.

Designing the Obvious was the first of the two books and, for me, the more successful of the two. It's rich with UI design aphorisms that simply make good common sense. Written in a simple, conversational style that draws heavily from actual Web application development experience, this book, and its counterpart just make sense. The book deserves to be read by anyone who actually builds any kind of Web application user interface, no matter how simple or complex. One of the things I really liked about his approach was the whole concept of turning beginning users into intermediate users quickly. That was the inspiration for my whole series of posts on the Contextual Guidance API. His outright demand that you make it simple, eliminate anything unnecessary in the app and in the design, and focusing on how you accomplish a task at every moment within the application is great advice. My team has taken that advice to heart and has begun designing our new applications around much of Hoekman's advice in this book. The result has been applications that visually make more sense to our clients, and clients that are really happy with what we're developing.

Designing the Moment is focused on very common, very specific moments of interaction with a Web application and how they can be made better. It's less cohesive as the previous book, which took more of a big-picture view to the art and process of designing user interfaces. In this book, the examples are very specific, somewhat less generalizable, but many of the same principles from Designing the Obvious come in to play. My sincere feeling is that a number of the solutions presented in this book will become outdated over the next couple of years (ie; blog and social networking site design) but, again, the basic principles of clarity, task-orientation and removing all but the essential are more than sound.

Designing the Obvious should be mandatory reading for all Web application developers, even those who rarely work on the UI. At the end of the day, the interface is the application, no matter what application you're using. Knowing how to create great interfaces is key to building great applications.

More Entries

BlogCFC was created by Raymond Camden.

Creative Commons License
The content on http://www.iterateme.com/ is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.