Minor Schema Tool Update

I just committed a minor update to my award winning schema tool that allows you to write your migrations as CFM files, as well as CFCs and SQL files.  The naming convention is the same (migrationNNNNNN.cfm), and the entire file represents the only minor version for that migration step.

What I've found over time is that I write almost all of my migrations in SQL, but occasionally I want one minor version that is implemented in CFML.  After that one minor version, I'm back to SQL.  There's no way to avoid having to create that one minor version as separate migration (since you have to change migration types), but having to implement a CFC to do it seemed like a waste.  As such, CFM-based migrations were born: just write your code in a CFM, drop it in, and you're done.  No subclassing, no one-case CFSWITCH, just the code.

CFCOOKIE Bug in Railo

Found another minor bug in Railo today: CFCOOKIE doesn't accept a date passed to it's 'expires' attribute.  It happily accepts 'now', 'never', and a number of days, but not an actual date.  Submitted as JIRA-149.

Railo-147 Resolved

To quote my post Tuesday about Railo bug 147:

Railo has an issue with non-defaulted, non-required, numeric method arguments that are omitted from a call.  I added it as bug 147 in JIRA.

Turns out I was a bit incorrect – I'd forgotten that method was proxied by ColdSpring's AOP engine (which is exactly what's supposed to happen with AOP), and that's where the bug actually resided.  Railo was returning "[runtime expression]" as the default value for the argument within the function metadata, which ColdSpring was faithfully writing into the proxy method that it generates.

In any case, got a JIRA update from Michael to say it's been resolved, so the next build should have it fixed up.

ColdFusion to Railo

Just completed my first port of a major app from ColdFusion to Railo.  Time elapsed from downloading the Railo WAR to my dev box to see if the app would run to reenabling the prod instance: 1.5 hours.

Downloaded the WAR, unpacked it into my webroot, unzipped a new Tomcat, set up a Context pointer to my webroot, and fired it up.  Worked like a charm, and after adding my DSN to the config file, the app was running.

I had to make a couple minor tweaks for Railo compatibility:

  1. Railo seems to stick getContextRoot() into cgi.script_name automatically, so I had to remove the function calls in my 'self' variable's definition
  2. Railo has an issue with non-defaulted, non-required, numeric method arguments that are omitted from a call.  I added it as bug 147 in JIRA.

After that I just checked /WEB-INF/ and the tweaks into Subversion for deployment to production.  On my prod server I did basically the same process: unzip  a Tomcat, set up a Context pointer to the existing webroot, configure an init script, and fire it up.  Once Tomcat was happy (first try!), I took the Alias directive out of my Apache config, replaced it with a mod_rewrite proxy directive, redeployed the app (to get /WEB-INF/ and the tweaks), changed the DSN credentials, and bounced Apache.  Done.  Live.  No errors.  And cookie-based session tracking worked flawlessly across the engine replacement.

Needless to say this is a HUGE win for both me and Railo.  I've been writing new stuff to Railo, but hadn't ported anything substantial because I didn't want to deal with the pain.  But with how minor the pain is, it's totally overshadowed by the benefits of separate contexts (or VMs!) per app.  That was never really an option with CF because of the memory footprint (350MB for CF vs 60MB for Railo).

jQuery's Autocomplete's Undocumented source Option

Yesterday I replaced an instance of my ComboBox widget with a jQuery Autocomplete.  A sad day it was.  However, I saved a JS file and a few K of download, so it was worth it.  Unfortunately, it's missing a fairly important bit of functionality: the ability to order the list of options.

If you're doing an Ajax-based complete, you can obviously order the options server-side and jQuery will happily spit them out in the same order.  In my case, however, the list of choices is static and fully known in the client.  jQuery only provides options for "url" (the URL to request for options) and "data" (a static array of options).  There's no half-way, where you can supply a function to return for the current term.

However, after spending a while digging around inside the internals of the widget, I discovered the undocumented "source" option (and it's complement, the "parse" option).  It's a function that will be called to get the options for the current term.  However, it seems to be undocumented, and is pretty tightly bound to the internal implementation of the widget.  Specifically, your return value structure has to be the same as the structure returned by the internal "parse" method.  Note this is NOT the 'parse' option I mentioned above.

If you don't supply data or a URL, the function passed as "source" will be invoked, and it's result will be either passed through the function passed as "parse" (if there is one), or returned directly.  That result must be an array of objects that represent the options.  Each object must have "data", "value", and "result" keys.  The first is an array of row data (passed as "row" to various callbacks), the second is the display value (what would come back from "formatItem"), and the third is the result value (what would have come back from "formatResult").

Mess though this is, it does let you execute arbitrary code to build the option list, including supplying a custom order, which is what I needed.  More specifically, I wanted to order tags that began with the search value before those that contained the search value in the middle.  Here's my code, just for reference.  "tagList" is an array of strings that are available for selection and the "tag" argument is the current value to be autocompleted.

jQuery("selector").autocomplete({
  source: function(tag) {
    var map = {
      first: [],
      internal: []
    }
    for (var i = 0; i < tagList.length; i++) {
      var pos = tagList[i].toLowerCase().indexOf(tag.toLowerCase());
      if (pos >= 0) {
        map[pos == 0 ? "first" : "internal"].push({
          data: [tagList[i]],
          value: tagList[i],
          result: tagList[i]
        });
      }
    }
    return map.first.concat(map.internal);
  },
  matchSubset: false // this is important
})

Eclipse and JUnit

I started building a little Java app this evenings.  First time I've done Java SE work in a long time, and it's kind of nice.  Not sure why I picked Java instead of Groovy, but whatever.  Probably the same reason people go home for the holidays.

In any case, being the good developer I am, after designing the core interfaces, I wrote some unit tests using JUnit 4.  Right click on the file in Package Explorer, hit "Run as JUnit Test" and it fires up in a fast view to show you how you did.  All very handy.  After a few tests, i figured I should build some test suites, but I really didn't want to.  I don't know about anyone else, but I always end up forgetting to register some test or another, and then I create a regression that would get caught by that test, but since it's not registered it doesn't run, and it's just bad.  So I didn't, and continued to run the tests individually.

After half an hour or so so, I had the idea to try right clicking on a package and see if I could run all the test in that package.  I was quite pleased to see that you can.  Same thing works at the source folder and project levels.  Little efficiency improvements like that make Barney a happy boy.  Of course, still have to write the suites if I want to run them from CI or the like, but this project at least will very likely never get there.

Are you a CF Rock Star?

Mentor Graphics (where I work) is looking for a top-notch CF/Flex/Java architect/developer to join our team.  There are five of us at the moment, and we need another one.  This is an on-site position in Wilsonville, OR (just south of Portland), and relocation assistance is available.

The "official" qualifications are pretty typical, and largely waive-able for the right candidate.  So here are the "real" ones:

  • know what ColdSpring (or Spring) is and understand why you'd use it
  • be able to compare and contrast, at least at a high level, a few Front Controller frameworks
  • articulate a considered opinion on JS vs. Flash for RIAs in different scenarios
  • know your way around Java SE and the Servlet API (more of JEE a plus)
  • explain why you'd use SOAP in a pure-CFML application that a single team owns from top to bottom
  • use CFEclipse because of Eclipse, not the reverse

Our work environment is casual.  We share a single "office" and spend a lot of time sitting at each other's desks working together and we have a dedicated "war room" for more in-depth discussion and planning (and a Wii for unwinding).  If you tuck your shirt in, you're probably overdressed.

Compensation is quite good, both the raw salary and the myriad benefits.  Mentor is a large, stable company, but without the Dilbert-esque nature.  The org chart is a meritocracy, pragmatism reigns supreme, and most of of the decisions (technical, architectural, etc.) are driven from the bottom up, not top down.

If this sounds like a place you want to work, shoot me a resume at bboisvert@gmail.com and I'll forward it to Ron.  The hiring process is simple: resume, phone screen, on-site interview.

Joe on ORM

Joe Rinehart made a very good post about the state of "ORM" in CFML.  Namely, that there isn't any.  There are several abstract persistence frameworks for CFCs, but no real ORM solutions.

Like Joe, I've been using Hibernate/Groovy to back a lot of CFML applications of late and it's wonderful.  Certainly not without some downsides, but having transitive state-based persistence is absolutely fantastic.  And Goovy makes implementing your entities so much easier with implicit getters/setters, non-tag-based syntax, rich types (for building schemas automatically), and a whole pile of syntactic sugar.

Sleepy Groovy

I just finished whipping up a quick little expense tracking app for Heather and me, and I'm again amazed at how wonderful the development experience is with FB3Lite, ColdSpring, and CFGroovy (Groovy and Hibernate for CFML).  When I was finished with the core functionality, I couldn't figure out where the app was.  There were my entities (in Groovy), my dsp_ files (in CFML), fbx_Switch.cfm, and a single CFC with a bunch of 1-3 line methods.  It's absolutely ridiculous how much code Hibernate saves you from writing with it's three pronged attack: HQL, state-based persistence, and transitive persistence (in an out).  It's further ridiculous how much code Groovy saves you in implementing entities.  With those two in place, CFML simply shines implementing the UI layer (with a snippet or three of Groovy in the mix).  Oh, and it's fast.

The FlexChart Manifesto

The current state of web applications is a fragmented mess.  HTML is still the standard approach, but dynamic data loading with Ajax and application embedding with Flash are both incredibly popular, particularly for data-heavy applications.

HTML is great because it's easy to build and well understood by user agents, but you lack drawing capabilities.  SVG addressed parts of that, and if XHTML ever gets adopted in any meaningful way SVG will see a resurgence.  The canvas element has stepped in, but it's not universally supported.

Flash is the other end of the spectrum: you have extreme customizability, but developing applications is significantly more work and requires people with a higher skill level than for HTML apps.  Flex, OpenLazlo, etc. attempt to ease the developer's pain, but it's still not nearly as easy as HTML.  Silverlight (Microsoft's Flash competitor) follows the same vein, though with the addition of binding to Microsoft's technology stack.  I'll only be refering to Flash from here out, because as far as I'm concerned here, they're basically equivalent.

Flash also has the significant downside that it's hard to go half way.  Applications tend to be either all Flash or all HTML.  Static HTML applications can add snippets of Ajax in an incremental fashion where they're best suited without going whole hog.  Of course, if you want to go whole hog with HTML, that can be a lot of work too.

But what does this have to do with FlexChart, you ask?

FlexChart provides a way for dynamic HTML applications to leverage the drawing capabilities of Flash in a nearly completely transparent way.  If you want to render a chart on a page in a static HTML app, you'll probably employ some server-side technology to build an image and embed that image in the HTML with the IMG tag.  But if you want to control the chart's appearance with JavaScript, you're in a bit of a bind, because you have to go server-side to generate a new image and then update the image source with the new URL.

Google Charts provides something of a solution for this problem, because the URL of the image implicitly causes a chart regeneration.  So you don't have to manually go server-side, it happens behind the scenes.  But as anyone who has worked with the API knows, it can be a bit of a bear to figure out all your data ranges, encode your data, lay out your axes and labels, compute bar widths, etc.  Plus, while the number of charts available is pretty good, they're fairly inflexible.  For instance, you can't plot a trend line across a column (vertical bar) chart.

FlexChart provides what I feel is a better solution for many applications.  It uses a simple XML dialect for specifying both chart structure and the data to display.  It leverages the Flex's charting engine to take care of all the chart layout tasks so you don't have to do that.  It's designed to be loaded once and draw multiple charts over the SWF's lifetime by passing it new XML descriptors via JavaScript (though it can also be used statically with descriptors from FlashVars).  Since it's Flash, it also has the ability to provide interaction with the user.  For example, when a user clicks a given data point on your chart, you can detect that with JavaScript and load a new drilled-down chart.  The tradeoff is that it's Flash, and while Flash has good penetration, it's significantly behind PNG support (what Google Charts uses), particularly on mobile devices.

As such, FlexChart addresses a narrow slice of the inability/reluctance to build hybrid HTML/Flash applications by providing a JavaScript-centric API for drawing rich charts.  Note that this API is not just for drawing static charts, you can register JavaScript functions for handling data tip rendering, click handling, and axis labeling.  This allows a very high level of interactivity that I've not seen replicated in any other charting package for HTML/JavaScript applications with similar browser support (or really at all).

Another significant advantage is the technology-neutral XML dialect that FlexChart uses.  There is absolutely nothing FlexChart-specific in the structure of the XML, so any charting engine could theoretically read and render the XML.  I'm currently in the initial stages of a Google Charts-backed implementation that does exactly that.  Yes, that means you can supply FlexChart XML to this new project and get back a Google Charts URL that displays the chart.  Obviously it won't be a complete implementation because of limitations in Google Charts (like the mixed line/bar chart issue), but for supported aspects it will be equivalent.  This will allow an application to render charts either as Flash (with rich interactivity) or as PNG images (for broad support) without having to change the format used to describe the charts.

Note that the XML descriptor language does NOT provide for the full gamut of capabilities that Flex's charting components have to offer.  Nor will it cover all that Google Charts has to offer.  The idea is that it provides a simple way to describe most common chart types, and do it in a rendering-neutral way.  I've also gone to great lengths to hide much of the complexity that Flex (and soon to be Google Charts) foists on chart developers.  For example, Flex forces you to create a huge number of redundant axis references when laying out complicated charts, but with the XML descriptor you can do it once at the top level.  In the other direction, Google Charts forces you to explicitly specify all your axis labels and their positions, but the XML descriptor is such that they can be figured out for you by the implementation.

As I alluded to above, if XHTML actually gains adoption and SVG makes a comeback, that's another very likely candidate.  I've used an SVG-based charting engine that I wrote five of six years ago on several applications (currently using Batik to conver the SVG to PNGs for display), so that would be another potential implementation.  There are several canvas-based charting engines as well, all of which could be potential targets.  Finally, there are preexisting XML-configured Flash-based charting packages (FusionCharts is one example).  Leveraging one of those packages from the unified XML dialect would come for the cost of some XSL templates.  The possibilities are quite promising.

FlexChart itself is only half of the puzzle.  Sure, it's greate to have nice charts in a HTML/JavaScript application, but the bigger picture is just as important.  Having a single way to describe charts across applications and rendering mechanisms is a huge win.  Even more useful is bridging the gap between HTML and Flash with a way to create hybrid applications, instead of people seeing them only as two alternatives.  This is a huge win for all web app developers.