(I apologize for the length of this one … but it’s a big topic.)

Mike Clark wonders where we went wrong with J2EE.

There are many answers to that question. The glib one is “J2EE is the wrong platform for a Hello World application.” A slightly more serious answer is that the architecture of the web is to blame. There is a lot of truth in both answers, but they miss the point. Hello World is just the extreme case of the broader problem that J2EE applications are much more complex than they have to be. Dave Thomas’ question about Hello World is just Dave’s way of getting us to consider why that is. As it happens, I’ve been thinking about the same problem a lot over the past few weeks.

I recently had lunch with a friend who has been away from coding for a couple of years (and before that he didn’t really do any J2EE work). He was in the middle of trying to explore two thingsblogging and J2EEby installing and investigating Roller. He got it installed and was using it for a blog, but he was very frustrated by trying to understand it. He’s no slouch when it comes to reading code; in fact, he has a reputation for being extremely good at picking up large systems and quickly understanding them well enough to make urgent changes. But Roller struck him as needlessly complex, with the sheer number of different frameworks, config files of different types, internal interfaces, etc. He did not have the impression that it was a Roller problem; he had come to the conclusion that this is just the state of J2EE. And whether Roller is a particularly good or bad example (I know hardly anything about it), my friend was definitely right about the state of J2EE.

He asked me the same question: “What went wrong?”

About ten years ago I read Bjarne Stroustrup’s The Design and Evolution of C++. It’s a wonderful book that I highly recommend. Stroustrup explains how C++ came to be how it is (or was, at that time), including rejected ideas, rationales, goals and priorities, etc.

The fascinating and troubling thing about it is that Stroustrup began with a language I likeCand made a series of very sensible design decisions, ending up with C++ (a language I don’t like). I found myself asking the same question as I finished that book. What went wrong?

Any answer to that question is bound to be too simplistic, but I think it’s not far from the truth that the misstep in the case of C++ was the very first one: deciding to implement a strongly typed OO system atop fast-and-loose C.

Looking at J2EE today, I find myself thinking similar thoughts. Of course, not all of the decisions were nearly so reasonable as Stroustrup’s C++ decisions (I have some friends who were involved in the original design of J2EE, and there were some very unpleasant political and marketing forces involved). But even if they had been, I fear the result would have been much the same.

Here’s what I think the problem is: we started with a language that is insufficiently reflective (so that it can only be extended in limited ways from inside) and that has too much syntax (making it difficult to adapt to more declarative tasks). So we have containers, code generators, interface generators, EJB compilers, and bytecode enhancers, XML config files running out the ears, and on and on.

It doesn’t have to be that way. Try building web apps in Ruby, using Borges. Or Smalltalk, using Seaside2 or Comanche. Or in Common Lisp, using KPAX or WebActions.

(It’s funny to note that the KPAX document contains the source for a Hello World application, the core of which is this Lisp call:

(defwebapp :helloworld
      (:root "/Users/tarkin/cvs/svc/kpax/example/helloworld/")
      (:prefix "helloworld")
      (:index "index")
      (:actions '())
      (:users (list (make-instance 'web-user
                                   :id 101
                                   :short-name "guest"
                                   :full-name "Guest User"
                                   :password "trustno1"))))

It’s even funnier to note that I’m almost guaranteed to get email from someone complaining about how hard Lisp is to read, but who doesn’t mind reading XML config files.)

Just today, during the blog roundup, I saw Chad Fowler and Rich Kilmer blogging about RubyGems, the Ruby package installation system they and others wrote this weekend at RubyConf 2003. From Rich’s blog about RubyGems, here’s what an example package definition looks like:

require 'rubygems'

    spec = Gem::Specification.new do |s|
      s.add_dependency('rexml', '> 2.7.0')
      s.name = 'jabber4r'
      s.version = "0.5.0"
      s.platform = Gem::Platform::RUBY
      s.summary = "Jabber4r is a pure-Ruby Jabber client library"
      s.requirements << 'Jabber server'
      s.files = Dir.glob("lib/**/*").delete_if {|item| item.include?("CVS")}
      s.require_path = 'lib'
      s.autorequire = 'jabber4r/jabber4r'
      s.author = "Richard Kilmer"
      s.email = "rich@infoether.com"
      s.rubyforge_project = "jabber4r"
      s.homepage = "http://jabber4r.rubyforge.org"
    end

    if $0== __FILE__
      Gem::Builder.new(spec).build
    end

Again, you may be able to find a few reasons to prefer XML, but the readability and simplicity of the Ruby version is indisputable, and a lot of power comes from having everything be within the language. A lot of power.

Also from RubyConf, one more answer to where we went wrong with J2EE, and Java in general. Matzthe inventor of Rubytitled his keynote address How Ruby Sucks. Java folk have always taken the language too seriously. It’s too late nowit would incite an irrational panic among Java developersbut we might be in a much better place today if, about five or six years ago, James Gosling had been able to deliver a talk about Java in that same spirit.