Java, Pain, and Low Productivity
The purpose of art is the lifelong construction of a state of wonder.
- Glenn Gould
There is a widespread feeling in the Java Community that there is something seriously wrong with Java web apps.
They are much too hard to build and maintain.
Below are some typical comments which illustrate this widely held opinion.
WEB4J was built in response to this issue, and it claims to demonstrate
that the problem lies not in the language, but rather with inadequate, overly complex frameworks.
Quotes from the community:
I think a lot of [the recent excitement regarding scripting languages]
has to do with just pure pain. [People] have been developing now in languages and frameworks,
which started out simple, started out elegant, and then gradually just accreted more and more stuff around
them - to the point where now I don't even know how a beginner J2EE developer gets started, because the stack
of books you have to read just to write a simple J2EE application it's probably 5-6 feet tall and it's a
lot of work just to get in there...
"I think Java, for the simple applications, is in trouble.
I see Rails as a fix to the major problem we solve most often: web enabling a relational database. For that
space, Java's productivity sucks....What's most alarming to me is this: Java's not solving the problems of the majority of its user base. If not
Rails, something else will step into that gap."
"The pain of dealing with Java, and the time/effort it takes to develop using it just isn't worth it to me.
Yes, at one point Java was definitely a god-send. It rescued me from the Microsoft hell I was dealing
with at the time .... But many years have passed since then, and sadly Java hasn't progressed, and instead has become
more and more obtuse and bloated with each passing year. At one point I thought I hated programming because
I was just so sick of it... It turns out I don't hate programming, I just hate programming in Java.
...There's something about the Java culture which just seems to encourage obtuse solutions over simplicity."
"The Java tool stack and runtime stack - this is incredibly complicated. There are at least 50 acronyms.
Even with the best tooling, if you have such a complicated technology or stack of technology, it will
always remain very difficult to build apps."
"One thing that a lot of people don't get, is that you can do what makes Rails successful in any language: the
key is keeping it simple, don't over architect it, start small, slowly build on..."
- Zed Shaw
"If folks in the Java space spent as much time designing easy-to-comprehend-and-use frameworks as the Ruby
community does, Ruby on Rails wouldn't be making such big waves."
- Tim Fennell
"Now, I've said that you can't do Rails in Java. That doesn't mean that you couldn't do something equally as cool
in Java. The strengths of Java could be applied to a brand new framework in interesting and amazing ways. It's just
that nobody has done that yet. Everybody has been too interested in chasing the J2EE cookie to rethink the
problem in a drastic and dynamic way. But even if somebody does come up with a killer Java-based web framework
that does as much as Rails, it certainly won't look or feel like Rails."
Where's the pain?
This is the mother and progenitor of many other types of pain.
From complexity pain is born a multitude of evils.
The core problem is that complex tools are, by definition, hard to learn and hard to use.
Complexity pain is usually correlated with some measure of size.
For frameworks, one measure of size is simply the number of published classes in its javadoc:
|Tool||Num Classes||Relative Size|
These tools aren't concise, and they aren't minimalistic. These tools are obese.
(For comparison, WEB4J has 95 published classes.)
One can reasonably argue that, in the case of frameworks, complexity pain is roughly proportional to the number of published classes.
Other measures of complexity pain might include the following:
- average time to learn the basics of the tool
- average time to more or less master the tool
- average time to implement a feature with the tool
- size of a tool's documentation (this metric is more ambiguous, since documentation varies widely in completeness)
Building plain, boring Java Web apps that just pump data into and out of a database should be just that -- boring.
But they're often a long distance phone call away from boring, because they're so complex.
What would a simple, minimalistic Java Web app framework really look like?
If you cut everything out until what remains is only that which is absolutely necessary, what would you be left with?
What would an antidote to the Java complexity epidemic look like?
WEB4J was built as one answer to that question.
The fundamental thesis of WEB4J is that building Java web apps is unnecessarily complex.
If you don't accept this thesis, then WEB4J is not for you.
Many tools make extensive use of XML files.
But coding in XML is widely recognized as a particularly fruitful source of pain:
- XML files aren't part of compiled code.
- typos are always easy to make in XML files.
- errors are often found only at runtime.
- XML syntax is widely regarded as verbose and clunky.
- modern IDEs are wonderfully rich tools for editing Java, but IDEs usually aren't of much help with XML files.
These drawbacks wouldn't be so bad if you needed to spend only a small amount of time editing XML files.
Unfortunately, many frameworks place such XML files at the very core of their design.
Because programmers need to spend so much time coding in XML, this causes significant and non-trivial pain.
Relearning pain is best explained with an example.
Let's take the example of an HTML form control, implemented either with a standard HTML form control, or with a Struts1 tag:
HTML: <input type='text' property='comment'>
Struts: <html:text property='comment'>
In Struts1, you typically don't implement form controls using standard HTML.
Instead, the framework forces you to replace standard form controls with a set of custom tags, one for each type of control.
The point here is that some tools force you to abandon things you already know how to do, and replace them with a parallel set of techniques specific to that tool.
That's not a good thing.
Clearly, it would be best if tools built upon what you already know, instead of forcing you to learn a different way of doing essentially the same thing.
Another shining example of relearning pain is Hibernate Query Language (HQL), which functions as a re-implemnetation of SQL SELECTs.
Flexibility pain is the pain of having to make too many choices.
- should you use annotations or XML files?
- which technique for binding data to form controls should you use?
- Hibernate Query Language, or back out to straight SQL?
- should you implement security with the Servlet API, or Spring security?
- should you use Spring AOP or AspectJ?
It's true that extensive flexibility certainly appeals to many people.
Indeed, many tools explicitly declare themselves as flexible and powerful in their marketing blurbs.
There is indeed a place for such tools.
But there's a downside: flexibility necessarily implies a certain amount of added complexity.
It simply takes more time and experience to understand all the options, and to make the right choice.
You simply can't get around that.
If you are looking for a simpler approach, then all these decision points can often be a source of flexibility pain.
Contention pain refers to contention between developers who want simultaneous access to a single file.
Typically, these are XML files or properties files required by the framework.
When such files are monolithic, and reference many distinct features, then contention between developers for such files is inevitable.
This slows down development, and creates unnecessary friction.
Translation pain refers to various nuisances associated with multilingual applications.
The change from a single-language app to a multilingual app often introduces problems, such as:
- invasive tags in HTML. These tags fundamentally change the look and content of your JSPs. Custom translation tags are used for each snippet of text. The source loses the feel of plain hypertext.
- lack of support for adding new
Locales dynamically in production.
- the many nuisances associated with using properties files for translations: problems with apostrophe characters, the need for line continuation characters, format restrictions unsuitable for non-technical users, no simple way of performing SQL-like queries on the data, no way of easily finding duplicates, and so on.
Staffing pain simply refers to the difficulty of finding people who can proficiently support a given toolset.
The larger the set of tools used by a given app, the more difficult it becomes to train people.
If, in addition, some of those tools have a long learning curve, then the problem is aggravated.
Moving less experienced folk onto projects becomes increasingly difficult.
API pain refers to undesirable aspects of an API that you are unable to avoid. For example:
- requiring a class to be thread-safe. (This was a problem in Struts 1, where action classes
had to be thread-safe.)
It's very easy to forget, since it's not enforced by the compiler.
If you do forget, the result is a subtle bug that is hard to identify and reproduce.
- requiring casts in application code. Since JDK 1.5, casts have become pungent code smells.
- forcing you to catch exceptions to implement logic branches.
- forcing you to place validation logic outside your domain object. This contradicts the first
thing you learn in object-oriented programming -- the idea that a class exists to encapsulate both data and closely related operations.
- allowing automatic binding of request parameters to model objects, without defining an explicit "white list" of acceptable parameters. This is a big security problem in web apps.
- excessive use of magic
String identifiers. If the name is not exactly right, you get a big juicy runtime error.
Most tools should be pain-killers -- that is, they should address some sort of pain.
At best, they should remove the pain entirely; if that's not possible, they should minimize the pain.
Above is a short compendium of the kinds of pain some people experience when building Java Web applications.
WEB4J has been designed to eliminate or minimize these sources of pain.