Choosing the Right Java Web Development Framework
Ed. Note: This article was originally published in March of 2009. It has been reprinted here because it provides excellent guidelines for evaluating and selecting the right Java web development framework. However, readers should be aware that some details about specific frameworks have changed in the year and a half since it was first published.
Open source application development frameworks have increased in both popularity and number over the past decade. Today, developers can choose from a wide range of frameworks, each of which offers a unique combination of features, limitations, and benefits.
But choosing the right framework can be a challenge.
Web application development frameworks have become very popular in the last several years. Wikipedia lists over 85 web application frameworks, with a large table comparing features.
This article covers some of the factors you should consider when evaluating and selecting a framework for building a Java web application. However, this is never a simple process and many different criteria can and should be considered. In other words, you will want to perform your own additional research.
When it comes to adopting a new technology, many of the decision points are organizationally — not developer — driven. When an organization intends to adopt an application development framework, it is typically looking to accomplish three things:
- Address the complexities of some lower level application architecture
- Reduce the amount of code developers have to write (aka "productivity")
- Allow developers to focus on "business logic"
As you begin the evaluation and selection process, beware of people giving easy, emphatic answers. Your development environment and goals are unique. Use this article as a starting point and a general guide, and you should be able to make a decision that helps you increase productivity and decrease pain.
First, we need to define the term application development framework and provide a little history. Application development frameworks are not new. They originally started with user interface (UI) development and have expanded into other areas. Just defining the term can be a little squishy. However, application development frameworks typically provide:
- A standard structure or design that allows the developer to create an application, without having to learn or understand complex low-level APIs.
- Some sort of programming paradigm or model. For example, for Java, Java EE is a great example of a framework that defines a paradigm.
Next, we need to define the types of application development frameworks currently available. There are, in general, three primary types of frameworks:
- "Application Frameworks," which typically focus on the low-level details, abstracting the developer from an operating system or from a programming platform (e.g. Microsoft Foundation Classes).
- "Enterprise Architecture Frameworks," which are at the other end of the spectrum, are used to govern or dictate the design of an enterprise system. An Enterprise Architecture Framework encompasses multiple different servers and software applications, allows for scalability, and supports "ility" constraints (e.g. Java EE, TOGAF).
- "Web Application Frameworks," which fit "right in the middle." Web application frameworks typically govern the overall architectural design, similar to Enterprise Architecture frameworks, but also are typically an extension of an application framework, albeit focused on a specific type of application development (web applications).
Zeroing in on web application frameworks, there are two broad classifications to be aware of:
- Server-side frameworks - focused on enabling back-end developers to create robust, scalable web applications (e.g., with Java, JSP with servlets; PHP is best known for server-side, and for .NET, ASP .NET).
- Client-side frameworks - focused on addressing the complexities and incompatibilities across browsers and user interactions.
Java Web Development Frameworks
So what's the current landscape? Basically, there are two large conceptual categories that you need to be familiar with: "Full-stack" frameworks and Model View Controller (MVC) frameworks.
Full-stack frameworks address back-end web development for a web app from start to finish. They have some infrastructure or component that addresses the common MVC paradigm plus components that address interacting with databases, possibly in a create-update-and-delete (CRUD) fashion. They interact with message buses, and with naming and directory servers like LDAP.
- ADVANTAGES: Full-stack frameworks have a complete stack, so, as a developer, you don't have to worry about how to integrate with a database, or how to integrate with a messaging system. It's one stack of libraries that all work together. One nice "side-effect" of that is that as a developer, you don't have to write the glue code to connect the "web tier" to the "enterprise tier."
- DISADVANTAGES: Certain frameworks suggest or encourage certain technologies, which means you lose some plugability. For some developers, this is a real disadvantage.
MVC frameworks are typically the most popular frameworks in the Java web development world and are structured around the framework of a re-usable web application. Re-usability is discussed with the model, the business domain objects, or the controller that handles to request processing.
- ADVANTAGES: MVC frameworks are typically referred to as lightweight frameworks, meaning there's less "baggage" and fewer connections with enterprise systems that you may or may not take advantage of.
- DISADVANTAGE: You do generally have to write the glue code to do CRUD operations.
In summary, both obviously have advantages and disadvantages, and there are too many to list them all. But at a high level, MVC frameworks are typically the most popular frameworks, so we’ll focus on those in our selection process below. However, should you decide to evaluate or select a full-stack framework, you’ll want to consider popular options like JBoss Seam and Spring (though it is debatable if Spring should be classified as a full-stack framework).
Understanding the MVC Paradigm
MVC is a design paradigm or design pattern that grew out of user interface development. Some people attribute it to Small Talk UI. At any rate, the real focus is to try to figure out how to structure a user interface application around good object oriented programming (OOPs) concepts like encapsulation, cohesion, loose couplings, and abstractions. All of these object oriented programming concepts can create re-usability.
If we were to dissect a user interface in the MVC world, in general we’d find three components:
1. The view is responsible for rendering the UI and is directly tied to a model for the state data of the UI. More specifically, as the view renders itself, it calls out to the model and gets back information from the model, so that it could draw a check-box either as a selected check-box or an unselected check-box, depending on the model structure.
2. The model contains the state data for the UI and supplies information to the view as requested.
3. Depending on the MVC paradigm, the controller functions as a traffic cop to allow the interactions that are triggered through the UI to propagate through the model. So, if somebody selects a check-box, that selection is going to go through a controller, and that controller is going to (hopefully) update the model. Then, the model notifies the view and the view redraws itself.
Of course, there are many ways an MVC architecture can be structured. In the interests of simplicity, we will not cover that information here. However, there are two main kinds of competing architectures or ideas on how an MVC framework should be implemented, and they are very important in making your decision. The two types of MVC frameworks that you will encounter are:
- Action-based (aka Push-based MVC) frameworks are the most common partially because they've been around longer (e.g. Struts). The idea is that when a request comes from a web browser and goes to a web server, there is a request handler that functions as a controller. That request handler takes the request data, puts it into some type of model, and that model then pushes that to the view — typically a JSP. Then, the JSP takes the model data and renders itself. Typically, it's easy to understand and a very straight-forward process.
- Component-based (aka Pull-based MVC) frameworks focus on rich UI development. They've moved away from the concept of request-processing a little bit, into view generation or view rendering. Included is a nice UI component set that creates re-usability within the application. Three of most common ones are JSF, Wicket, and Tapestry. With Component-based MVC frameworks, it is the view's responsibility to pull in data from potentially multiple controllers and render itself. Instead of having the controller give all the appropriate data, the view can pull in all the data from the appropriate controllers. There is still a model, and the model is still generally represented as a Java object. The model still could be a composition of objects; the difference is how the view accesses the information.
Comparison of Six Popular MVC Frameworks
We’ve selected six of the most popular MVC frameworks to compare – three action-based and three component-based. You may wish to evaluate different options, but the evaluation process outlined below will help you determine the best framework for your needs regardless of the options you consider.
The action-based frameworks we’ll compare are:
- Struts 2 is sometimes called "the evolution of the Struts framework." The Struts framework was originally popularized back in the late 1990s and early 2000s, and Struts 1 is still regularly used in enterprises. Struts 2 was released in February 2007 and is a redeveloped implementation of Struts 1, based on a framework called WebWork.
- Spring MVC 2.5 is the MVC component of the MVC Framework, built on top of the Spring Framework. It adds MVC capabilities, which means that you can leverage Spring features like inversion and control and dependence injection. It has organizational support from SpringSource which means good training and documentation, and a large supporting community.
The component-based frameworks we’ll compare are:
- Stripes 1.5 has a big grass roots following but no organizational backing.
- Java Server Faces (JSF) / MyFaces 1.2, probably the most popular implementation of the JSF specification, is the only framework supported by a Java community process specification. This gives multiple vendors the opportunity to implement JSF and, in turn, gives adopters many different vendor choices. However, many people believe that Sun dictates how the technology is implemented, so they feel there is a big marketing machine trying to push a standard.
- Wicket, sponsored by the Apache Foundation, is a web application development framework for Java developers, which means it's focused on writing web applications in Java versus writing web applications in something like HTML. It is very Java focused.
- Tapestry 5, also a part of the Apache Foundation, it is a complete rewrite of Tapestry 4 that attempts to simplify some of the cumbersome features found in Tapestry 4.
Criteria for Choosing a Framework
There are many different opinions on how to choose the right framework. Approaches used to select frameworks include:
- The Popularity Formula - How many Google searches? How many jobs on Dice?
- The Community Activity Formula - When was the last commit or release? How active is the mailing list?
- The Learning Formula - How many books? How's the documentation?
- The Architect Formula - How clean are the results? How well does it scale?
- The Pragmatist Formula - How hard is it to build a prototype?
Since none of these approaches provides a complete picture, we decided to use them all to evaluate the six frameworks outlined above.
Popularity. If you choose a framework strictly based on popularity, you'll pick JSF. But, consider that Sun, IBM, and Oracle have invested time and marketing dollars to make JSF popular, so popularity here is skewed by marketing budgets.
Community. If you choose by active community you might base your decision on frequent releases, or the most current release, or the most active mailing list. If your decision was based on the most current release, it would be Stripes. Obviously, in some cases, you might find a recent release simply because of coincidence.
Learning. In general, the availability of documentation is common, so perhaps you might narrow down this category to the number of books written on the subject. If that is your differentiator, then again you'll choose JSF (based on Amazon numbers). But then again, it's possible that JSF has more books because it's harder to understand. Choosing, then, by larger numbers of books might not be a great thing to do.
Architecture. Looking for Plain Old Java Objects (POJO) is one way to examine the various frameworks. (POJO, used to be "JavaBeans" but the Java community does not like the term because of the enterprise JavaBeans world.) There is constant debate on how much imposition a framework should have on one's architecture. The trend in the last 3-5 years is to separate the application from the framework by using some POJO structure. Some are POJO-based, some "hedge their bets" and let you use POJO with annotations or create a subclass of one of the pre-built classes already included. It's all over the board, so it would be pretty hard to decide based on the cleanest architecture.
Pragmatist. One of the major reasons for choosing an application development framework is to reduce the amount of code you have to write, or to increase the productivity of the development team. In that case, you should first and foremost be using "The Pragmatist Formula" as well as the other criteria. Unfortunately, measuring productivity of a development team is a crap-shoot. If someone could figure that out conclusively, they would be very wealthy! Different developers code at different speeds, some developers learn really quickly, others take longer but really master it completely once they get it. Ultimately, it's very hard to measure accurately.
The Productivity Formula
The real motivation for using an application framework is simplified development. While not always the case, simplified development usually translates into increased developer productivity. Therefore, we suggest choosing your framework with productivity in mind instead of using the five criteria mentioned above. Here are some key elements that could be used when making a productivity-focused decision.
When it comes to rapid application development (RAD) consider measuring productivity in terms of support for:
- Convention over configuration
- Inversion of Control, also known as Dependency Injection
And, yes, it would certainly be possible to add other items here to measure, but the point is to narrow down the list to have a succinct discussion.
When it comes to rich internet application development (RIA), consider measuring productivity in terms of support for:
Understanding Variables of RAD: Three Trends within the RAD World
Convention over Configuration. The idea here is that as a Java developer — historically, at least — you spend 50%-60% of your development effort on configuration. Too much time is (or at least used to be) devoted to dealing with XML files, property files... lots of different pieces. It's been said that "configuration is the demise of Java." The hope has been to move some of that configuration burden off of the developer and let the platform be smart enough to adopt some convention. As long as the developer adopts best-practices or coding conventions the framework can figure out what's being done.
Scaffolding. This generates a boilerplate code, the views, the controllers, the CRUD operations — in other words, a first rough pass at taking the developer's database design and mapping to the web application. Scaffolding has become popular due to the RAILS movement.
Inversion of Control. In the Java world, specifically in the Java EE world, there is the mechanism called the Java Naming and Directory Interfaces (JNDI) used to look up internal or external services. These could be an enterprise JavaBean, a database, or a message queue. Instead of the developer doing all those extra steps to look up internal or external services, the framework does the work and hands to the component or object a reference to that external service. In other words, the service look-up responsibility is delegated to the framework.
Understanding Variables of RIA
We categorized Struts 2 as a Configuration framework because if you look at the number of XML artifacts that you have to create to configure the framework (approximately 2-7 files) it's very configuration-heavy. Read through the Struts 2 documentation to make your own decision whether it's a Convention or Configuration framework. Stripes, however, is on the opposite end of the spectrum. It professes that it's a very Convention over Configuration framework. It leverages not only coding conventions but also class reflection to help it understand what the different components are of the application. There is only one configuration file: web.xml. In the middle is Spring MVC, which started off as a Configuration framework but with every release it has moved more and more towards Convention. It currently has probably just two configuration, and in Spring 3 it is supposed to be even less.
One of the trickiest things with a web application is the question, "How do I deal with navigation paths?" In other words, when a request comes in and I process the request, where does the request go? What's the target? For navigation, basically you're going to end up with either XML or Java.
None of the RAD-based frameworks support scaffolding or basic CRUD operations, which means the developer has to go get a third party adapter or plug-in to create that functionality. There is one third party plug-in for Spring MVC that will do both.
In the Java world, Inversion of Control is a big trend in RAD. All three of the frameworks support it. And they also support annotations — the metadata to make development easier.
Not a single framework today supports RESTful URLs. For Struts, a plug-in is being developed. In Stripes, there are several different "ActionResolvers" that help you, and in Spring there is an annotation that helps.
And none of the frameworks out-of-the-box will generate AJAX for the developer. The developer has to make the AJAX, the asynchronous calls, the XHR objects, and the interactions
So, none of the three really hold up to what we're interested in from a productivity standpoint.
Using the same comparison criteria, only JSF is configuration heavy, and of the two Configuration frameworks, Wicket and Tapestry, Tapestry has only one configuration file. Navigation flow — where does a request end up, and how easy or hard is it to configure? — was looked at, and only JSF adopts an XML-based structure. Therefore, for both Wicket and Tapestry, the controller is going to govern where the target is located and what the target looks like.
For scaffolding, only one supports out-of-the-box scaffolding: Tapestry. When compared to Ruby on Rails or Grails, Tapestry 5 scaffolding allows you to take a Java object and annotate the object. It can be mapped to a view with a single tag — a tag and a tag library. The developer doesn't have to generate the input text fields or the input submit fields or the drop-downs for the different states. The point is that is does NOT do the full scaffolding that you would find in Ruby on Rails.
If the developer spends a lot of money and is using IBM's WebSphere or Oracle's JDeveloper, there are some scaffolding capabilities in both of those tools to help minimize the amount of UI code that has to be created.
There's no out-of-the-box support for CRUD.
Two of the three support Inversion of Control: JSF and Tapestry 5. Wicket does not directly, but you can layer Wicket on top of Spring to get some Inversion of Control. Both JSF and Tapestry 5 support annotations while Wicket, out-of-the-box, does not.
And the "Winner" is...?
Choosing a winner is obviously subjective. It's certainly possible to use all of the various formulas discussed above: popularity, community, learning, and architecture, plus pragmatically looking at RAD and RIA. The chart below, then, is based purely on numeric ranking. The lower number is best.
For Popularity, JSF is ranked first.
Note: For RAD and RIA, the ranking is 1st, 2nd, and 3rd for Action-Based, and then again for Component-based, so they're ranked twice. Therefore, Stripes is ranked as more productive under Action-based RAD, though it's only more productive because it supports more of the evaluation criteria, and Spring MVC is better from a RIA perspective because it supports more of the capabilities that were identified. On the Component-based side, Tapestry supports more of the RAD capabilities for both RAD and RIA.
So, in conclusion, obviously the list of frameworks we evaluated is not comprehensive. You may want to add to the list or take things away. It depends very much on the type of web application that you intend to build and what features and functionality you are looking for. And, to be clear, in the table above, Tapestry comes out as the winner, but in no way does this suggest some sort of absolute winner. Nor is JSF the biggest loser.
There are other criteria that you may very well want to consider. Licensing is one. In this case, every single framework supports the Apache 2 license, which is very good for the developer community.
They all support Java 1.5 except for Spring MVC, which utilizes Java 1.4. This may not be an issue if your organization only has 1.4.
Most of the frameworks support Spring, so typically you can layer your framework on top of Spring. There's some debate and discussion on whether you can get Spring and Wicket to work nicely together, hence the question mark here.
JSF support is uneven, but all of the frameworks support a validation mechanism. You could also evaluate whether the framework supports JPA, or EJB, or has a templating engine.
A Note about Scaffolding
If you truly want to get that scaffolding functionality with generation of the UIs or the views, and generation of the controllers, models, and CRUD operations, the first thing you probably have to do is move away from an MVC and into a full-stack implementation. Seam, for example, has a full-stack implementation. The challenge with SEAM is that it is really focused on Java EE development, and if you don't like Java EE that's not so great for you. More commonly, if you want the full scaffolding support, you'll use a dynamic language in a dynamic language framework like Ruby on Rails or Grails. The point is that if you want the full-stack capability interacting with a database you have to move beyond a framework that is just structured around re-usability of the model view and controller.
So... that's how things stack up!
This work is licensed under a Creative Commons Attribution 3.0 Unported License
This work is licensed under a Creative Commons Attribution 3.0 Unported License