I have a confession to make: I cheated on CFML this weekend. And I enjoyed every minute of it. Heresy, I realize, but if you stick with me through this brain dump I hope you’ll see that despite the sharp criticism contained herein, I’m extremely optimistic about the future of CFML. We just have a helluva lot of work to do.
To set the stage for things, I’m embarking on a side project with a friend of mine and as usual it’s a big job with a tight deadline. None of this is anything new and previously I wouldn’t have thought twice about which technology to use.
CFML: Now More Than Ever. (Sorry, I just love that bumper sticker.)
I’ve been taking several runs at
Grails over the past year or so, and with a semi-free weekend I decided to re-read a few books and some issues of
GroovyMag. Basic requirements for the aforementioned project in front of me on
Protoshare, I figured I’d give myself an hour to get a couple of the domain classes up and running in Grails. I downloaded fresh versions of
Groovy and Grails and set off to work.
I didn’t need the whole hour. I didn’t even need half an hour. About 10 minutes after getting everything installed, and this included reading a couple of
refresher instructions (and truth be told I ate a little sushi while doing all of this), I had my basic domain classes that involved a one-to-many relationship done, persisting to a database, tested, and the basic Grails master/detail views and CRUD functionality up and running. And before you think an IDE of some sort was lightening the workload, I did all of this in a terminal using
vi.
Whoa.
Granted, I’ve done this sort of exercise before so Grails wasn’t totally new to me. For someone new to Grails you might have needed the whole hour. 😉 Previously though, I’d screw around with inconsequential “Person” or “Book” or “ToDo” classes and think, “Impressive, but if I were doing this for a real application there’d be much more to it.” But this time around I was starting at square one on a real project, so in my mind I was looking at Grails from the standpoint of building a real application with it.
I proceeded to build out more of the application, fully expecting to lift up a stone and find some nastiness I couldn’t live with, but the hidden gotchas never came. Grails simply delivers.
A Concrete Example
Before moving on to my counterpoint that sets up the rest of this post, let’s take a quick detour to see how Grails does what it does. To prove I’m not blowing smoke, this–literally and with no omissions–is what you have to type in a terminal to have
this working Grails application up and running. (Be nice if you add stuff there. Your mother might read it.)
First, you create the application and have Grails generate a couple of objects:
grails create-app UserTest
cd UserTest
grails create-domain-class User
grails create-controller User
That creates the application and two files, User.groovy and UserController.groovy.
You then add this to User.groovy:
String email
String firstName
String lastName
You then add this line to UserController.groovy:
def scaffold = User
And finally, you run the application:
grails run-app
That’s it. You’ve just built out the basic CRUD operations for a User class in about two minutes. And if you don’t like the terminal,
NetBeans makes this even easier.
Want to deploy the app to another server? Type:
grails war
Then drop the generated WAR file on any Java servlet container. Granted this is using
HSQLDB at this point, but having it point elsewhere is a matter of tweaking a DataSource file and setting your production database to whatever you want. Grails is smart enough to handle different environments (e.g. development vs. production) and use the production database settings when you generate a WAR. (Yeah, they pretty much thought of everything.)
Stark Contrast
Back to my experiment. With some basic functionality for my app up and running so quickly in Grails I decided to open up Eclipse and go through my usual process of developing this same functionality in CFML. I’ll be completely honest and say that this is not a fair fight, which kind of gives away one of the punchlines of this post, so read on …
I haven’t ever been a real fan of any of the code generators available for CFML, nor have I ever delved much into the CFML ORM tools. This is not a slight against the authors of those tools in any way; I’ve just always preferred to do things by hand. I do use Peter Farrell’s
Rooibos Bean Generator regularly since writing beans is pretty much the definition of drudgery, but my
Mach-II listeners, my service layer, my DAOs, etc. have all been written by hand.
Why? Because I’m a control freak. Every time I’d try a code generator or ORM I’d be thinking, “That’s not exactly the way I’d write it,” or I’d be wondering what the heck the ORM was doing under the hood, or I’d be concerned about performance with an ORM, or any number of other excuses, so I never made the leap. I didn’t want to give up the control. And I type fast enough and have done enough of the basic grunt work that it’s not as if I was adding a ton of time to my projects. A few days on most typically sized projects for me and the basic plumbing would be done. Not so bad.
To even begin to approximate the Grails test I started from scratch with the CFML application as well, other than my existing Eclipse/CFEclipse and Tomcat installation. (For those who aren’t aware, Grails comes with literally everything you need to run it including
Jetty.)
I downloaded an
Open BlueDragon WAR, Mach-II, the Mach-II Dashboard, the Mach-II skeleton, and
ColdSpring … all the familiar faces I’m used to seeing in most of my projects these days. I then set out to write all the same code that existed in the application that Grails scaffolded for me, which involved:
- Creating a database (I used H2 to keep things simple)
- Creating two domain classes with a one-to-many relationship between them
- Creating a controller for each domain class
- Creating a list view and the related queries for each domain class
- Creating an add/edit form and the related queries for each domain class
- Creating unit and integration tests for each domain class
In short, all the stuff you’d need to get a nice head start on the backend of any web application, and nothing more than what Grails gave me in 10 minutes.
I downloaded files. I unzipped files. I moved files around. I edited config files. I wrote code. I edited more config files. I wrote more code. I wrote a lot of freaking code.
A couple of hours later, I had something that approximated my stopping point on the Grails experiment. But it wasn’t as nice, and I had to be honest with myself: it was a horrendous amount of work by comparison.
I didn’t even get to the testing part, for which I would have had to download
MXUnit and create test CFCs and functions. I gave up and went to bed.
It’s All Relative
Before people think the situation is too dire, let’s keep things in perspective. Creating a working prototype of a couple of major pieces of a web application in a couple of hours really isn’t that bad in the greater scheme of things. As I said earlier, it’s not as if we’re talking about adding weeks to a project schedule by doing things this way (though I suppose on huge projects time spent here would add up). And of course if all I wanted was pure development speed I could have done old-school CF 5 style development and been done with it, but that’s not a good way to lay the foundation for a extensible, maintainable application.
On the other hand, everything’s relative. After the instant gratification from Grails I had to face the fact–and I hope everyone understands how difficult this was for me–that working with CFML was like running in bare feet on the sand, and working with Grails was like
having that jet pack we’ve all been promised for so long.
I didn’t plan on winding up where I did when I fired up Grails the other night. It’s not as if I’m fed up with CFML and was looking for something different, and I had no intentions of taking a bit of a hard right turn on this particular project and going with a technology that truth be told I’m still not
all that familiar with. But here I am. And I’m not sure I can look back.
No, This is Not One of “Those” Blog Posts
I’m not going to make a big speech about how I’m “leaving CFML” to raise a ruckus and get some attention. I care a great deal about the future of CFML or I wouldn’t spend
so much time on it. But the longer I’ve been in this business, and the longer I’ve been using CFML, and given all the tools and languages I’ve seen come and go over the years, I’ve become a lot more pragmatic than I used to be.
I’ve gone down a couple of dead-end paths over the years (any
REBOL fans in the house?), and although each of us tend to have what amounts to a love affair with a particular language–the one we keep going back to time and time again, and the one that will always have a special place in our hearts for more emotional that practical reasons–we owe it to ourselves and the technology we love to be open to other possibilities, and to be brutally honest when something comes along that just plain works better. Admitting that isn’t admitting failure: it’s admitting that you care.
If we
don’t ever look outside our own little world, preferring instead to contemplate our navels, live blissfully in
Lake Woebegone, and engage in full-blown
siege mentality when we’re
threatened, then I’m sorry, that’s not being dedicated to the technology we love. That’s coding while Rome burns.
I realize this sounds pretty dismissive of CFML. It’s not, but that’s another punchline coming a bit later. CFML is the first programming language I learned after HTML, and 12 years later I’m still using it and still extremely excited about where it’s going, particularly with the shiny new open source movement in CFML.
All this being said, I simply can’t shake the experience I had with Grails the other night. The contrast between a sophisticated, well-thought-out, extremely well-executed, comprehensive framework like Grails (not to mention the elegance of the Groovy language) and the comparable tools we have available for CFML is too striking to dismiss or ignore. And again, that’s not to denigrate the fantastic work anyone does on any of these tools. Remember, I’m involved with some of them myself and I don’t plan on stopping those efforts. They’re great at what they do, but what they do is no longer enough.
As I mentioned earlier I’ve taken a few stabs at Grails so I’m not quite sure what was different last night. Probably a whole lot of thoughts and directions and changes in my attitudes about things came together in a particular way and at a particular point in time and space, but whatever the reason, Grails opened my eyes wide last night, and I simply can’t dismiss that. To quote one of my
favorite movies, “How you gonna keep ’em down on the farm once they’ve seen Karl Hungus?”
What Changed?
If I’m totally honest with myself, probably the biggest change in my attitude towards development these days is I just want things to work. After writing CRUD code for so many years, not being willing to give up any control, and convincing myself I was doing my application a favor by writing every single line by hand, I’m tired.
CRUD crap (is that redundant?) is a commodity. Basic object generation is nothing more than a means to an end. Your users don’t care a lick about your hand-crafted, finely tuned SQL, or your oh-so-clever service layer, and if
you do, I’m reminded of the old adage about peeing your pants: it may give you a warm feeling, but no one else cares. Users want something with a great front end because to them that IS the application. As long as it’s easy to use, it works, and it meets the applicable performance and scalability requirements, the application is successful.
So given the finite amount of time we all have, why would we consciously choose not to use a tool that does the commodity stuff for us so we can focus on the front end and business logic? I know SQL pretty well but I can’t say I enjoy writing SQL. It’s just something I felt I had to do. Same with so much other boilerplate crap. But if I had my druthers, I’d focus more on business logic and UI functionality and have all the persistence nonsense and a lot of the other drudge work handled for me. Not to mention the fact that when I’m using best-of-breed tools to do this, I can rely on the fact that the underlying code has been battle-tested by thousands of users. I can’t say the same for my own persistence code until I put the app into production.
Grails isn’t only about
GORM of course. If I just wanted an ORM I’d use
Transfer, and ORM capabilities are coming in ColdFusion, Open BlueDragon, and Railo. But Grails is about much more than ORM. ORM alone only gets you a fraction of the way there.
The real secret to the Grails sauce is how overwhelmingly compelling the entire package is, from the Groovy language itself, to GORM, to the fantastic flow and incredible speed of the entire development and deployment experience, to the powerful front-end tag library, to the integrated testing, to the sophisticated and dead-simple AJAX functionality … I could go on. The point is Grails is a complete pleasure to use from top to bottom, and I’m finding it increasingly difficult to talk myself out of taking it seriously.
Apples and … Different Kinds of Apples
Thus far you may have been thinking, “Is this guy a moron? He’s comparing a language (CFML) to a framework (Grails).” To a point, that’s true. But when I’m comparing Grails to CFML I’m just using CFML as a short-hand way of referring to the tools available in the CFML world. So I’m really comparing Grails as a package to the disparate bits and pieces that create some semblance of Grails-like functionality in CFML.
Take
Mach-II for example, which in my incredibly biased opinion is the finest MVC framework for CFML. 😉 Peter Farrell, Kurt Wiersma, Brian FitzGerald, and I spend a ton of time on Mach-II, not to mention all the
great help from our community, and it’s a damn nice framework. It continues to get
better with each release, and with caching, logging, the dashboard, the new front-end tag libraries, and everything else we’ve put into Mach-II and have planned for future releases, it’s a really compelling package.
One of many things that struck me as I’ve been working with Grails is how the basic constructs of Mach-II map one-to-one with Grails. Grails has “controllers,” Mach-II has “listeners.” Grails has a flash scope to persist data across redirects, Mach-II has the same. The Grails docs talk about how to keep your controllers dumb and use a service layer for your business logic, just as we advise in Mach-II. Even the Grails code I’ve been writing, particularly the controllers and services, looks eerily similar to the Mach-II code I write. This is probably why I’ve found myself surprisingly comfortable in Grails so quickly.
But Mach-II is only one piece of the puzzle. To manage dependencies, we need to grab
ColdSpring and wire everything together in an XML config file. If we do want ORM, we have to grab Transfer or
Reactor and again, more configuration. Then we grab MXUnit for testing, and it’s yet another piece of things that knows nothing about any of the other pieces of our puzzle until we explicitly tell it. If we want to do functional testing we grab
Selenium. And round and round we go.
Ultimately it’s not that we lack the tools in the CFML world that give us the ability to do what Grails does. Heck, Grails is based on
Spring,
Hibernate,
JUnit, and other best-of-breed tools in the Java world, so it’s not as if the Grails authors created this entirely from scratch.
What we’re missing in the CFML world is
flow, and without good flow you simply don’t have good productivity.
Integration, Integration, Integration
I won’t belabor this point too much since I’ve made it in other ways a couple of times now, but the magic of Grails is the cohesiveness with which all the various bits and pieces of the web development process have been integrated. MVC, DI, ORM, unit and integration testing, functional testing, i18n, AJAX, deployment, documentation, even a run-time environment … literally everything is contained within Grails, and it all works seamlessly.
It’s magic.
This elegant integration of what in the CFML world are still very disparate tools is what makes Grails such a joy to work with. I’ve never experienced a better development workflow than what I can achieve with Grails, and this leaves me free to focus on the things that matter most to the success of my application. And for simple applications I can crank stuff out more quickly than ever before.
That’s what I kept coming back to as I fought with myself over whether or not to use Grails for a real-world application. In the end, it’s all about the success of the application and how I can do the best job possible in the shortest amount of time. Much as I love CFML, in this case Grails won out. Even with my years of experience with CFML and relative lack thereof with Grails, I had to have a heart-to-heart with my friend (after the one I had with myself) and tell him that I truly believed I could get things done more quickly and with a better end result than I could with CFML, at least for this particular project. After showing him a demo or two of what Grails can do and writing some live code to show I had nothing up my sleeve he, another long-time CFML developer, had to agree.
Yes, it’s a poor craftsman who blames his tools. But you sure can cut the grass faster with a lawnmower than you can with a pair of scissors.
Why Grails
I’m well aware that this is the honeymoon period between me and Grails. I’m sure we’ll fight. But I’m equally sure we’ll make up. The real test will be building an actual application with it, and I’ll have a lot more to say as I do.
At least at this point in my experience with Grails, it strikes the perfect balance between taking the drudge work out of web development while still letting you have full control over the stuff that matters. This is the promise of CFML, but compared to Grails we’re not there yet.
As for going with something like
Spring, I like Java, I really do, but
Java Sucks Ass. It’s documented. (Be sure and read the
follow up post to that one.) So Groovy gives me a faster, dynamic version of Java, and Grails gives me a fantastic toolkit to get great stuff done quickly. This way I keep what I love about Java in the mix without having to make a
massive sacrifice in productivity.
Can
Ruby on Rails do all this stuff for you? Sure. Grails used to be called Groovy on Rails (no way!) until
DHH requested a name change (at least
that’s what wikipedia says), so clearly the Grails folks thought Rails had a ton of good ideas in it. I’ve also dabbled in Ruby and Rails a bit over the years, but as a language
Ruby just doesn’t do it for me. I’m sure many people out there love Ruby, and that’s fine. For me Grails is a much better fit, not to mention the 100% seamless integration with Java when I need it.
Why Doesn’t CFML Have a Killer Framework Like Grails?
Honestly I’m not even sure the “why” even matters. I have some ideas about why CFML isn’t farther along than it is given its lengthy history, but I’ll save those for another post. Fact of the matter is we have the makings of what could be a great development experience, but we don’t have the whole enchilada. Not by a long shot. We deserve better. We can do better.
What would make up a Grails-like framework in CFML? Here’s the basic pieces:
- CFML runtime
- MVC framework
- ORM framework
- Logging
- Caching
- Unit and integration testing framework
- Front-end/functional testing framework
- JavaScript/AJAX framework
- Templating engine
- Command line tools for code generation, scaffolding, deployment, etc.
If you’re saying “we’ve got all that,” on most points you’re right, and with the view tag library in Mach-II 1.8 we’re even getting there on the templating engine front. But we’re still lacking all of this in a single easy-to-use package that increases our productivity in CFML by leaps and bounds. One could argue there’s still less typing in CFML than in other languages, which is a dubious argument at this point given things like Ruby and Groovy, but we’re still lacking the proper tools to truly make developing an application, not just writing code, far more productive in CFML.
So let’s go down the list and figure out how we’d make this happen.
Building the Perfect Framework
You can’t run CFML without a CFML runtime, so the CFML engines are certainly part of the puzzle. My only cautionary statement here is we can’t rely on them to give us the CFML version of Grails. In my opinion that isn’t their job. To create a development experience similar to Grails, having the ability to easily plug in
and distribute (that’s key) a CFML runtime is crucial. The distribution part is where Adobe ColdFusion is a non-starter, but of course the magical CFML framework that exists in my head would allow you to choose OpenBD or Railo as your runtime, and those could be bundled, or you could plug Adobe CF in after the fact if you so choose. To me having everything in a single downloadable package eliminates one more headache and much more closely approximates what you get with Grails.
ORM is another piece of the puzzle. We have Transfer and Reactor now, and we have ORM support being baked directly into the CFML engines as we speak. Again no offense to the Transfer and Reactor folks, but I think once Hibernate, or
JDO, or some other implementation of the
JPA is baked into all the CFML engines, or even just available as a seamless add-on to CFML, we’ll have a much bigger step forward on this point. I’ve used Transfer a bit and it works great, but there’s no substitute for the thousands of man hours of development and testing, not to mention the wide usage, of the ORM tools in Java. Java’s just a much bigger pond and I think we can benefit greatly from leveraging it whenever we can.
As for MVC, here’s where I’m going to get myself into trouble, but I don’t think the CFML world needs a dozen MVC frameworks like we have now. The CFML community is way too small to have so many people spending so many man hours reinventing the same wheel over and over again. Now of course I’ll admit my bias and say I think as a whole Mach-II gets us closest to the final result we need, but ultimately what I’d like to see is all the framework authors working together towards a common goal even if the people behind the various frameworks still choose to do things their own way. Maybe the magical framework in my head exposes an API that all the MVC frameworks implement so you’re free to pick your poison on that front as well. (As you can tell, I’m still thinking through how all this would work.)
As for the rest of the pieces the choices are obvious. For JavaScript and AJAX, jQuery would be rolled in but you could use another framework if you choose. Pluggability is key here as well. Mach-II is well on its way to having a full templating engine built in, but there may be other projects out there in CFML land that I’m not aware of. For unit testing we have MXUnit. For front-end testing we’d have to leverage something like
Canoo, or maybe Selenium is equally configurable and scriptable (haven’t looked at it in a while).
Command line tools are where things get interesting since you can’t run CFML commands from a terminal. (Anyone working on that?) So, two thoughts come to mind. Either this is all web-based, which is OK, or Java and ANT are used to do the command line pieces. Maybe we have both options. (I can ask for the world when this all exists only in my head.) I do think the command line bit is key, not only because I like working that way, but because it’s a faster, easier way to do things than clicking around on web pages.
So put all this and some awesome scaffolding together and you’re done! Yes, I realize what I’m proposing is a tremendous amount of work. Grails was three years in the making before it hit 1.0. So it’s not that it can’t be done, we as a community of framework authors and CFML advocates just need to commit to making it happen and start chipping away at the mountain of work involved to get there.
The Punchlines
I said I had some punchlines, and though you’ve probably assembled then in your head by now after reading everything to this point, I’ll just enumerate them so they’re more, uh, punchy.
- Grails kicks ass, and we deserve something this awesome in the CFML world. We should have had it by now. We don’t need more frameworks, we need to demand more from our frameworks.
- We need to collaborate more as a community and work towards common goals instead of everyone being off in their separate caves cranking out code that does the same thing as what the guy next door is writing. Specifically I’m targeting those involved with framework projects, myself included. I’m not even necessarily proposing one framework to rule them all, but it does seem a bit silly that as a relatively small community we spend such a huge amount of time and effort to wind up with such subtle differences in how the various frameworks do their respective jobs.
- We need a vision. I’ve tried to present one here, although as you can tell at this stage it’s still a bit cloudy. But we need to open up the dialogue and remove our egos and biases from the picture and answer the question: What would the perfect set of tools for CFML development be?
- We need an action plan. I haven’t thought that far ahead quite yet, but the first thing that comes to mind is a framework authors mailing list. Maybe there already is one. And it’s key that this discussion be completely open and anyone who has interest, framework author or not, can participate. From these discussions we can quite easily come up with a high-level, concrete set of tasks and goals and get to work. I’m not saying it’s going to be easy, but on the other hand I feel like we have all the basic building blocks available, so how hard can it be? 😉
Who’s With Me?
If the ideas in this post scare you, good. They’re meant to. But they’re also meant to motivate you. If you care about CFML as much as I do, then I hope you have the courage to admit that we’re falling behind and that we need to do something about it. This doesn’t mean blogging, and twittering, and conferencing, and defending CFML against all enemies domestic and foreign, and all the rest of the community-oriented stuff we all do. This means coming together as a group, knuckling down, and doing some seriously hard but even more seriously rewarding work from which we all will benefit.
We can do this. We need to do this.