Java, Pain, and Low Productivity
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 :
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 more or less like SQL.
Flexibility pain is the pain of having to make too many choices. Some examples :
- 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. And there is indeed a place for such tools. But there is a downside to it: 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 HTML.
- 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 is a problem in Struts 1, where action classes must 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
Stringidentifiers. If the name is not exactly right, you get a big juicy runtime error.