Sunday, November 23, 2008

Do Java Web Application Frameworks *Really* Provide Too Much?

The other day we witnessed a DZone disaster. The article (Web Frameworks - We Need Less, But They Keep Adding More (Part 1)) was a five-paragraph claim that typical/most Java web frameworks were full of bloat and too complex, and that this is bad. I don't think anybody would argue that. The disaster's underpinnings? He was voted down, and called the downvoter a jerk.

I also voted the article down--I didn't like the article. IMO that's what the voting system is for. I was also called a jerk, and great hilarity ensued. Yes, I should have stopped feeding the troll, and I take full responsibility for my end of the discussion. I still, however, don't like the article, and believe his reaction was about as ridiculous as I've ever seen.

Are Java web frameworks actually "adding more"? Does "doing a simple task requires pages of code and configuration..." and do current frameworks want "... control of both sides of the web application coding (server and browser)"? Do "... many/most web frameworks is the fact that they try to do too much and require large amounts of configuration (usually with XML)"?

The popularity of Ruby on Rails prodded most Java-based web frameworks to move, often rapidly, *away* from static configuration. Some have moved towards annotations (still configuration), some towards convention-over-configuration, many allow multiple configuration (and configuration-less) styles. Even the annotation-based solutions are, at this point, pretty minimal in terms of cognitive overhead (which is the ultimate issue), although annotations are still configuration. Most frameworks, even *with* XML configuration, allow convention-style configuration via wildcards and the like, often allowing large web applications to be configured, even in XML, with only a few lines.

Do frameworks "force me to use your embedded code and/or tags in my HTML"? I know of very few that *force* us to use framework tags, although it's often unreasonable not to. The article is basically a commercial for jWebApp, and several jWebApp examples use jWebApp-specific tags. The explanation given in the DZone meltdown is "The tags are framework independent and optional, but are obviously needed to repopulate the form if validation fails." I'll largely discount the entire tag issue, then, if they're obviously needed for functionality normally associated with a web application. I'll admit a certain amount of confusion as to why it was brought up, however.

The second article begins the actual technical discussion, using the "perfect web framework" (which turns out to be jWebApp). It includes code and configuration (which we didn't want, if I recall) samples as well as a laundry list of features.

The example request handler skeleton given is this (slightly reformatted and redacted):

public class Customer extends RequestHandler {
public String validateSaveCustomer(ServerInterface serverInterface) { ... }
public String processSaveCustomer(ServerInterface serverInterface) { ... }
public String processGetCustomer(ServerInterface serverInterface) { ... }
}

ServerInterface is a wrapper around an HttpServletRequest, HttpServletResponse, and ServletContext, directly tying request handlers to the servlet framework. The wrapper class also defines a slew of convenience methods that access things like request objects and so on.

Directly tying to the servlet spec creates an awkward dependency that unnecessarily complicates testing. These days it's relatively unusual to find a framework with such an explicit dependency on the servlet specification. If time has taught us anything it's that dependencies like this are (largely) unnecessary and impede development.

The Hello World example on the jWebApp site shows an example with a similar skeleton:

public class HelloWorld extends RequestHandler {
public String processHello(ServerInterface serverInterface) { ... }
public String processHelloAgain(ServerInterface serverInterface) { ... }
}

This example is intended to service the /helloWorld/hello and /helloWorld/helloAgain URLs. The "configuration-less" configuration, however, looks like this:


jwaRequestServlet
jwebapp.RequestServlet



jwaRequestServlet
/helloWorld/hello



jwaRequestServlet
/helloWorld/helloAgain


The first mapping is reasonable, the jwaRequestServlet is acting as a controller. What's less clear to me is why the next two servlet mappings are necessary: they seem redundant and unnecessary. Again, in modern Java frameworks this would be handled automatically via convention, wildcarding (XML or annotation configuration), or classpath-scanning convention (configuration-free or annotations).

Note that as with most other modern Java frameworks it's possible to use convention-based URLs in jWebApp, but we're then back to comparing apples to apples.

The article then goes on to say that he would like to "optionally define simple configuration":









This brings us back into the realm of a typical XML-configured framework, which seems to go against the grain of part one, which makes me wonder what the point was in the first place. At the end of part two is a laundry list of features desired in "the perfect framework", but none of them seem to be features that are particularly lacking in other modern frameworks.

Some features present in jWebApp *are* nice to have, and it's cool they're integrated into jWebApp--but those features aren't necessarily features that *should* be integrated into a web application framework. If they meet the needs of the developer and/or project then that's a Good Thing, and a definite win. Some of the features, however, like emailing, payment processing (I only found support for PayPal, but I suspect there's more), and so on may be so project- or environment-specific that having them included in the framework itself is at best useless, at worst an unnecessary distraction. It may not be *fundamentally* bad they're included, but directly integrating cross-cutting concerns like that always raises my eyebrow.

Moving away from the articles and towards the framework itself there are several claims made regarding the features of jWebApp. The lack of need for custom tags is mentioned (no *need*, but again--they're used by the framework to provide the same functionality provided by most other frameworks' tags). Easy AJAX support is touted, but appears to be handled by creating a JSP page that returns JSON-formatted data which is then evaled in JavaScript, rather than the automatic JSON de/serialization offered by other frameworks (often including automatic help in avoiding scripting attacks).

Something not mentioned in the jWebApp documentation is Spring integration, which for the types of applications I write is a very important requirement: yes, Spring *can* be complicated and it's definitely overkill for many types of applications--but those aren't the applications I write. If all we need is dependency injection (something I didn't find support for in jWebApp--again, that doesn't mean it isn't there) then Spring is a pretty heavy solution--there are much lighter-weight DI containers. Once we throw in transaction management, AOP, and so on, I find out-of-the-box Spring support compelling, although there are other good solutions.

Simply put, I don't find anything compelling about jWebApp. That doesn't mean it's not an adequate for some problem domains or developers--it simply doesn't meet my needs. For quick, one-off, Java-based e-commerce apps it may be exactly what somebody is looking for, since it has typical functionality built-in.

The bottom line is that I still don't find the article I voted down interesting, particularly well-written (although it's not *badly* written), or of any great value. It was five paragraphs that didn't say very much. I feel badly that the author reacted so poorly--quit frankly if I'd known he'd fly off the handle like that I probably wouldn't have bothered voting it down, but part of the point of voting is to provide feedback to the community at large, and at the time I read it I didn't think it provided enough value to recommend it to others, and it seems to ignore the Java web app frameworks that alleviate the bulk of what's being complained about.

On the social aspects of the original DZone submissions, I'm somewhat at a loss. The author decries the childishness of "arbitrary" downvoting, then downvotes *multiple* submissions by his downvoters in retaliation... We may just be operating under different definitions of "childish", but IMO that's even *more* childish. It appears that the tantrums brought nothing more than *more* "arbitrary" downvoting. Is this a Good Thing? No, he's right that downvoting just because he played the fool isn't appropriate behavior: the only thing that should enter in to submission voting is the article itself. His playing tit-for-tat, however, completely demolishes any credibility he has to complain about arbitrary downvoting. I was called a jerk because I didn't like the article--this is also inappropriate behavior; not liking the article *is* an appropriate reason to vote it down.

Lesson(s) learned? For my part, I'm less likely to downvote an article I think has no redeeming value, depriving other readers of a reasoned opinion. On his part? I don't know--I'd like to think he'll come out the wiser, and I hope he does. I'm glad he's developed a framework that meets his needs, and if it meets the needs of others, I think that's terrific; more power to everybody involved. Despite his sarcastic parting comment: "Thank you all! You've shown me what the open-source community and netizenship is all about." (it was originally followed by a "Fuck off", but that part was deleted, which is good) I actually *do* believe this is what the open-source community and netizenship is all about: open discussion that sometimes happens to go horribly, horribly wrong.

Friday, February 01, 2008

Today's Java Irritant: No sense of closure.

There's still enough back-and-forth about the inclusion of closures in Java 7 that I'm nervous it might not make it in to the language.

James Gosling supports the addition of closures and states that the reason they weren't there in the first place was due to time pressures and seems to have some regret about their absence (understandable; he's a Pretty Smart Dude and probably feels the pain of Java wartage more keenly than most).

Ricky Clarkson blogs about why we need a new syntactic construct to make the use of closures cleaner and less verbose, even while admitting that Java does, in fact, have a form of support for closures already.

My languages of choice (Lisp, Smalltalk, Ruby, etc.) all have cleaner support for closures without the syntactic overhead that current Java has. For a trivial example we can compare the use of closures for processing a file.

file.each_line do |line|
# Process line of file.
end

With current Java syntax we might end up with something like this:

import static bar.baz.eachLine;
...
eachLine(file, new EachLine() {
void doLine(String line) {
// Process line of file.
}
});

We could also create a File-like object with an eachLine method.

This isn't the Worst Syntax in the World, but it still makes me think more when writing the code and when I'm reading it later.

A relatively minor point is that any variable used in the closure must be declared as final in the enclosing method. This may obfuscate the actual functionality of the enclosing method and, in some cases, require the introduction of a final variable just to satisfy the requirements of Java's current "closure" syntax/implementation.

It'll be interesting to see what finally happens; I hope that (a) support for closures is added and (b) it doesn't irritate me too much.