2005/10/28

RoooooaR!

Crushing all in it's path

So it's become increasingly evident to me that the the hour at which Ruby on Rails proceeds to stomp all over 80-90% of all Java webapp development is coming closer and closer, if it hasn't got here already.

As a developer, who's been online for ages and a computerphile for even longer, seeing whole fields of technology and millions of man-hours of work obsoleted in a period of months is something I've seen over and over again, so I knew it would inevitably happen to my own sub-sub-field.

And so, as a Java webapp developer, this necessarily requires a response, such as (for example) moving to RoR myself. I can do that if I have to, no problem, in fact I'd kinda look forward to it.

However, I'd like to make one thing clear: to anyone who claims that RoR can do things Java can't, I would politely request that they renew their acquaintance with the concept of the 'Universal Turing Machine', and then come back an re-examine those claims in the light of their newfound knowledge.

</snide>. Myself, I've also seen plenty of reaction from the world of Java, starting with things like Trails and Sails, and continuing with the various solutions that have been welded ontop of existing frameworks.

However, this is not enough to prevent Java's obsolescence in this field. All these solutions so far have been reactionary, and while it's good that the world of Java can readily admit influence from outside sources, all these solutions, by virtue of being copies or tributes to the original, cannot help but serve as a mere reflection of the power of the original.

(It's also worth noting that Python, Perl, Lisp etc. all had their Rails knock-offs months before Java did.)

Firstly, there are interesting ideas that don't exist in RoR. Of all of these, the most interesting by far is continuations.

Put simply, Spring Web Flow and Apache Beehive both encapsulate page-navigation workflow through the construction of state machines, similar in principle to directed state graphs, and influenced to a certain extent by JSF. [Web Flow does actually support continuations, I've just discovered.]

This is one way of expressing logic. However, logic is far better expressed in (guess what) a full-featured programming language, which will always be richer than any configuration file. This is what continuations should be used for. Construction of wizards, guides and sub-sequences could hardly be more natural.

Secondly, the (at least) two areas in which RoR is indisputably king is in inferring webapp structure from database structure, and in the all-important zero-turnaround time. Neither of these are impossible to do in Java, but I'll take them in turn.

Firstly, ActiveRecord. What is it that RoR does? Simply put, it makes the database the 'center of authority' (CoA) for the structure of the web-app. It infers what it can, which is usually 90% of what is needed, and lets the developer add the finishing touches.

Trails is similar in that it uses the business object model (BOM) as the CoA, and uses that to generate both the persistence (database) and the frontend webapp. This is in keeping with the Java view of keeping the semantic discussion at the object level instead of the DB level.

However, Trails also requires you do use annotations, which assumes that you have control over the source of your BOM, which in many cases isn't true (SOA-based methodologies can mean that you're simply the client of a different division, and that your BOM is generated from WSDL/XSD). This isn't a problem, Trails could just as easily use reflection to infer all the stuff that the tags point out to the framework.

Secondly, zero-turnaround time. Template-wise, Java already has this because JSP is recompiled when the source file changes. Personally however, I think JSP (1.x) sucks, and the whole idea of compiling markup templates into .class files is braindead, so I won't rely on this example too heavily, but nevertheless it proves my point.

WRT. zero-turnaround Java, in the traditional webapp this is of course not possible, but (a) this assumes that Java is your workaday language, whereas in fact it's entirely possible (and often desirable) for other languages such as Groovy, Rhino etc. to provide the meat of the application, for this very reason among others, and (b) you're not using something like Janino, which effectively provides the eval() function, and then some, to your normal JVM. (At a cost of course, but that's what facades are for.)

Yet another framework?

Which brings me to my point. If Java webapp development is not just to survive but also to thrive, reacting to RoR is not enough. It must also leapfrog RoR in the metrics by which RoR judges itself.

You can stop laughing now.

It's OK, I'll wait.

This in itself is fairly simple. So far people have been expressing web-development in lots of different languages, some (such as Ruby) more sympa than others (Java), but all of them, even JavaScript, when it comes down to it are not webapp-native languages.

For webapps, when it comes down to it, the language is very simple. There are four verbs: Create, Read, Update, Delete (CRUD). Your set of base nouns is defined by your database, or your object model, where-ever you put your authority. You derive nouns by operations on your base nouns. Each noun can have the four verbs applied to it.

This is all you need for webapps. The rest is reporting - list views, summary pages, query interfaces, etc. In an SOA environment these are simply other services, so that's easy for me, but I imagine other solutions would have to be found for this.

Thus the whole issue is resolved to three domain-specific problems: how to derive nouns, how to customise templating, and how to customise verbs.

(The typical Java response would be to have three different XML config files. Grr. Me, all my config files are generated via xDoclet and other fiddles, so *.xml is simply not part of my development world.)

Deriving nouns: can be done either way, by reducing/eliminating BOM fields or by expansion, i.e. creating new objects mapped from the old ones. Both should be possible, so I'm thinking of something like XPath or JxPath, or CSS-style selectors.

Customizing templating: obviously, model changes shouldn't re-generate and overwrite changes you made to previously generated templates, so a merge algorithm should be used by the framework in updating templates (this may be the sledgehammer approach.)

Customizing verbs: obviously done in the same language as the verbs themselves. Again, either with merges or an AOP-style thing (not my preferred choice).

Once this is all done, continuations take the verb-noun operations and turn them into complete sentences.

The one thing I haven't mentioned so far is validation, and that's because this is a simple choice: it should be done in JavaScript. This is so that exactly the same logic is used server- and client-side, It also avoids extra code-generation, is DRY and can be changed in-flight, just like the above thee things.

Or not.


So, that is my idea. Not that complicated, intended to be incredibly powerful and very flexible. Why shouldn't I do it?

Firstly, there are already far too many frameworks out there. I should find a way of augmenting an existing structure, saving myself lots of time and contributing to something bigger than this in the process.

Secondly, creating a framework is a bad idea. I should know, I've already done it once or twice.

Thirdly, Java webapp developers such as I are not paid to work on frameworks, but on solutions. Therefore this should be done in my spare time, which introduces all kinds of issues when using it at work, for example.

In conclusion, the world would be a much better place if only everyone did what I said. the world of Java is not without hope in the latest mindshare battle. That said, any cool idea used in a Java framework would probably still end up easier to use and simpler in Ruby, by virtue of it being a nicer language.

Aargh.

No comments: