WEB4J Version History

web4j.jar version 4.10.0 (Published October 19, 2013)

This release is not backwards-compatible.

The most important changes are the use of JDK 1.6, and the ability to easily use the web4j data layer in any app, outside of a servlet context.

JDK changed from 1.5 to 1.6
Version 4.10.0 is the first version to be compiled versus JDK 1.6. At the moment, JDK 6 is nearly 7 years old. This change was prompted in part by the change which lets InputStream be treated as a building block class (see below).

ServletConfig replaced with Map
This is, in part, to allow more ease of use outside of a servlet context. It also improves the design, since it relies on a simple, universal data structure, and not on the presence of a servlet context. These interface methods now take a Map instead of ServletConfig:

In the context of a web app, the Map (created and passed by the framework) simply includes all of the init-param settings in web.xml. Existing custom implementations of these methods will need to change. Such changes will be minor, as long as existing code uses ServletContext to simply access config data, and nothing else (which is expected to be the case).

TroubleTicket
Method name corrected from mailToWebmaster to the more accurate mailToRecipients. Warning added to javadoc about possible problems with spam filters.

AppException
AppException now extends Exception, and not ServletException. This will break any calls to the AppException.getRootCause method (which was inherited from ServletException). This lets the class be independent of the servlet context. When the Controller needs to throw an AppException, it now wraps it in a ServletException.

The remaining items below are backwards-compatible.

Using the database layer outside of a servlet context
Previously, the design of the web4j database layer relied on the presence of javax.servlet. This was an embarrassing design error which has finally been corrected. For more information, please see the User Guide.

Various init methods
Some classes have init methods which are called only by the framework. As part of an internal re-design of how config data is processed, the following classes have had their init methods removed, since they now have access to config data in an improved style:

(Any init methods which do more than simply access config data have remained in place.)

Initialization changes

InputStream has been added to the set of building block classes

When passing an InputStream to the database, web4j uses (in the package-private SqlStatement class):

PreparedStatement.setBinaryStream(int, InputStream)
This is a JDBC method from JDK 1.6. It may not be supported by older database drivers. You may need to update older drivers.

For example code which saves and fetches an InputStream with a relational database, see the file upload feature of the Fish & Chips Club example app.

Minor nuisance: in Servlet 2.5 there's no simple way to access the uploaded file as an InputStream, so web4j isn't currently able to translate a RequestParameter into an InputStream. This will be amended when web4j moves to Servlet 3.0 as its base. When you build a Model Object from an incoming request, you will simply need to first get an InputStream, and then pass it to ModelFromRequest explicitly, instead of passing a RequestParameter object as a proxy for the InputStream.

Use of sun.util.calendar.ZoneInfo
The silly import of this unpublished class in ConvertParamImpl has been removed. The implementations of both ConvertParamImpl and ConvertParamErrorImpl have changed to use Class.isAssignableFrom(), instead of an identity comparison with the (abstract) TimeZone class.

Util.logOnePerLine(Map aMap)
In addition to suppressing values for items whose name contains 'password', this method will now also suppress values for items whose name contains the text 'credential'.

web4j.jar version 4.9.0 (Published October 5, 2013)

This release is not backwards-compatible.

DynamicCriteria
[Mark Rostron, Thomas Hallgren]. This class has changed its name to DynamicSql. Its javadoc has been clarified to note that it can be used to create not just WHERE and ORDER BY clauses, but complete SQL statements as well. This is an annoying change - sorry about that. In addition, the previous version attempted to perform an extra level of validation, by trying to detect if the SQL was properly parameterized. That code was mediocre, and has been removed. Indeed the whole idea seems to suffer from the fact that it doesn't seem possible to implement it 100% correctly. Reference: link. The DynamicSql class can be subclassed, if you wish to add that style of validation yourself.

StartupTasks
The single method in this interface now takes a second parameter, the name of a database. The database names are passed in by the framework, and are the exact same names as those already defined by your implementation of the ConnectionSource interface. It's important to note that your implementation of StartupTasks will now be called multiple times, not just once:

You will have to review your implementation of this interface to ensure it's compatible with the new semantics. In almost all cases, the adjustments will be simple. As usual, you can use the example apps as guides.

Implementations should typically have this form:

public void startApplication(ServletConfig aConfig, String aDbName) throws DAOException {
  if (!Util.textHasContent(aDbName)){
    //tasks not related to any db
  }
  else if (ConnectionSrc.DEFAULT.equals(aDbName)){
    //tasks related to this db
  }
  else if (ConnectionSrc.TRANSLATION.equals(aDbName)){
    //tasks related to this db
  }
}

Databases down at startup
[Thomas Hallgren]. The reason for the above change is that the Controller logic during startup has changed slightly regarding databases. If a database is found to be down upon startup, the app will continue, and later attempt, with each incoming request, to connect/startup the remaining 'bad' databases. An example of how this can be useful is a translation database: if it happens to be down upon startup, the app should still proceed, but in a degraded form without translations.

Decimal
The policy regarding internal rounding has been removed. It was felt that the existing design was poor with respect to rounding. When performing a calculation, rounding should be performed at the end of the calculation, and not at each intermediate step. With the new version of this class, callers must round explicitly at the end of a calculation, if needed. These methods related to rounding have been removed:

Warning: this change is trickier than most, since it affects the data returned by the API. Apps that use Decimal for rounded amounts will need to review and test their use of this class. The DecimalStyle setting in web.xml was related to the internal rounding. It can be removed from your web.xml files. (Leaving it in will not do any harm.) These methods (not related to rounding) have been added: As well, a number of new overloads of existing methods have been added, as well as some new constants.

Stopwatch
The toString method now returns a value to microsecond resolution (instead of milliseconds). Example return value : '108.236 ms'. It goes to microseconds (and not nanoseconds) to reflect the real resolution of most systems.

The toValue method now returns a value in nanoseconds, not millis; this will break most callers of this method.

DateTime
The plus and minus methods now take nanoseconds. Existing callers can simply add a new 0-valued parameter at the end of the argument list. Three new methods have been added: isParseable, forInstantNanos, and getNanosecondsInstant. DateTime is now synchronized with the current revision of date4j (1.5).

The remaining items below are backwards-compatible.

ModelUtil
[Jared Thomas, Thomas Hallgren.] Javadoc clarified: self-referential arrays are not supported. The areEqual(Object, Object) method now supports arrays.

ActionImpl
Added a field called DATA, to act as a convenience key when adding structured data to request scope (intended for JSON, XML, and so on). As well, the User Guide has been updated with a new section for serving structured data.

Controller
Formerly, the Controller handled only GET and POST methods The PUT and DELETE methods have been added as well, since those methods can be used by XmlHttpRequest.

ShowForRole
[Thomas Hallgren.] This tag has been updated to accept a third attribute, isLoggedIn. This lets you hide the display of the tag's body, simply according to whether the user has logged in or not.

Controller
[Angus Lee.] NPE line 635 in the Controller class. Logging value of app-scope item named 'com.sun.jsp.taglibrarycache', when using Jetty 9. Relates to Util.quote(). Web4j wasn't at fault, but I have coded it defensively in case it happens in some other tool again.

web4j.jar version 4.8.0 (Published June 9, 2012)

Added support for some HTML5 form controls. This release is backwards-compatible.

HTML5 Input Controls
Support has been added for seven HTML5 form INPUT controls with these values for the type attribute:

The <w:populate> tag now understands such controls. Not all browsers support these controls. For up to date information on browser support, please see html5test.com.

For an example of using these controls, please see the exercise module in the latest version of the Fish and Chips Club example application.

Beware of the color and range controls. The current draft version of the HTML5 specification (rather disturbingly) insists that such controls must always submit a non-empty value when the form is submitted. This means that it's not possible for such controls to cleanly model null-able columns in your database. If you use such controls with null-able data, you will need to add extra logic - perhaps using magic values to take the place of null.

If the browser doesn't support the color control, then the user may see a color value in its raw hex form in an ordinary text control, as in '#aa1133'.

Support for the new HTML5 date/time controls has not been added in this release. Most current browsers don't support them. Worse, when a browser doesn't support these controls, then problems ensue with prepopulating the control. The problems center on the fact that the value attribute has completely different syntax and behaviour between the new date/time controls and regular text controls. This makes it very hard to properly control the value seen by the end user in a reasonable way, in cases where the browser may or may not actually support that kind of control. For the moment, support for the new date/time controls is being left out.

DateTime
The DateTime constructor which takes a single String now accepts Strings having either a 'T' separating the date from the time, or a single space. (Formerly, only the single space was accepted as the separator.) The DateTime constructor now matches the ISO 8601 standard. Note that the standard allows either a 'T' or a single space to separate the date from the time. Both are acceptable. This also matches what is allowed by the draft HTML5 specification for forms that submit a value for input controls of type datetime-local and datetime.

WebUtil.getFileExtension
A bad bug has been fixed for the WebUtil.getFileExtension(String) method. Its attempt to find the dot character should have used String.lastIndexOf instead of String.indexOf. Its JUnit test case has also been updated.

ResponsePage
The templating mechanism used in the example applications has been moved into the core. This is implemented simply by adding a new constructor, ResponsePage(String, String, Class). This allows the removal of a helper class named TemplatedPage from the example applications. If you used such a helper class in your applications, you can now remove it as well, if desired.

Postgres Database
A note has been added to the User Guide regarding postgres. When postgres is used with web4j's data layer, you need to add this connection parameter:

stringtype="unspecified"

Populate Tag
In the example applications, instances of the <w:populate> tag have been altered to ensure that the start and end of the tag are placed symmetrically around the tag's content. For example, the end tag will no longer cut a table into two parts. (This is not a code change, merely a change in how the tag was being used in the example apps.)

web4j.jar version 4.7.2 (Published May 14, 2012)

Small release, fairly minor issues.

PermittedCharactersImpl
This is the default implementation of an interface. It was too restrictive. For example, it was disallowing U+00B4. The new implementation only calls Character.isValidCodePoint. This change is not backwards-compatible.

ApplicationInfo
ApplicationInfo.getBuildDate() now returns a DateTime, not a java.util.Date. This change is not backwards-compatible.

Form Population
[Thomas Hallgren]. For OPTION tags, special characters (for regular expressions) were not being escaped properly. Link.

Text.java
Text.java was throwing an exception when the tag's body was empty and no text attribute was specified. This should have been allowed in the first place.

Text.java was using greedy regular expressions, which should have been reluctant, in order to match against the smallest data, not the largest.

ModelCtorUtil
[Thomas Hallgren]. The private vomit method should have passed along the underlying cause. Link.

Controller Logging
The Controller now logs ApplicationInfo.toString() at the end of startup, so you can see the name and version of the app which has just started.

web4j.jar version 4.7.1 (Published September 24, 2011)

One minor bug fix.

DateTime
The DateTime.toString() method (and its corresponding unit test) should've been corrected in 4.7.0 to return a more natural result, but it wasn't. Sorry about that.

web4j.jar version 4.7.0 (Published September 17, 2011)

Small release, with relatively minor issues.

EmailerImpl
EmailerImpl can no longer be configured to send emails in a separate thread. This is a conservative policy, more appropriate to the core library. An application creating threads while running in a Servlet Container can lead to problems. For example, on Tomcat, any user threads created by an application will cause Tomcat to be unable to shutdown in the regular way.

In web.xml, the corresponding setting named EmailInSeparateThread has been removed from the example applications.

PerformanceMonitor
The option of configuring a BadResponseDetector has been removed. This tool was using worker threads. For the same reasons as stated above for EmailerImpl, it's not a good idea for a web app to spawn threads inside a Servlet Container. In addition, using an app to monitor itself is not robust, since it cannot detect all failures.

In web.xml, the corresponding setting named BadResponseDetector has been removed from the example applications.

TroubleTicket
TroubleTicket now includes basic information on current memory use. If available memory is low at a given instant, this doesn't necessarily mean that low memory is a problem. Low memory is a problem only if subsequent garbage collection doesn't free up significant memory.

DateTime
The DateTime class has been updated, to remain synchronized with the version published on date4j.net.

The toString method now returns a more natural result.

The format() methods have changed implementation. The style 'YYYYMMDD', for example, is now permitted. (This corrects an oversight.)

In addition, the text that can be passed to the format methods can now take a much wider range of values. For example, a valid format String is:

'Now: YYYY-MM-DD hh:mm:ss'
This text acts like a little template. The preamble 'Now :' is simply echoed, since it contains no formatting symbols.

Such free-form text will often need pairs of escape characters '|', to prevent h, m, s, a, f, and so on from being interpreted as formatting symbols. For example :

'|The date is:|  YYYY-MM-DD'

DateTime.isValidFormatString(String)
This method has been removed. Since the String passed to the format() methods has no restrictions, such a method no longer makes sense.

MessageList
Two related methods have been removed from this interface (and corresponding implementations)

These methods were used to suppress the display of session-scope messages in JSPs. Formerly, the messages stayed in session scope after being displayed, and a boolean flag was used to signal the fact that they shouldn't be displayed a second time.

That mechanism has been abandoned in favour of something simpler - just deleting the session-scope messages after they have been displayed. The deletion from session scope takes place in the JSP, immediately after showing the messages. The displayMessages.tag file in the example applications has been updated to reflect the new style of removing the messages after they've been displayed.

web4j.jar version 4.6.2 (Published July 9, 2011)

This is a bug-fix release, for a single important bug.

Tomcat has changed its return value for

HttpServletRequest.getRequestURI()
with respect to jsessionid. As a result, this was breaking WebUtil.getFileExtension(String). That method is used to determine the operation associated with a request (.do, .show, and so on).

web4j.jar version 4.6.1 (Published May 15, 2011)

This is a bug-fix release, for a single important bug.

The web4j data layer was not always closing connections correctly during SELECT statements. In some cases, when SELECT statements had unusual failures, a branch of code was not calling close() on database connections. This means that such connections would not be returned to the connection pool. As a result, the connection pool could become exhausted if :

  1. your connection pool isn't configured for resuscitating dead connections
  2. N SELECT statement failures occur, where N = the maximum size of your connection pool

If the above occurs, then it's a serious problem. If the connection pool becomes exhausted, then your app will no longer function: no further HTTP requests would be able to get a database connection. In other words, your app would completely hang.

web4j.jar version 4.6.0 (Published March 1, 2011)

LoginTasks
The LoginTasks interface has been added. Implementations of this interface instruct the web4j Controller how to react when a successful user login is detected. The Servlet API already has hooks for the creation of a session, but not for a successful login.

Many existing apps will already implement the same idea, usually with a Servlet Filter. Those apps have the choice of sticking with their existing code, or migrating to this new interface. If you choose to use this new interface, then you will likely need to:

If you choose not to migrate to this new interface, then you will still need to supply a (trivial) implementation of LoginTasks, which performs a no-operation.

As usual, please see the (updated) web4j example apps for working illustrations.

EmailerImpl Has Been Improved
The default implementation of the Emailer interface (EmailerImpl) has been improved. It now allows you to log in to the SMTP server, and to pass name-value pairs to configure the java mail mechanism. It uses two new settings in web.xml:

The old setting named MailServer is now obsolete, and should be removed from existing applications.

Bug Fixes
Bug fixes included in this release:

web4j.jar version 4.5.1 (Published January 29, 2011)

This is a bug-fix release.

web4j.jar version 4.5.0 (Published April 17, 2010)

Thank you to Burk Mayer of Barcelona for pointing out a number of ways to improve web4j, implemented in this release.

The DynamicCriteria Class Has Been Rewritten
The changes are not backwards compatible - sorry about that. Every use of this class will need to be rewritten, but the amount of work to do so is usually minimal. Migration tasks include :

The reasons for changing this class are :

The current implementation of this class differs from the old in the following ways :

The DynamicCriteria class is still somewhat unsatisfying. The main reason is that robust validation for SQL Injection flaws likely requires a full SQL parser - which the current implementation lacks. The current implementation uses relatively simple regular expressions, and succeeds in protecting the programmer from obvious errors, but it's not perfect. (See its javadoc for more on this issue.) On the positive side, even with these defects, this class goes further than most other tools, which usually allow the programmer at least one way to define arbitrary, dynamically built Strings for SQL statements, with no checking for SQL Injection flaws whatsoever.

Database Settings in web.xml Now Sensitive To Db Name
All settings in web.xml related to the database have been made sensitive to the database name. There is a single exception - the TimeZoneHint setting is still applied across all databases. (The reason for this exception is simply that changing it would have a large number of ripple effects, and would represent too much pain for too little gain.)

Formerly, the settings were applied uniformly to all databases. This change was needed since, in particular, some applications use not only multiple databases, but also multiple database vendors (MySQL and PostgreSQL in the same application, for example).

When a database setting has a single value applicable across all of your databases, you simply specify that single value, as before. When a database setting takes different values for different databases, you define the various values with the following syntax :

100~Translation=200~AccessControl=300
The '~' character is used as a separator. Here, the first entry '100' represents the setting for the default database. It also represents the setting for all other databases, unless an override value is provided by one of the subsequent 'name=value' pairs. Thus, the above represents :

Database NameValue
[the default db]100
Translation200
AccessControl300
[any other db name]100

Messages Are Now Serializable
AppResponseMessage and MessageListImpl now implement Serializable correctly, such that messages stored in session scope can be successfully transported to a new session. This is needed for 'failover' operations between servers. There is a defect to the implementation: 'Object...' is used for message parameters, not 'Serializable...'. Thus, at runtime, you're not guaranteed that serialization will work. In practice, however, almost all message parameters will be simple, serializable building block objects.

Other Changes
Other changes in this release :

web4j.jar version 4.4.0 (Published January 30, 2010)

The main item in this release is support for the new DateTime class. This is a new building block class, similar to Integer, Decimal, Id, SafeText, and so on.

The DateTime class is intended as an alternative to the widely reviled java.util.Date class. WEB4J will support both classes, but recommends DateTime as the preferred way of representing dates and times.

The following items resulted from the addition of DateTime :

The addition of DateTime to WEB4J is not backwards compatible. Sorry about that.

Initially, to use the new web4j.jar with an existing app, you will need to :

Later, if you want to start using DateTime instead of java.util.Date, then you'll need to do more work :

Please use the Predictions example app as your guide. It makes extensive use of DateTime, while the Fish and Chips Club does not.

Other items in this release :

web4j.jar version 4.3.0 (Published Sep 7, 2009)

This release is the first to include a second example application, called Predictions. It allows users to enter and search for predictions on any topic. It was built for these reasons: Ownership Constraints
The most important addition in this release is improved support for "data ownership constraints". When data is 'owned' by a specific individual user, then there are restrictions on who can edit (and perhaps view) the data. Such constraints are very common for public web sites. Whereas the Servlet Specification has ample support for role-based security constraints, it has nothing for 'owner-based' security constraints.

In previous versions of WEB4J, you had to implement ownerships constraints manually. Version 4.3 of WEB4J adds the following items, to let you implement some commmon data ownership constraints in a manner somewhat similar to role-based constraints:

Please see the updated User Guide for more information on this topic. Other class have been updated to accomodate this new addition:

The new Predictions example application demonstrates data ownership constraints.

Anonymous Sessions and CsrfFilter
Forms are usually presented to a user only after they have logged in. There are some common cases, however, in which a form must be shown to a user who cannot log in:

(The new Predictions example application includes such forms, and illustrates the new feature described here.)

In previous versions of WEB4J, such forms could not be handled by CsrfFilter, since that class required a valid login in order to function. That is no longer the case. CsrfFilter can now be used with sessions having no user login. The following items are related to this issue :

With respect to CsrfFilter, there is one difference when a session does not include a user login: when a session expires, there's no way to recover using a 'previous' token (since there is no previous token attached to the unknown user).

Change In Populate Tag's Logic
There are use cases in which a form shown in a GET operation should use request parameters to populate the form :

The logic of the Populate tag has been amended slightly to the following:
if a Model Object of the given name is in any scope {
  override the default HTML for each control
  use the Model Object 
  (match control names to Model Object's getXXX methods)
}
else if the request is a POST  {
  override the default HTML for each control
  must populate every control using request parameter values
  (match control names to request param names) 
}
else if the request is a GET {
  if control name has a matching req param name {
    override the default HTML for each control
    populate control using request param values
    (match control names to request param names) 
  }
  else {
    use the default HTML for that control
  }
}
The new logic change is in the final GET branch. Before, the logic was based on the kind of operation. The new logic is more inclusive, and allows all GET operations to have the option of populating forms with request parameters. Strictly speaking, this change is not backwards compatible. However, it is also likely that the great majority of applications will not be broken by this change.

Escaping Characters for JSON Data
JavaScript Object Notation is a simple way of implementing a public API to your website's database. Serving JSON allows other developers to access your data programmatically, using javascript. Two new methods related to JSON have been added:

Please see the ViewPublicListJsonAction in the new Predictions example web app for an illustration of generating JSON text.

Miscellaneous Changes

web4j.jar version 4.2.0 (Published March 19, 2009)

The following change is not backwards compatible. However, it will affect only those who have created custom implementations of the PermittedCharacters interface:

The PermittedCharacters interface and its default implementation have been changed to use code points, not chars. This was necessary since some languages use marks that are represented not by a single char, but by a pair of chars. In addition, PermittedCharactersImpl has been changed to accept code points categorized as NON_SPACING_MARK by Unicode. (This was needed to accept Thai characters, but is likely necessary for other scripts as well.) The implementation of SafeText has been updated, to iterate correctly over code points instead of chars.

The following additions are centered on making it a bit easier and safer to delete N items at once :

For an illustration, please see the "Members" feature of the Fish and Chips Club example application (version 4.2).

Minor changes to the User Guide :

web4j.jar version 4.1.0 (Published February 21, 2009)

This is the first open source version of WEB4J.

Minor fixes :

New items added :

web4j.jar version 4.0.0 (Published December 21, 2008)

The web4j.jar binary is now free, and has no time limit restrictions whatsoever.

The distinction between Trial Version and Full Version no longer exists. The following features, formerly available only in the Full Version, are now always available :

web4j.jar version 3.10.0 (Published September 20, 2008)

This release is focused mainly on adding a new building block class called Decimal. The reason for adding such a class is to provide a more friendly way of dealing with items with decimal values than that provided by BigDecimal. Decimal is meant for representing money amounts and measurements. The Decimal class extends Number, so it can be used in the same way as a BigDecimal, Integer, and so on.

Conversely, support for Float as a building block has been dropped completely. The reason is that, for typical business applications, floating point data has many undesirable characteristics, making it an almost pathological data type. Any WEB4J apps that use floating point data will need to convert to either the new Decimal class (recommended), or BigDecimal.

The following classes have been affected by this change, and no longer support floating point data. Thus, these changes are not backwards compatible (sorry about that):

One other item is also not backwards compatible :

We apologize for any inconvenience these changes may cause. All other items are backwards compatible.

The addition of Decimal has made other additions necessary :

Other changes :

web4j.jar version 3.9.0 (Published August 30, 2008)

This release is focused mostly on improving security. Many of these changes are not backwards-compatible. We apologize for that. The justification for these nuisances is that, in the end, your apps will have significantly better protection against malicious attack.

Reminder list of upgrading tasks (more details below) :

SafeText versus String
Of particular note is the new emphasis on SafeText instead of String. This new emphasis will often be a nuisance to those migrating from earlier versions. We apologize for that. The underlying reason for the change is to make the protection against Cross-Site Scripting attacks as strong as possible.

Roughly speaking, String has been made a second-class citizen in the list of supported base classes, while SafeText has been promoted to take its place. If you were already making liberal use of SafeText, then this changes shouldn't be too onerous.

The PermittedCharacters interface has been added, with PermittedCharactersImpl as its default implementation. The idea here is to define a white list of accepted characters for all instances of SafeText. The default implementation may or may not work for you. Old apps will break if they use unusual characters. The fix is to supply your own implementation of PermittedCharacters which accepts the unusual characters. For an example, see the Fish & Chips Club, which needed to extend the default implementation for a single unusual character.

ConvertParamImpl now works with a new setting in web.xml, called AllowStringAsBuildingBlock. By default, this setting is 'NO', which disallows using String as a building block class such as Date, Integer, and so on. Again, the reason is to protect you from Cross-Site Scripting attacks. If you still wish to use String as a regular building block class, you may still do so by setting AllowStringAsBuildingBlock to 'YES'.

Other related changes :

Session Management
The following changes improve security of sessions. The general idea is that since session identifiers are open to session fixation and session hijacking, sessions and their identifiers should be treated as a controlled substance. Sessions should be created only when the programmer explicitly intends it. They should not be created liberally.

The most conservative approach is to create a session only when the user logs in. In addition, your app should explicitly destroy session cookies when the session ends. See the LogoffAction in the Fish & Chips Club for an example.

SQL Injection
These changes improve protection against SQL injection attacks :

Although previous versions of WEB4J did not have the above behavior, those previous versions still had strong protection against SQL Injection attacks. However, it was recently noticed that DynamicCriteria was theoretically open to some obscure problems -- not really through crafted input, but rather through some egregious and bizarre programming errors, in which criteria added in code did not actually contain any '?' parameters. Such cases were unlikely, but theoretically possible. In addition, since the programmer is the source of the criteria, and not a crafted request, it's very improbable that such programmer errors could have resulted in a successful SQL Injection attack.

However, the above improvements to DynamicCriteria were felt to be necessary, in the interest of providing protection even from unlikely sources of error.

Defaults Settings in web.xml
The following changes were made to default settings in web.xml. Strictly speaking, these changes are not backwards compatible. In practice, however, these changes are not likely to affect most apps, since few apps would have actually relied on the old default values.

Other Items
Other items in this release :

web4j.jar version 3.8.0 (Published June 7, 2008)

Small update (backwards compatible) :

This update is mostly about improving support for typical unit testing, by providing a number of test doubles. The test doubles aren't provided as part of web4j.jar, but rather as source code in the example application. They are provided as source code since they are usually incomplete, and may need to be edited occasionally. (They are incomplete since some methods, typically not needed for unit testing, are left unimplemented.)

For more information on unit testing, please see the User Guide.

web4j.jar version 3.7.0 (Published May 12, 2008)

Small update (backwards compatible) :

web4j.jar version 3.6.1 (Published April 8, 2008)

Minor bug fixes (all backwards compatible) :

web4j.jar version 3.6.0 (Published March 11, 2008)

A single change is not backwards compatible (sorry) :

All other changes are backwards compatible :

web4j.jar version 3.5.0 (Published February 16, 2008)

Two changes are not backwards compatible. Both are related to startup operations : In effect, any ConnectionSource initialization tasks have been moved directly into ConnectionSource itself.

All other items are backwards compatible :

There is now a distinction between the behavior of the trial version of web4j.jar and the full version of web4j.jar. These distinctions are minor, and affect only the execution of the following startup validations :

web4j.jar version 3.4.0 (Published January 22, 2008)

The sorting mechanism has been changed (and the changes are not backwards compatible).

the <w:sort> tag has been removed, for these reasons :

The <w:sort> tag might have been fixed, but given the other issues, it was decided to drop it entirely, in favor of a more satisfying mechanism, implemented in code instead of the JSP. Changes include :

web4j.jar version 3.3.1 (Published January 15, 2008)

All changes are backwards compatible :

web4j.jar version 3.3.0 (Published December 19, 2007)

Changed (not backwards compatible - sorry) :

Added/Changed (backwards compatible) :

web4j.jar version 3.2.0 (Published November 15, 2007)

Added :

Response Headers - the Controller now sets the charset HTTP header for every response, according to the existing CharacterEncoding setting in web.xml. Thus, JSPs no longer need to repeatedly set this header. If desired, you may override in a JSP by using the page directive.

web4j.jar version 3.1.0 (Published October 27, 2007)

Tools for building more secure web apps, and other items.
Only two new classes have been added.

Added :

Fixed :

WEB4J source did not compile/run under JDK 6! (Sorry about that. A single call to Class.getConstructors() failed. This call generated only a warning under JDK 5. WEB4J source now compiles/runs under both JDK 5 and JDK 6.)

This failure was apparently an instance of the following (taken from JDK 6 docs) :
"The cast implementation adheres more closely to the Java Language Specification. In general, this means that javac will accept more programs. However, in some rare cases, javac can now reject previously accepted, yet incorrect programs." - see link (point 5).

Changed (backwards compatible) :

Changed (not backwards compatible - sorry) :

web4j.jar version 3.0.0 (Published September 8, 2007)

Very large number of changes, deletions, and additions. (Unfortunately, there are too many to list here.) The overall number of classes has actually decreased slightly.

The tool has been improved substantially, and is now both more elegant and robust.

Some highlights include :

web4j.jar version 2.3.0 (Published November 11, 2006)

Items not backwards-compatible with version 2.2.0 : All other items are backwards-compatible with version 2.2.0 :

web4j.jar version 2.2.0 (Published September 9, 2006)

Items not backwards-compatible with version 2.1.0 : WEB4J now has good support for multilingual applications. WEB4J generates user-visible output in these ways : showing response messages (AppResponseMessage), viewing ResultSets (ReportBuilder), showing dates (ShowDate), and prepopulating forms (Prepopulate). All of these areas have been affected (some of the changes are unfortunately not backwards compatible). Here is a summary of the changes : All other changes are backwards-compatible with version 2.1.0 :

web4j version 2.1.0 (Published March 26, 2006)

One item in 2.1.0 is not backwards-compatible with version 2.0.0 : All other changes are backwards-compatible with version 2.0.0 :

web4j.jar version 2.0.0 (Published February 18, 2006)

web4j.jar version 1.9.0 (Published November 12, 2005)

web4j.jar version 1.8.4 (Published September 4, 2005)

web4j.jar version 1.8.3 (Published June 11, 2005)

The main addition to this version is Pick Lists. See MyPickListDAO for an extended discussion of WEB4J's design for Pick Lists.

Add two items which model Pick Lists :

Add two JSPs to allow an administrator to edit Pick Lists : Add corresponding WebActions for such edits : Extensive changes to MyPickListDAO.java were needed, along with minor changes to Other items included in this version :

web4j.jar version 1.8.2 (Published April 23, 2005)

Add Oracle 9.2 as a second database example, in addition to MySQL. Provide CREATE TABLE statements for Oracle, and a second version of the sql.properties file. As an illustration, the issues encountered during the port were :

web4j.jar version 1.8.1 (Published March 5, 2005)

web4j.jar version 1.8.0 (Published Feb 5, 2005)

web4j.jar version 1.7.3 (Published Dec 29,2004)

web4j.jar version 1.7.2 (Published Dec 26, 2004)

web4j.jar version 1.7.1 (Published Nov 8, 2004)

web4j.jar version 1.7.0 (Published Nov 7, 2004)

web4j.jar version 1.6.0 (Published October 10, 2004)

web4j.jar 1.5.0 (Published July 3, 2004)


Configurable Selection scheme for enumerated items Better support for multi-valued parameters, and demo thereof Variation of MyUser to demonstrate 1..N relation AbstractRequestParser.java Small changes

web4j.jar 1.4.0 (Published May 15, 2004)


Large changes Medium changes Small changes

web4j.jar 1.3.0 (Published Feb 21, 2004)

There is a single, large edit to this version. A browsing mechanism, suitable for browsing a large result set interactively, using various sort, filter, and page criteria, has been implemented.

Added :

Edited :

web4j.jar 1.2.0 (Published Feb 03, 2004)

Large changes Medium changes Small changes

web4j 1.1.1

This is the first version sold as a zip file.