Rhino + JavaScript + Swing, Look Ma No Java

A while back I was discussing the future of programming languages with a colleague, and we agreed that for all its foibles, JavaScript will continue to enjoy very wide and increasing use in the coming years. I wrote last year about Steve Yegge’s hints that JavaScript is the “next big languages”, see that post for the reasoning.

Based on all that, I set about writing a small test app to see what it’s like to program a Swing app with JS.  After a day or so of work (spread over a few months), I offer my Rhino Swing Test App:

Run RSTA now via Java Web Start

Get the RSTA code (git, on GitHub)

It implements the same “flying boxes” animation demo that I presented a few years ago at the St. Louis JUG, but aside from a generic launcher class, the GUI is implemented entirely in JavaScript. To clarify, this is not web browser JavaScript; it is running in Rhino, in the JVM, using Swing classes.

The documentation for interaction between Java and JS is limited, but sufficient. For simplicity, I used Rhino as an interpreter, I did not compile to java bytecode. Nonetheless, the animation runs about as smoothly in JS as it does in Java, because the heavy lifting is done by the JDK classes.
I used Eclipse (with JavaScript support) to write this code, but of course JS makes much less code completion possible than Java, and I missed that. Typically I mildly prefer IDEs, but am also productive with a text editor. For working with a large API like Swing though, IDE support helps greatly.

Still, I recommend a look at this approach if you are fond of dynamic languages but need to build on the Java platform, and I intend to investigate server-side JS development also.

Ease of Installation: DokuWiki, PHP, files

In the past I’ve installed MediaWiki, ruwiki, git-wiki, and several other Wiki implementations (Perl, and Java implementations), with varying degrees of effort. For example, ruwiki required considerable gymnastics to get the right Ruby libraries in place on the machine I hosted it on, MediaWiki required a database, etc. Ruby libraries, databases, JVMs, and the like are all at the top of my toolbox so in most cases it’s just a few minutes and a few commands, which seems amply easy until compared wtih…

Yesterday I set up a DokuWiki instance (which stlruby.org might migrate to), and found that its underpinnings (PHP, plain text files) make for ridiculously easy installation:

  • wget
  • tar xzf
  • browse to install page, set a few settings
  • delete install page

Yet those underpinnings are very well suited to the task at hand. A typical Wiki does not need a database underneath it. As with many things, this reminded me of a general principle: use the least complex, most readily and commonly available, easiest to administrate technology appropriate for the task at hand.

Webby – Client-side, static content management system

This afternoon I rebuilt OasisDigital.com using Webby, stripping out hand-coded HTML and replacing it with much more maintainable Markdown. The site looks about the same as before (which is to say, mediocre), but under the hood it is much easier to update. We intend to use this new ease, to move forward in improving it. There is a general principle here, which applies broading in software development also:

If you need to make a change, but that change is difficult / tedious / risky to make, first improve the underlying system that makes it so.
(OasisDigital.com is a static web site; we have dynamic contact (issue trackers, etc.) to automate our work together and with our customer, but that content is on another domain.)

Webby is a client-side, simple CMS for generating static web sites, written in Ruby. Why serve a static site (plain old files on a web server) in 2008?

  • It minimizes the moving parts, there is almost nothing to break or maintain.
  • It is very unlikely that any hosting issue will break a static site.
  • It is easy to serve a static site fast (though our current host, TextDrive, sometimes is not all that fast).
  • Security vulnerabilities are very unlikely, in the absence of any executable content.
  • The canonical content (in this case, mostly Markdown) is stored in plain text files, which we track, diff, and merge in git.

In an earlier foray in to Drupal, we found that Drupal has extensive and useful capabilities, as well as a vibrant community, but it also has many moving parts; too many, in my judgment, to make it a good solution for building an essentially static web site.

TDD, Still in Style?

Test Driven Development doesn’t seem to be in style today to the extent it was a few years ago. I think that’s a shame, because TDD is among the most powerful ideas I’ve come across to boost the quality of the software we deliver. At Oasis Digital we even use it in unusual places, like this Palm application we develop for a customer:

This application forms the core of our customer’s business; they sell it at a commercial product to their customers, who use it in high-pressure situations. Over 4 major versions and 4+ years, there been remarkably few bugs or other issues found “in the field”, which I credit to:

  • Use of automated testing
  • An overall level of care and attention to quality

The second item alone is not enough. To achieve quality you need to do more than have the right intentions and work hard. You need to do the right things.

Start with a Prototype

I have often given the advice to start each project with an end to end working first draft, also known as an evolutionary prototype, and sometimes I have even followed this advice myself. My own projects have been most successful when following it, such as in three projects that come to mind:

  1. A 6+ year project, with a team of developers. In month 3 it was deployed to production, meeting real needs.
  2. A 4+ year project, with a team of developers. In month 2 it was deployed to production, meeting real needs.
  3. A 10+ year project, initially just myself but later with a small team of developers. In month 1 it was deployed to production, meeting real needs.

On the other hand, most failed projects that I am aware of had been slated from the beginning to not deliver a working system until late in the schedule, and ended up not delivering at all.

The traditional software development plan for a typical enterprise forms-database-rules-reports application looks like this:

  • Planning and design
  • Implement schema
  • Implement infrastructure
  • Implement admin/setup features
  • Implement core features (transactional data)
  • Implement reports

This waterfall model is a great way to think about software. Think through your requirements in depth at the beginning, and write them down in a coherent form. However, this is generally a bad manner (specifically, a very poor order) in which to write software.

Thanks to the agility movement, many teams are now using iterative, incremental approaches. Unfortunately, it is common nonetheless to lose some of the benefits of agility by laying out a set of releases with features/work in approximately the traditional order.

The solution, espoused by the Extreme Programming movement but rarely executed, is to start at the very beginning of a project, with building an end to end, first draft, working prototype system. This then grows slowly over the life of the project in to the finished product (i.e., it is not a throwaway prototype). We take this approach at Oasis Digital, and generally require it of our subcontractors also.

Development proceeds in a way that we create a working, end-to-end system with minimal features, very early in the work. For example, on a typical forms-database-rules-reports project, after a few days of work, we have:

  • A little bit of schema, just enough to support a small subset of desired features
  • A few screens, with very few features
  • A report or two, again with very limited features
  • Placeholders for some other screens and report, to allow the beginnings of the desired final application flow to appear

Then as the work proceeds, every week (or less) we can deliver a working system with a few more features present.

But this is impossible on my project!

The question is not whether this approach is possible; rather it is to what extent it can be done on each project, and what can be done to make it possible? The primary tool is imagination, in selecting a small subset of the desired feature set which plausibly works end-to-end.

For example, perhaps you are building a CRM (customer relationship management) system, one with thousands of features, 200 database tables, 450 reports, 85 screens, etc. How could you build a working system in the first week? Start by reducing the system to be its bare essence of companies, contacts, and interaction history.

A second example is a time tracking system with elaborate rules, reports, approval mechanisms. For the first draft, discard most of that and create only the ability to add a user (forgot edits and deletes, forget most of the fields), to enter hours for that user (forget approcals), to see a screen with those hours (with the simplest possible layout), and export a data file with those hours (any data file format, forget XML for now).

A third example is a trouble ticketing system. For the first week, make a way to add a ticket, a way to add notes to a ticket, to see a list of tickets, and to close a ticket. This could readily all occur on one screen, with only a few buttons. Its schema could consist of three tables: user, ticket, note.
A fourth example is a system which will write checks. In the very first week of the project, make it write a check. Dummy-out as much as needed to make it achieve this core goal.

Just Do It

Certainly there are plenty of problem domains where this advise doesn’t readily fit. But don’t be too eager to make that claim. By finding a way to deliver a working system early, we eliminate the risk that the project will never deliver anything, and we make progress and value visible (continuously) to whoever is paying for the project.

On the Job Training

I recently heard from a developer who worked on a project here for about one year, several years back. I won’t name or quote him directly; the essence of his message was:

  • He learned a lot during that year.
  • This learning was a turning point in his career.
  • What he learned has proved lucrative.

Of course it feels great to receive a message like this, but beyond that, it got me thinking about on-the-job training at Oasis Digital. We don’t have a formal training process. Rather, opportunities (and pressure) to learn and improve are woven in to our daily work. Described in coarse terms, a typical workflow for a developer (“You”) starting out on our projects is:

  • You write some code (or other work product).
  • Tech lead and other developers (sometimes including me) complain about it. This takes the form ideally of constructive criticism.
  • You improve the code.
  • More criticism.
  • You improve the code more, resulting in code that essentially works.
  • Tech lead revamps and refactors it mercilessly, explaining what was changed and why. Note though, that at this stage the changes do not require justification.
  • Tech lead sends developer a list of things to further improve.
  • You improve the code.
  • The code is now good enough to go in to the project.

It turns out that this process is a very good learning experience, if you are willing to take feedback. It can be hard to hear feedback, especially if its essence is that that your work product is not all that great. Yet the computer is merciless, it does not care about your feelings. The end customer does not care about your feelings either; both care only about correctness and quality.

I started out writing bad code. Having written many lines of such code, I now, somewhat regularly, write good code… though I am certain there are plenty of better developers out there who could find much fault in it. Writing bad code and accepting criticism of it is on the path to writing good code. Is it controversial to observe that a lot of software is quite bad? If so, that’s fine; I mostly agree with Steve Yegge’s observation:

By way of setting context for today’s blog, I’ll summarize everything I’ve ever written to date in one sentence: I think most software is crap.

By accepting that most software is bad, you can get on a path to make yours better. It turns out that working on our projects gets you a lot of coaching and training; and instead of paying for these things, you get paid. For the right kind of developer, I think this is an important part of our value proposition and compensation.