Overview : WEB4J Java Web Application Framework

The primary design goal of WEB4J is to always exercise deep compassion for you, the application programmer, to make your tasks as simple, natural, and as effective as possible. The framework should take on as much pain as possible, so that, in the end, you experience as little pain as possible.

The whole point of WEB4J is to give those who use it a deep feeling of simplicity, clarity, and elegance. That feeling is the ultimate goal of WEB4J, and nothing else. This is an esthetic goal, not a technical one.

The important things about WEB4J are :

In the interest of not wasting your time, please see below for a listing of its drawbacks.

If you can accept the above, then WEB4J is often the best tool for the job of creating browser interfaces to databases. Because of its deep simplicity, it allows markedly faster delivery of applications.

Simplicity is the state in which all extraneous structure is removed, except exactly that structure which is required.
- Christopher Alexander

WEB4J is Small

One measure of complexity is size. Here is a listing of the number of documented classes in various tools :

NameNum ClassesRelative Size
WEB4J 82Graph
Servlet/JSP API 96Graph
Rails 170Graph
Struts 720Graph
Rife 1,110Graph
Tapestry 1,140Graph
JEE 1,188Graph
Spring 2,464Graph

As you can see, most tools have a size that might be described as "rather large". Note that WEB4J has the smallest surface area of any tool in its class. It is even less than half the size of Ruby on Rails, which has gained attention lately for its ease of use. Correspondingly, it takes a shorter time to learn WEB4J, and to implement features with it.

Not only is WEB4J compact, but, more importantly, applications built with WEB4J are compact as well. Here are some typical line counts per feature, taken from a cross section of several features in the Fish & Chips Club example application. (Documentation comments are included in the line counts.)

ItemAvg LinesRelative Size
SQL file (.sql)25Graph
Presentation (.jsp)108Graph
Total133 
Model (.java)111Graph
Action (.java)144Graph
DAO (.java)46Graph
Total301 

In general, your code will only be roughly twice the size of the non-code elements of your application.

(DAOs are often short and simple, consisting only of a few single-line methods. In such cases, it is recommended that those methods be moved into the Action class.)

WEB4J Requires A Minimal Toolset

You use the following tools when building a WEB4J application :
  • views use HTML/CSS, JSP 2.0+/JSTL 1.1+, plus some custom WEB4J tags. The custom tags are minimal, and do not interfere with regular HTML. In particular, forms use plain HTML. (Note that WEB4J does not require javascript.)
  • data access objects (DAOs) reference standard SQL statements placed in .sql text files. There is no database mapping of any kind.
  • in general, your code uses web4j.jar, and the following commonly used tools : JDK 1.5+ and Servlets 2.4+. (EJBs are not used.)
In short, you use existing, well known tools appropriate for each layer. In addition, there are no other dependencies on third-party tools, other than widely used tools published by Sun Microsystems.

WEB4J Uses Convention Over Configuration

Convention over configuration is used to reduce the effort needed to create and maintain your application. It is used in the following ways :
  • a default naming convention maps request URIs to corresponding Actions. See RequestParserImpl.
  • in JSPs, a naming convention for the names of input controls allows for automatic mapping between controls and corresponding getXXX methods of a Model Object. This convention allows painless population of forms with data. See RequestParameter.
  • an ordering convention for the columns of a ResultSet is used to map columns to corresponding parameters in a Model Object constructor. See the overview of the database package.
  • an ordering convention is used for SQL statements with '?' parameters : when your DAO passes values for such parameters to the framework, the order of the passed parameters matches the order of the '?' items appearing in the underlying SQL statement. See Db.
  • where possible, default implementations of required interfaces can be used with no effort on the part of the application programmer. If there is no default implementation, or if the default implementation is overridden, then a naming convention for the package/class can be used. See BuildImpl.
  • the set of acceptable RequestParameters for each Action are found automatically by the framework upon startup, with no configuration required. See ApplicationFirewallImpl.

WEB4J Application Classes Are Usually Simple

The quality of a framework can be measured by examining the concrete classes which use it. Questions to ask of a such a class include :

  • is it fairly simple and compact?
  • does it read at a high level of abstraction?
  • does it read clearly?
WEB4J performs well in this regard. Here are some examples of typical implementations :

Model Objects :

Data Access Objects (DAOs) :

Actions :

WEB4J Enables Package-By-Feature

The package-by-feature technique is a powerful method for organizing your code. It has many advantages, and is superior to the package-by-layer style so often promoted by other tools.

All items related to a single feature can be isolated in their own directory/package - Action, Model Object, DAO, plain text SQL statements, and even the JSP. This gathering together of all items related to a single feature (and only that feature) is extremely satisfying. It allows the following goodness:

  • say goodbye to tedious navigation from directory to directory to change closely related items - everything is in one place
  • it allows deletion of unwanted features simply by deleting a single directory
  • it allows some items to reduce scope from public to package-private. (Minimizing scope is a central idea of lasting value in programming, and should always be aggressively pursued.)
  • in many source-code control environments, it allows developers to see immediately if another developer has checked out an item related to their current work

WEB4J Forms Use Plain HTML

Forms are an important part of web applications. Most frameworks implement forms with a large set of custom tags, that are different for each framework. These are meant to replace the existing, well known HTML controls such as <INPUT>, <SELECT>, and so on. That style is not the best, since it forces you to learn a new set of tools to do something you already know how to do - build an HTML form. This is neither necessary nor desirable.

In WEBJ, the typical form looks like this :

<w:populate using="member">
<form action='MemberEdit.do' method="post">
<input name="Id" type="hidden">
<table align="center">
<tr>
 <td><label>Name</label> *</td>
 <td><input name="Name" type="text"></td>
</tr>
<tr>
 <td><label>Is Active?</label></td>
 <td><input name="Is Active" type="checkbox" value="true"></td>
</tr>
</w:populate>
<tr>
 <td align="center" colspan=2>
  <input type="submit" value="Add/Edit">
 </td>
</tr>
</table>
The population of the form is done by wrapping a normal HTML form with a single <w:populate> tag - that's it. There are no custom tags for the various kinds of form controls. The WEB4J mechanism is the simplest possible way of populating forms.

WEB4J Has No Custom XML Files

The only XML file required by WEB4J is the deployment descriptor, web.xml. Whereas many other tools force you to spend significant time coding in XML, WEB4J was explicitly designed to let you avoid it.

In a WEB4J app, you implement features using JSPs, Java, and text files containing SQL statements. That's it. If you are looking for "XML hell", you won't find it here (but you can certainly find it in many other tools).

WEB4J Doesn't Use Object Relational Mapping

When building DAOs, you may use either WEB4J's data layer or any other tool. By design, WEB4J's data layer doesn't use object-relational mapping (ORM). For the majority of cases, implementing a DAO method with WEB4J's data layer will be more compact than an ORM implementation. The minority case in which an ORM tool may result in less coding effort and increased elegance is that of building an extensive object graph.

However, building an extensive object graph is the exception, not the rule. The majority of pages in a typical application relate not to relatively complex views of data, but to relatively simple ones. The reason for this is that it matches how people think, and how they work - on one specific thing at a time. Yes, large summary pages are very often part of an application, but such pages are usually the exception, not the rule.

There are some serious drawbacks to object-relational mapping :

  • it replaces standard SQL with alternate query mechanisms (reinventing the wheel).
  • it makes it difficult to debug and tune SQL, since the SQL is generated behind the scenes.
  • it often forces you to code in XML, which is inherently more difficult to work with.
  • its details are often non-trivial to learn and use.
  • it's often tedious and verbose.
  • it destroys the clear separation between application layer and data layer.
  • it violates encapsulation of database secrets, since the application layer repeats information that's usually hidden in the database: column types, nullity, key information, and so on. (SQL statements never explicitly include such information.)
In addition, ORM tools are invasive, in the sense of restricting the implementation of your Model Objects in certain ways, such as:
  • perhaps requiring you to add a no-argument constructor
  • perhaps requiring your class to be non-final
  • perhaps requiring you to add setXXX methods (roughly doubling the number of methods)
  • perhaps requiring you to add annotations
  • perhaps requiring you to implement Serializable (doing this correctly is non-trivial)
These restrictions don't exist for the benefit of your Model Object. Rather, they exist because the implementation of the ORM tool needs them in order to function. That is, they represent "leaks" of the ORM tool into your data model. These restrictions are particularly annoying since they don't allow you to design your own classes as immutable objects. This is a serious defect since immutable objects have so many compelling benefits.

In WEB4J, these restrictions don't exist. The only restriction for WEB4J Model Objects is that the constructor must throw a ModelCtorException, and that restriction has nothing to do with persistence. Rather, it's related to an important problem each Model Object should solve: the problem of validating state, and communicating related errors to the caller.

WEB4J Uses Plain .sql Text Files

The WEB4J data layer uses regular SQL statements, stored in ordinary .sql text files. Here is an example showing the basic idea. This style has many benefits.

WEB4J Has Minimal Configuration

WEB4J has no .xml configuration files, other than the familiar web.xml file (used for a number of initialization settings). In addition, it requires the application programmer to supply concrete implementations for a number of interfaces. Default implementations are supplied for about half of these items (no reasonable defaults are possible for the others). See BuildImpl for details.

WEB4J Does Not Impose Thread-Safety Constraints

Some tools force some application classes to be thread-safe. In Struts 1, for example, Action classes must be thread-safe. Forcing such a requirement on an application programmer is inappropriate :
  • implementing thread-safety is not trivial, especially for novice programmers
  • even if the programmer is experienced with the issue of thread-safety, it is still dangerously easy to simply forget to enforce it. Thus, there is the continual danger of introducing thread-related bugs.
WEB4J makes no requirements of thread-safety on the application programmer.

WEB4J Allows Multilingual Apps To Feel Like Single Language Apps

WEB4J translation tools allow the implementation of a multilingual application to look almost the same as that of an ordinary single language application. All Actions, Model Objects, and DAOs are exactly the same in both cases.

The only differences are in JSPs - and even there, the differences are relatively minor. The markup retains the overall look of a single language application. It remains legible, and appears natural to the eye. This is because the WEB4J translation tags are designed explicitly to be non-invasive. For example,

  • translation of large chunks of markup can be often be implemented by wrapping the 'single language' markup in a TextFlow tag
  • translation of all tool tips (TITLE attributes) can be done by placing a single Tooltips tag in a template JSP

WEB4J Allows Applications To Assist In Their Own Translation

The WEB4J translation mechanism can be backed by a database (recommended), or by any other means, including properties files. If a database is used to store translations, then applications can assist in their own translation.

The general idea is that, during development, all user interface items needing translation can be collected simply by exercising the application. This is done with a Translator implementation that records items having missing translations. Translations for such items can then be added later, through the browser, using screens created for that purpose, just like any other data. (Please see the WEB4J example application for further illustration of this useful technique.)

WEB4J Protects You From Common Hacks

WEB4J has tools to protect you from common hacks :
  • SQL Injection attacks are not possible when using the WEB4J data layer, since it always uses a PreparedStatement in the background.
  • SafeText models free-form user input, and automatically escapes special HTML characters (by default). This protects you against XSS attacks. It also allows you to forget about repeatedly escaping special characters in the view.
  • CsrfFilter protects you against CSRF attacks.
  • ApplicationFirewallImpl checks that all incoming parameters have known names, and that their values satisfy basic sanity checks.
  • SpamDetector helps you prevent spam from entering your database.

WEB4J Is Cheaper Than Open Source Tools

WEB4J is cheaper to use than open source tools because it is so much easier to learn and use.

There are three costs associated with any tool, not one :

  • the cost of acquiring it
  • the cost of learning it
  • the cost of using it

In almost all instances, the acquisition cost is only a small fraction of a project's total budget.

Example : Spring + Hibernate versus WEB4J

Here is a nominal example having books costing $40, and developer time costing $1,000/week. (These figures are taken as a simple representative example. Regardless of what numbers seem reasonable to you, the basic result is the same.)

CostSpring + HibernateWEB4J
Acquire $0$20
Learn $4,080
[2 books + 4 weeks]
$1,000
[1 week]
Use $500/feature
[2.5 days/feature]
$140/feature
[0.7 days/feature]
Total Cost Of 10 Features $9,080$2,420

The reduction in both 'learning' and 'using' costs are of course related : things that are easier to learn are easier to use.

All tools have a cost. Free open source tools are "free" only if you don't need to buy a book, and only if your time has no cost to you.

WEB4J Has An Example Application

WEB4J comes with an extensive example application. Its modules are typical for a business application :
  • a main business domain
  • access control - adding users, changing roles, resetting passwords
  • user preferences - changing language, changing passwords
  • webmaster tools - diagnostics, logging config, performance stats
  • translation - adding and editing translations of text appearing in the user interface

The WEB4J example application is provided as both a starting point and as a guide. It is recommended, though not required, that your applications be created by starting with the example, and changing it gradually. If any items are undesired, then they are simply removed by deleting directories (and any links from menus). This is only possible because of the package-by-feature style recommended by WEB4J. (See the User Guide for more information.)

This approach is consistent with the following :

  • destroying things is easiest of all
  • next, changing something that already exists is usually easier than starting with nothing
  • finally, starting with nothing usually takes the most time

In any case, the classes in the example application are always effective guides.

Other WEB4J Features

  • action classes are usually automatically mapped to URIs, without any manual configuration (see RequestParserImpl)
  • several abstract base classes are provided as templates for common action classes (see the subclasses of ActionImpl)
  • Report helps you build reports quickly
  • ModelUtil helps you implement equals, hashCode, and toString in your Model Objects
  • Check and Validator implement many common validations, and can be extended with validations particular to your application
  • ModelFromRequest and Db allow rapid creation of Model Objects from incoming requests and ResultSets, respectively.
  • messages to the user can survive a redirect, allowing the application to inform the user of successful edits to the database
  • settings in web.xml are used to establish application-wide default formats for dates and currencies
  • the Db class is the main tool for implementing DAO methods
  • applications can easily use multiple databases, when required
  • upon startup, WEB4J can optionally perform a test precompilation of all SQL statements. This is highly beneficial since it detects errors at startup-time instead of at run-time. (Not supported by all database drivers.)
  • if the database is down when the container starts, your app will attempt to recover with each incoming request. As soon as the database is up, your web app will start functioning normally.
  • the webmaster is emailed if an error occurs, or if your application's response time exceeds a configured number of seconds. In the case of an error, the email includes extensive diagnostic information, including a stack trace
  • upon startup, WEB4J will scan your Model Objects for possible Cross-Site Scripting vulnerabilities
  • and other features as well...

WEB4J Has Drawbacks

All tools have drawbacks and trade-offs.

How many times have you become disillusioned with a tool, but only after you have invested a lot of time and effort in it? The purpose of this section is to make sure that doesn't happen to you with WEB4J, by listing items you should know about.

Tools which don't clearly state their own drawbacks don't have your best interests in mind.

WEB4J's philosophy is one of deep minimalism. Thus, WEB4J may not include things which you might feel should be there:

  • it has no library of fancy user interface widgets. It's likely not appropriate to use WEB4J for building Rich Internet Apps - although you may still like its data layer.
  • it has no items related to Ajax, Web Services, or Messaging.
  • it doesn't generate JavaScript.
  • it doesn't have a CAPTCHA mechanism.
  • it has no components, events, listeners, and so on (as in desktop programming).
  • it uses JSP/JSTL, and alternative tools such as Velocity aren't supported.
  • its form population mechanism doesn't include a way of changing the appearance of controls containing erroneous user input, nor for associating specific error messages with specific controls.
  • for spreadsheet-style forms, no parsing of request parameter names to extract numeric row identifiers is performed.
  • its data layer builds simple Model Objects in a single step. It can also build the simplest kinds of Parent-Child relations. But if you need to build a complex Model Object, containing many collections, then you will usually need to build such objects in several steps.
  • when displaying an existing Model Object (built from an SQL statement) in a form, the data is formatted by the <w:populate> tag using application-wide format settings defined in web.xml, with no override. Some may find this pleasing, while others may find it an onerous constraint.

You May Need Third Party Tools

WEB4J doesn't depend on any third party tools or jars other than those published by Sun and expected in a servlet environment (Servlet API, JSP/JSTL). Thus, adding third party tools to your WEB4J application may well be necessary. Examples of tools you might have to add:

TaskExample Tool
Unit TestingJUnit
Feature TestingHttpUnit
Build Scripts Apache Ant
File Upload Commons FileUpload
Charting JFreeChart, Google Charts
PDF Generation iText
Microsoft File Formats Apache POI
Dependency Injection Google Guice
Aspect Programming AspectJ

The toString, equals, and hashCode Methods Have Some Repetition

WEB4J provides good tools for implementing toString, equals, and hashCode. For each Model Object, the implementations of these methods vary in details, but their general technique or style is always the same. It would be very satisfying if these "general techniques" could be defined in one place.

There doesn't seem to be a satisfactory way of doing this with standard techniques of object programming. You may want to try and remove that repetition by using aspect programming tools such as AspectJ. Using JDK 5 annotations may be another option.

Backwards Compatibility Issues

We apologize for making occasional changes that are not backwards compatible. Such changes occur only when deemed necessary for the long term quality of the tool, in the direction of increasing elegance and simplicity. Such changes are never large scale, but it doesn't take much to break backwards compatibility. If you need to update an existing WEB4J app to a new version of web4j.jar, you may need to perform some 'migrations' to the new way of doing things, using the Version History to find items that may affect you.

You should evaluate the recent Version History to see if you are comfortable with the size and frequency of such changes.

It's true that there isn't much positive to say about such changes, except for this: it allows the tool to remain aggressively minimalistic, and increases its overall elegance.

"There's a natural law in programming language and API design : as backwards compatibility increases, elegance decreases."
- Bill Venners, Artima.com
Given the minimalist philosophy of WEB4J, it seems appropriate to trade some backwards compatibility problems for increased elegance and simplicity. Some will not be comfortable with this.