Monthly Archive for September, 2008

Application.cfc Mappings Gotcha

If you use Application.cfc mappings on Adobe CF, watch out.  If your mapping names contain only alphanumerics, the leading slash is optional.  However, if the name contains other characters (like an underscore), then you HAVE to use the leading slash or it won't resolve.  Ran into this on an app where my "coldspring" mapping worked flawlessly, but my "schema_tool" mapping refused to resolve.  Unfortunately for me, I wasn't aware that "coldspring" worked until about half an hour in to troubleshooting, because the "schema_tool" mapping gets used first.

The livedocs' example does not show leading slashes, which misled me for quite a while after I resorted to looking there when it didn't work.  It's been a long time since I went to livedocs, and I remember why.  ;)  If you scroll down, however, there is a comment about the leading slashes.  It's only five months old, so hopefully it'll get incorporated into the actual document at some point.

In the mean time, make sure you get those leading slashes in there!  I haven't tested this issue on any other CFML engines, but as long as you don't forget the slashes, it shouldn't matter.

FlexChart Update

Been a long while since I've made any updates to FlexChart, and this is only a minor one, but it's potentially important.  Since it's designed to be used in JavaScript applications, data tips and click events are all processed by JavaScript (not ActionScript).  When I'd created the data tip callbacks, I'd neglected to considered the hierarchical nature of sets of series.  So I've added a 'seriesContext' array that contains the context for the series that is having it's data tip generated.  This is strictly an additive change, the existing 'seriesLabel' remains, though it is present in the 'seriesContext' array as well.

What is this good for?  I need to create a funnel chart, and while the built-in stacked-column chart is close, it computes the percentages in the data tips the wrong way.  Reimplementation was a snap with the context, just pull the relevant numbers out of the descriptor XML and do the division.

Even More Groovy

I have a confession to make.  My neat little code counter utility is partially a lie.  I wrote the entire thing as a single Groovy script, and only split it up into individual files for each class to release it.  271 lines of code (419 if you count the blank lines) simply does not justify seven distinct files.  That said, it does justify a runner script and six distinct classes.  So if you want the "real" source, just take the six classes, copy them directly into Runner.groovy and then delete the files.  Everything works exactly the same, except it's all in one concise package.

The project started with a pile of procedural code (i.e. a Groovy script), all inline with no classes at all.  My basic concepts proved sound, and I started refactoring.  Does anyone NOT like refactoring?  If so, raise your hand so I'll know who to slap.  ;)  Classes quickly started falling out of the proof-of-concept code, and soon I had my four core classes (CodeCounter, ProjectInfo, PathInfo, and FileInfo), plus some no-longer-quite-functioning output code.

Once the "backend" was refactored into a stable model, the front-end went just the same.  XML was the format of the original script, and so I reimplemented the same output based on the model, rather than emitting it inline.  To ensure I wasn't being stupid and coupling where I shouldn't, I threw together the text renderer as well.

I'm a huge fan of this style of development, and do much the same thing with CF.  Start writing one big-ass file with no real concern for parameterization, abstraction, or encapsulation.  Once it works "enough", start refactoring for those three characteristics, as well as extending the functionality into something useful to the real world.

Doing Java is a bit harder, since you have the object nature foisted on you from the start.  You can still begin with one class and a pile of static methods, but the refactoring is a bit harder, I think, because of the static/dynamic transition.  With CF and Groovy, you pretty much bypass all of that (thank you compilers!), which is very nice.

What's the downside to this style of development?  Unit testing is hard.  With a rapidly evolving project (structurally), having to evolve unit tests can be a significant burden.  Not to mention that you can't really unit test a single large script; you're stuck waiting until you have an class which is after most of the work is done.  So if you write unit tests at all (I didn't), they have to come late in the cycle.

The main benefit is that you don't have to think about architecture before implementing functionality.  If you know exactly what your desired functionality is, and know how you're going to approach implementing it then architecture is the "hard" part, and unit tests can help ensure your implementation matches what you expect/require.  However, that's not the case a lot of time.

More Groovy Goodness

Yesterday afternoon, I was talking to a friend about one of my apps, and he asked about how big the app was.  I had no idea, and thought I'd write a little app to figure it out for me.  Oh how easy Groovy makes things.  The basic idea was to build a simple parser to return counts of files, directories, lines of code, and bytes, as well as break them down by file types.  Hand that data structure off to a renderer for output, and you're done.

The code is available at https://ssl.barneyb.com/svn/barneyb/code_counter/trunk/, just check it out and execute:

groovy Runner </path/to/project>

Executing the project on itself, you get this output:

                         Count      All Lines     Real Lines          Bytes
---------------------------------------------------------------------------
Paths                        1
Directories                  1
Files                        9            422            291          8,047
   text                      9            422            291          8,047
      groovy                 7            402            271          7,945
      txt                    2             20             20            102
   binary                    0                                            0

<project pathCount='1' fileCount='9' directoryCount='1' byteCount='8047' lineCount='422'>
  <type type='text' fileCount='9' byteCount='8047' lineCount='422' realLineCount='291'>
    <extension extension='groovy' fileCount='7' byteCount='7945' lineCount='402' realLineCount='271' />
    <extension extension='txt' fileCount='2' byteCount='102' lineCount='20' realLineCount='20' />
  </type>
  <type type='binary' fileCount='0' byteCount='0' />
</project>

You can also pass in multiple paths (if your project has multiple components), and you'll get per-path breakdowns as well as the totals.  The two output formats are created by separate renderers (text and xml) operating on the same data structures, and each can be used independently.

Of particular interest was the ease of counting lines (line 2 gets the lines in the file as List of Strings, line 3 counts them, and line 4 counts the ones that have non-whitespace characters):

// 'file' is a java.io.File
def lines = file.readLines()
this.lineCount = lines.size()
this.realLineCount = lines.sum(0, { it.trim().length() == 0 ? 0 : 1 })

Similarly, reading the configuration for which files to ignore, and which extensions are considered text files:

TEXT_EXTENSIONS.addAll(getClass().getResourceAsStream("/text_extensions.txt").readLines())
FILES_TO_IGNORE.addAll(getClass().getResourceAsStream("/ignore.txt").readLines())

This piece, in particular, I'd intended to leave as configured-in-code, because I didn't want to deal with the external resource headache and then the parsing of the files once I got them.  Ha.  As if Groovy would make me do that.

There's a whole bunch of other stuff in there, particularly the mixing of implicit and explicit getters to unify object APIs.  If you want a directed tour, the core of the app resides these methods: CodeCounter's constructor, PathInfo.processDirectory, and FileInfo's constructor.  The output is handled by TextRenderer (using a PrintWriter) and XmlRenderer (using MarkupBuilder).

Total time to build the app was about an hour, required no special editor (I used TextPad), IDE, or compiler.  The classes can be executed in any Groovy environment (including CF Groovy), or run them through groovyc and use them in any Java environment.  Oh how nice it is.

Meme(me)

Per Mark:

The Rules:

  • Take a picture of yourself right now
  • Don't fix your hair, don't change your clothes, just take the picture
  • Post that picture with no editing
  • Post these instructions with the picture

I do this every day, meme or not.  See the stream, or get it as RSS.

CF Groovy Preso

Last night I talked at the PDX RIA group about using Groovy to extend CFML applications and better leverage some of the benefits that Java has to offer (in addition to the benefits Groovy itself brings).  Unfortunately we had some technical difficulties, but the presentation was recorded on Connect, and can be accessed at http://experts.na3.acrobat.com/p71343823/.  I apologize for the delay in posting, I usually try to get things up immediately afterward, but just didn't happen this time.

In addition to the Connect recording, I've posted my slides (in PDF format).  The sample app I demoed is just the CF Groovy demo app available at https://ssl.barneyb.com/svn/barneyb/cfgroovy/trunk/demo.  Within the demo app is the framework itself, including Hibernate (whose JARs are the source of the large download).  The demo app is also available online should you wish to run it without having to download anything.  Of course, there's not much to see without the code.

Why, Microsoft, Why?

I've had the unfortunate luck to partially inherit sysadmin duties for the web team at Mentor (along with Joshua) after one our coworkers left.  While I don't necessarily mind a sysadmin role, almost all of the infrastructure is Windows.  The sole exception is our Subversion server, which is Linux, and only because I migrated everything of the existing Windows box last year sometime.  That migration was done specifically for the mod_python support that Linux provided to gain a significant performance benefit for Trac.

So today, I'm trying to help the boss install this Scrum management application on one of our internal servers.  It's an ASP.NET application (horror of horrors, I know), and the server doesn't have the WWW Publishing Service installed.  It's got IIS for the mail server, but all the apps on there are standalone JEE apps, and we just let the container serve directly to the network.  Simple process, go into Add/Remove Programs, hit the Windows Components button, find the right item, check it's box and hit next.  Ha!

Apparently the Cluster Service (which we didn't ask for) requires MSDE to be installed, and while it's listed in the installed programs, it was apparently not installed enough.  So we spend like an hour trying to find this stupid MSI that it needed.  My question is, why the heck can't Windows go get this package automatically.  When I install Apache via 'yum' (on Linux), it magically goes and gets everything it needs, all by itself.  And keep in mind that we have to pay money in order to use Windows and IIS!

Eventually we gave up, hit Cancel about ten times to skip the Cluster Service, and the rest installed.  We installed the app (which needed the ability to create it's own database, I might add, refusing to accept an already-created one - WTF?) and it didn't work.  Little did we know that while we could go edit the ASP.NET settings in the web site properties, that doesn't mean anything.  The properties just sit there until you go install the ASP.NET Windows component.  Next question: why the hell can you use a Windows-provided dialog to configure a service that isn't installed?  Surely dependency management is something they understand up in Redmond, and things like making configuration dependent on the software to be configured seems reasonable?

I haven't been around Windows servers in a good number of years, but this kind of lunacy is just what I remember from when I was.  No visibility into what's going on and/or why, plenty manual work to get things juuuuuuuuuuust right and then no way to save that stuff in SVN in case it breaks, and horribly fragmented everything.

Fortunately, we're slowly replacing IIS on all our other boxes with Apache so we can at least version the config and use such radical tools as copy and paste.  We've just about eliminated JRun in favor of Tomcat.  Once CommonSpot is gone from our last property still using it we'll be free of that burden.  We still have huge investment in MS SQL Server, but beyond that, we'll actually be in a position to start switching servers to Linux, which will be awesome.

The success of the SVN server (perfect uptime, great performance, easy configurability, etc.) has definitely shown the utility of a programmer-friendly OS and toolset over what Windows provides.  Hopefully that carries sufficient weight to justify migrating other infrastructure where there's not a specific platform advantage to exploit.

Stream Layouts

No, I'm not talking about those things full of water running down the mountainside, I'm talking about how you assemble a full HTML (or whatever) page from a webapp.  Being a Trac user, I've done a bit with Genshi, and then with Grails used SiteMesh, both of which are stream-based engines.  I'd always though the paradigm was a bit odd, and kind of inside-out, but today I realized they're exactly the right way to do things.

The basic idea is that your app generates the page body, as a full HTML document, and then it gets passed down the stream and manipulated.  Maybe it gets some LINK and SCRIPT tags added to the HEAD, or a footer to the end of the BODY.  Contrast this with the "content variable" assembly process, where your app generates a bodyContent variable which is handed to a layout to render into a full page.

What invariable ends up happening with the latter approach is a whole pile of variable along with bodyContent (headContent, pageTitle, footerContent, aboveFooterContent, belowFooterContent, etc.).  A huge mess, especially if you're using Fusebox or something like it, where you typically put your HTML in a dsp_ file and include it into a content variable, because you end up with a massive number of one-line includes, most of which are all bound to rendering a single page (i.e. aren't reused).

Contrast that with SiteMesh or Genshi, where you can package all those separate pieces up in a single packet, and let them stream out of your app to the layout engine that takes care of everything.  It might be combining your content with another app (think a portal), might be wraping it with header/nav/footer, might be restructuring it for an iPhone vs. a PC.

This doesn't come without a downside, of course.  For example your navigation isn't controlled by your application anymore, so if you're addicted to XFAs (as I am), you're kind of stuck.  For websites it's not as big a deal because you don't want your URL-space changing, but for applications it's a bit more troublesome.  This is straightforward to deal with in the opposite direction, however.  There are also some performance implications, though they're pretty trivial.

I'm trying to figure out a good way to integrate SiteMesh with CFML.  CF is just a huge burden to try and drag into the JEE way of doing things, but Railo should be far simpler.  I really don't want to use JSP for the layout engine, and while I like using Velocity, keeping to a single templating language is certainly beneficial.  Whether I'll actually have time to implement something remains to be seen, but it sure would be nice.

Groovy Preso on Connect

My Groovy presentation next week for the PDX RIA will also be available online (via Connect) at http://experts.na3.acrobat.com/r59025898/.  A recording will be available as well, but that URL isn't available until afterwards.  I'll post it after the meeting, along with my materials.

Groovy at PDXRIA

Next Thursday (Sept 11) I'll be presenting at the PDX RIA group (formerly CFUG) about Groovy.  Someone (cough…Simeon…cough) hasn't updated the site with the new info, but rest assured that it's happening.  As you might imagine, I'll be talking about my CF Groovy framework, but I'll also be talking about JVM language integration in general, Groovy in general, and how hybrid apps are a good thing.  Included in that will be some Hibernate goodness, which I'm still amazed by every time I pick it up because of the drastic reduction in code to write.

Unfortunately, I'm currently at a job where leveraging these technologies is verboten.  We use CF8 and Magnolia (a Java CMS) for most of our sites, so it could be really handy to shell out for some "Java" without invoking a compiler.  However, it doesn't happen like that.  We write some Java, compile, deploy, cycle the container, test, repeat.  Or we hack together something with CFML to synthesize the functionality we need.  I get some relief on personal projects, where it's CF Groovy w/ Hibernate all the way, but that understandably pales in comparison to my at-work efforts.  C'est la vie.  I do get a paycheck for the work stuff, which does a remarkable job of offsetting the downsides.  ;)