Let's face the facts
by Karl Banke
The Java Server Faces Framework has been under development for about a
year and a half. Now it is finally available for public review.
But was it worth the wait? In fact, we waited so long that we started
to develop a framework of our own that is now
available for preview.
So let's compare the (preliminary) specification with our own and
have a closer look at some of the design
decisions and development implications that are implied.
First let me say that I love standards. They make development so much
easier, since they enable migration between products, minimize vendor
lock-in and generally are a good way to protect your IT investments.
I also love to program multitier Java applications. They are fun
to develop, run almost seamlessly in a distributed environment and
scale easily. On the other hand, customers are not so much worried that
your application is easy to distribute and scalable. They are worried that
you build the kind of application that they envision - in time and budget.
Along comes rapid prototyping
In conventional software development this maps quite easily to
something called rapid prototyping.
For Java web applications - and most other web applications for that matter -
rapid prototyping is a fairly new way of developing
things. There are usually mockups done with HTML editing tools
and of course there are storyboards - usually developed using
Photoshop or something similar to create an impression of the layout and
control flow of the final application. And there are numerous libraries that
allow you to create some sort of page flow or state machines. They might
even include a tag library for wiring a server side model with some HTML
widgets. But most of these are quite crude and do not map well to the behaviour
of user interface components. And more often than not they
do not allow templating to adapt to
different corporate identities and they can't be configured to work with
different device types like WAP, HTML, iMode etc.
For the last year or so I have been very worried that the JSP and
Servlet environment might loose its position as a first class environment
for web development. Especially Microsoft's ASP .NET framework
started providing more and more functionality in their built in components.
Input validation and callback handling provided a development approach
similar to the one used with traditional UI development. At the same time
MS provided some indispensable components that are required for web
development, like a date chooser or a table component along with the
simple HTML form components that you'd come to expect anyway.
But as I said before, I believe in standards. So we put our bets on the
Java Specification Request No 127,
called Java Server Faces. Unfortunately the expert group did not
manage to release a specification as planned and our attempt to participate in
this expert group was not successful - for whatever reason I don't
remember, but it might well have been our own fault.
Anyway, in fact it took them so long
to produce something that we at iternum started to loose faith in this
particular specification and started our
own UI framework implementation in
June 2002. By the end of August we were almost finished with the design,
although nowhere near to release it to the public yet. As it happens,
this was precisely the time something was finally coming out of JSR127.
What's facing us?
So let's have a look at what is available right now, as of 2002-09-06 12:00
MEST. There is a tutorial, a specification and a reference implementation
available for download
from the Java Developer Connection. Please keep in mind that the state of the
specification is still draft but it looks complete enough to allow some
comment about its architecture and design. Let's measure it up to some of
the main goals that are laid out in the specification. It is also quite
interesting to compare it with the design of our own components, revealing some
striking similarities as well as differences.
The main requirements I have for a server side UI framework is mainly
about the following points. As it turns out, these are basically the same
points that the Java Server Faces specification tries to address.
- Rapid prototyping - make it easy to compose a UI application
with minimal programming effort.
- Form handling - allow composition and processing of multiple
forms on one or multiple pages.
- Type conversion - Create a meaningfully typed server side model
object from the request and render it back to the client in a meaningful way
- Templating - Apply your own look and feel for rendering the components
- Error Handling - Define an error reporting model to report processing
errors to the client
- Provide a rich variety of components to choose from. Specifically provide
higher level components like tables, trees and tabbed panes
Lifcycle based
Unfortunately the reference implementation that was available from the JDC
today just won't work, although I followed the instructions quite literally.
Therefore, all information mentioned here is taken from the specification.
The first thing that I find interesting is that the whole framework is designed
across a lifecycle process rather than being designed around the components
itself. If a request is processed it passes through seven lifecycle phases
as shown in figure 1 below. During the processing a component tree is built.
Then several operations are applied to the components of the tree until the
"Render Response" phase is reached which results in delivering a new view to
the user.
Figure 1.: The lifecycle used in Java Server Faces. Source: Java Server Faces Specification, Early Access 2
In contrast to the JSF specification we found it much more natural to
create our model not around the request processing lifecycle but around
the component model. At the heart of our component model is the Page that
contains any number of UIComponents. This creates a tree much like in JSF.
However, unlike JSF we specifically divide between Page (or Tree) definition
and Page execution. From our point of view, the "Reconstitute Request Tree"
phase of the JSF Lifecycle is superfluous, since we assume that for any
users session there is only one active Page (or Tree) at a Time.
Also, our tree structures are inherently static once they are defined. This
is analogous to a user interface in a windowed application where the
component hierachy of the interface stays the same but components can be
turned on or off by changing their attributes.
The second phase of the JSF lifecycle - Apply Request Values - is used
to create the typed values for the components from the request and store
them in the components. After this phase the "Handle Request Events" phase
can be used to handle any events that have been generated on the client and
that might not map to a simple form submittal - for example clicking on a node of a tree control, selecting a tab in a tab control or something similar.
In the next phase the components are validated using Validators that have been
registered with the components. After successful validation the model values
are updated. Before the response is rendered back to the client, events can
be delivered to the application that can then take some appropriate action
- e.g. actively storing the model values in some data source.
Our implementation relies purely on an event delivery mechanism to pass
through the stages of storing and validating the values and updating
the model. It turned out that this is a more flexible way of handling
the user interaction than the queing of different stages. For example, the
event driven model makes it very easy to nest forms within a page inside
other forms and allow to submit or to update the full dataset or just a subset of
the data while retaining the full input of the user. This will not work with
the current JSF specification since by definition all component validations
must be successful for an update to occur. It also becomes much easier to
create statically wired component trees for rich components like tabbed panes.
With the current JSF specification this involves a rather awkward
reconfiguration of the component tree prior to each request - very hard
to accomplish without extensive object creation activity or component
instance caching.
One of the rather irritating responsibilities that occur during the
JSF request processing lifecycle is that the stages that transfer to
the Render Response phase can optionally manipulate the component tree
for output. This is somewhat analogous to an event listener in a standard
gui application that creates a new gui panel. In my gut this just doesn't
feel right, although it probably works alright. In case of high level
components - like a tabbed pane for example - the render response tree
might be switched to the new panel page in this phase.
JSP Integration
The JSF specification defines a framework that might describe any
server side Java UI framework. In constrast, our framework has been designed
specifically to work with the servlet and JSP API. This creates a somewhat
higher level of abstraction in the JSF. However in typical development tasks
this does not really show. Actually to display and process
a simple form with either framework can amount to the usage of some JSP
Tags. Of course there are development situations where the usage of JSP tags
becomes a bit clumpsy. Both frameworks allow you to divert to pure Java coding.
The JSF specification requires the use of a registered
servlet for request processing. For rapid development this might introduce
additional overhead concerning registration and configuration of the servlet,
but as I mentioned before, I just did not manage to actually try it.
Our framework can work with plain JSP, just requiring the usage
of a tag library for definition and processing of gui elements. I like that.
One of the biggest drawbacks of the JSF specification is that it does not seem
to provide support for wiring pages together in a declarative way, preferably
within the JSP page itself. It also lacks the ability to create simple workflows
let alone stack them together. This is a bit of a disappointment. It is of
course understandable that the JSF specification does not provide a full
blown server side state machine. But simple support for workflows (e.g. a
number of pages that is traversed in a certain order), subworkflows (e.g.
branching to a subform for chosing dates) and workflow validity (for
inhibiting multiple submissions of the same form) are pretty much a standard
building block of any form based web application flow. Not supporting them
will inevitably lead to proprieraty solutions that are either project
based or supplied by a certain vendor. This is why our implementation
provides some simple tags that support these activities.
Templating
The JSF specification does not require a specific templating mechanism.
Conceptually this is quite correct, since the framework itself does
not rely on a specific presentation technology like JSPs. However
it does support delegated rendering and specific RenderKits.
This makes it possible to define renderers or a RenderKit that in
turn provides a templating mechanism. Unfortunately more often than not
such an implementation will be provided by the various vendors - for
example of the application server. This will almost guarantee vendor
lock-in. Our framework on the other hand has been specifically geared
for JSP integration. It therefore provides rendering facilities that
make use of the JSP include mechanism as well as a class based delegated
rendering mechanism like the one specified for Java Server Faces.
Rich Components?
This came as some sort of shock to me. There are actually only very
few Components and Validators available in the JSF.
No tabbed pane, trees, menus or anything similar. No combo boxes and
no Validators that compare date entries. Not even entry support for dates
or numbers. Of course this is due to the fact that some work should be
available for tool vendors. On the other hand this feels wrong: For using
something as simple as a date chooser I have to tie myself to a specific
vendor, probably the vendor's IDE or even - if worse comes to worse -
her server implementation. I cannot claim that our framework does have
any of these - after just three man month of design and development!
But I am confident that they should be part of the
framework for good. Otherwise I would not have the feeling that my
investment is really protected.
Summary
Altogether I think that JSF is a good server side UI framework on a high
abstraction level. On some occasions I think it is even too high an abstraction
level. I think it is a shame that Sun was not able to provide a working
version of the demos - but I am sure by the time you read this they will
have fixed it for good. I am looking forward to see what changes the
specification will undergo until its final version. I think I gave you an
idea that there might still be plenty of stuff that can be improved. Anyway,
feel free to try it out and give some feedback to the people at the expert
group. And meanwhile feel free to try out iternums own implementation that
is available in a free alpha trial. As with JSF it also not quite complete
but fun to use.
About the author
Karl Banke is general manager and principal consultant of
iternum GmbH. He has contributed to numerous Java and J2EE project.
His publication list includes works about web usability, XML usage
and mobile web services.
Karl Banke
2004-02-02