“Comparing JVM Web Frameworks” – a response to Matt Raible

For the last few minutes I’ve been trying to post a comment on this blog post http://raibledesigns.com/rd/entry/my_everything_you_ever_wanted and the blog engine there (Roller) throws an exception. Matt links to one of my tweets as an example of the “anger” he has inspired. Here is my response, hopefully at least the blog pingback will register.

Matt, you’ve linked to one of my tweets as an example of the “anger” you have inspired, so I’ll comment.

I have no problem with the web-frameworks comparison presentation you have been making for a while, sure, it is probably highly entertaining in a conference setting, audience participation and all. For the record, I have never agreed with some of your conclusions, having followed your legendary presentation for the last four years or so, but that is another story altogether. Just one example is the fact that you gave Apache Wicket negative marks (was that 2007 or 2008?) because you couldn’t integrate Sitemesh (of all things), and you were trying to do this the night before your presentation. Many in the Wicket community remember this incident well.

What troubles me (and many others in the community) is that you give the impression that your ratings are based on objective information, but that is not true, see this tweet from you: http://twitter.com/mraible/status/9819312227352576. What you are doing is adjusting ratings based on who in the community shouts the loudest. I can’t help saying that this approach comes across as highly arrogant and condescending, you seem to expect framework developers and proponents to rush over and fawn over you to get better ratings, like waiters in a restaurant trying to impress a food-critic for Michelin stars. If you are truly someone who is qualified to evaluate the framework relative strengths and weaknesses, you should be able to come out with your conclusions and stick to them, instead of relying on “community feedback”.

So please, by all means continue to do your web-framework comparison song and dance at conferences and the like, but please stop this charade of serving as an objective source of information on web-framework comparison. You certainly do have a reputation and level of respect in the Java EE community, and I guess there are still many development teams and stakeholders who would blindly follow your advice and recommendations, which I find highly unfortunate (for example, don’t get me started on your recent SOFEA obsession ;).

It looks like you had a great time at the Rich Web Experience, I just hope you don’t add “conference ambience” as a rating factor, because in that case other frameworks don’t stand a chance against Spring MVC and Grails. Just saying.

Anyway, for those wondering if I am anywhere near qualified to comment as Matt Raible, please have a look at some of the work I have done here for example: http://code.google.com/p/perfbench/

“Perfbench” update: Tapestry 5 and Grails

I attempted to port the Seam “hotel booking” sample to Grails 1.1.1 as well as Tapestry 5.1, to add to this head-to-head comparison of Apache Wicket and JBoss Seam done earlier this year. You can find the code here: [browse] [SVN]

Here are the relative performance test results (page response time in milliseconds):

perf-four

Heap-dump comparison for 20 concurrent user / sessions:

mem-four

I’ll save detailed framework impressions and comparison for a later blog post, and I may need to make updates to the code based on feedback. Here are some overall observations:

  • Grails was far more productive than Tapestry 5. This was mainly due to the documentation quality of Grails compared to the scattered and not very well organized Tapestry documentation.
  • Ease of writing custom tag-libraries is IMO one of the best things about Grails.
  • The two missing rows in the Tapestry performance test results are because I gave up trying to implement form field validation over Ajax when the user “tabs out”. Actually I didn’t implement form-field validation at all because I could not figure out how to integrate Hibernate Validator. Maybe I missed something obvious, do let me know.
  • Grails still has some way to go in terms of performance. I am told that significant performance optimizations for GSP will make it into 1.2
  • Overall, Wicket is fastest, with Tapestry coming a close second.
  • Wicket also takes up the least amount of heap. 31 MB of the Grails heap alone is taken up by instances of the “groovy.lang.ExpandoMetaClass”.
  • Session usage of the Seam + JSF combination is significantly higher compared to all the rest, around 760 KB per session.

Thoughts on Tapestry 5

I was very interested in seeing if Tapestry 5 lived up to its promise of significantly better performance and scalability – which is known to come at a cost: a programming model that treats web-pages as static structures that can be “pooled”. One example of what this means is that you can’t rely on constructors anymore so you now have to figure out other ways of re-initializing your server-state (if applicable) after you are handed an instance from the pool. The “magic” of getting a page from the pool or getting hold of request or session scoped variables is all achieved predictably – using annotations.

Another example: due to the way Tapestry does byte-code manipulation – the annotation approach works only for “private” fields and not “protected” ones. I found this out the hard way, encountering an exception when I tried to extend from an abstract base class and re-use code the “old-fashioned” object-oriented way.

There’s a lot more I can go into, but for now, to summarize my experience as a long-time Wicket user trying out Tapestry 5 – the top few differences I found are:

  • Having to work around the implications of Tapestry pages being static and “annotation driven” programming like I described above.
  • Tapestry does not have the equivalent of Wicket Model-s which give you fine-grained control over the data you need to render (and bind) within a page and how much of it you decide to persist in the session. Model-s are certainly the aspect of Wicket that takes the most getting-used-to, but I have a new-found respect for them now after trying Tapestry.
  • I would rate the Ajax infrastructure of Wicket higher: for example Wicket Behavior-s are cleaner compared to Tapestry Mixin-s, and calling / handling Ajax requests (especially when you depend on server-side state) is far easier.
  • Tapestry 5 does not have built-in support for web-flow or “conversation scope” so I had to write some code to maintain a map of bookings in the session. BTW I did not have to do this for Grails as I could use WebFlow.

So coming back to the question, does the “Tapestry way” have a distinct advantage and are the quirks of the programming model worth it? The opinion of the Tapestry team on this is pretty clear. Take this quote from the Tapestry home page for example:

In some Tapestry-like frameworks, such as Faces and Wicket, the page structure is more dynamic, at the cost of storing much, much more data in the HttpSession.

Well, looking at the performance comparison results, my personal conclusion is that statements like the above are incorrect. In fact Tapestry seems to take up more heap space than Wicket for the same functionality. Also worth noting are the results of running the Wicket application using the HttpSessionStore instead of the default SecondLevelCacheSessionStore + DiskPageStore:

wkt-httpsessionstore

Because this time, Wicket is faster now even for the “post confirm booking” page. This particular action actually ends up displaying 200 items in an HTML table by the end of the test run for 20 concurrent users, since pagination is not being used.

The benchmark has been designed to be easy for you to run once you check-out the code, refer the end of this blog post for details. The details of the environment I used for the results posted here are as follows:

  • java.runtime.version : 1.6.0_16-b01
  • java.vm.name : Java HotSpot(TM) Server VM
  • java.vendor : Sun Microsystems Inc.
  • os.name : Windows XP
  • os.version : 5.1
  • sun.os.patch.level : Service Pack 3
  • Intel Core 2 Duo 3.01GHz
  • 3 GB RAM

Feel free to post your results or suggest changes to the code.

Wicket Tutorial: YUI AutoComplete using JSON and Ajax

Getting an AutoComplete JavaScript widget to work with a server-side framework involves a few more steps and integration points than what it would take for e.g. a simple date-picker widget. It makes for an interesting example that shows off the strengths of Apache Wicket when it comes to creating custom components – especially when Ajax and integrating third-party JavaScript and CSS is involved.

This tutorial covers the following topics:

  • Creating a re-usable Wicket custom component
  • How to use a Wicket Ajax “Behavior”
  • Integrating a third party JavaScript widget into a Wicket application
  • Packaging CSS and JS resources needed for the custom component
  • How the required CSS and JS can be contributed to the HTML <HEAD> on demand
  • Hooking into the Wicket Ajax life cycle
  • Returning custom JSON data from the Wicket server-side component

The Yahoo! User Interface Library (YUI) AutoComplete control is our target. Our example uses YUI version 2.7.0b which you can download from the YUI home page. We’ll be using Wicket 1.4 but this particular example should work unchanged in Wicket 1.3.X as well.

Note: The Wicket Extensions project includes an AutoComplete component (see it in action here) which should suffice for most of your AutoComplete needs. The YUI version arguably looks and feels richer (animation and all) and has a whole host of customizable options that are worth looking at.

You need Maven 2 installed. Create a new Wicket project by using the Wicket Maven quick-start archetype which you can find here: http://wicket.apache.org/quickstart.html

You can leave the archetype parameters unchanged, and go with the default “com.mycompany” and “myproject”. Run the Maven command to generate the project structure including quick-start Java code. In the resulting “pom.xml” add the following dependency (within the <dependencies> section) so that we can use the Jackson JSON processor library for converting Java data into JSON.

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.2.0</version>
</dependency>

Using something like Jackson means that you don't have to worry about forming JSON by hand and dealing with things such as nesting, escaping characters etc.

Now you can import the project into your IDE. Instructions pertaining to your IDE of choice are available at the Wicket quick-start page itself. Our AutoComplete use case is to load a list of country names matching the user’s input. We’ll use the java.util.Locale class as a quick and easy data source. Create a new Java class in a “com.mycompany.util” package as follows:

public class LocaleUtils {

    private static final Set<String> countries;

    static {
        final Locale[] locales = Locale.getAvailableLocales();
        countries = new TreeSet<String>();
        for(final Locale locale : locales) {
            countries.add(locale.getDisplayCountry());
        }
    }

    public static String[] getCountryNamesMatching(String query) {
        List<String> list = new ArrayList<String>();
        for (final String country : countries) {
            if (country.toUpperCase().startsWith(query.toUpperCase())) {
                list.add(country);
            }
        }
        return list.toArray(new String[list.size()]);
    }

}

And let’s also get this other utility class out of the way before we get to the really interesting stuff. Here’s the listing of “com.mycompany.util.JsonUtils” which uses Jackson to convert Java data into JSON:

public class JsonUtils {

    private static final JsonFactory jf = new JsonFactory();

    public static String marshal(Object o) {
        StringWriter sw = new StringWriter();
        try {
            JsonGenerator gen = jf.createJsonGenerator(sw);
            new ObjectMapper().writeValue(gen, o);
            return sw.toString();
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

}

By looking at the simple “Basic Local Data” YUI AutoComplete sample, we can figure that the following YUI modules are needed as dependencies for the AutoComplete control:

  • yahoo-dom-event
  • animation
  • datasource
  • autocomplete

We need to copy these modules containing JS and CSS resources from the YUI downloaded distribution into our project structure. First create a “com.mycompany.yui” package where our YUI Wicket components will live. Under the “yui” folder on the file system, create a new folder called “res” (resources). Copy the folders listed above from the “yui/build” folder into the “res” folder. You should end up with something like this:

directory-structure

The JavaScript API documentation of the YAHOO.widget.AutoComplete component says that it requires a YAHOO.util.DataSource instance to work. For example, a LocalDataSource can be used when the data is available as an in-memory JavaScript array or JSON object. We will create a new JavaScript component that extends LocalDataSource and override the “makeConnection” method to get the data from a Wicket component over Ajax. Details of how to go about implementing “makeConnection” can be figured out by looking at the base method in “res/datasource/datasource-debug.js” - which is excerpted below for completeness:

// begin excerpt from YUI code
makeConnection : function(oRequest, oCallback, oCaller) {
    var tId = DS._nTransactionId++;
    this.fireEvent("requestEvent", {tId: tId, request: oRequest, callback: oCallback, caller: oCaller});
    var oRawResponse = this.liveData;    
    this.handleResponse(oRequest, oRawResponse, oCallback, oCaller, tId);
    return tId;
},
// end excerpt

In the code taken from YUI above, “oRequest” is the string the user has typed into the input text field. So it looks like after fetching the corresponding data, we need to call the “handleResponse” method to complete the flow, and the data is passed on as the “oRawResponse” method argument.

Here is the code we end up with for “WicketDataSource” which extends “LocalDataSource” the JavaScript “prototype” way and all. We re-use the “YAHOO.widget” namespace to keep things clean and reduce the risk of JavaScript name collisions:

YAHOO.widget.WicketDataSource = function(callbackUrl) {
    this.callbackUrl = callbackUrl;
    this.responseArray = [];
    this.transactionId = 0;
};

YAHOO.widget.WicketDataSource.prototype = new YAHOO.util.LocalDataSource();

YAHOO.widget.WicketDataSource.prototype.makeConnection = function(oRequest, oCallback, oCaller) {
    var tId = this.transactionId++;
    this.fireEvent("requestEvent", {tId: tId, request: oRequest, callback: oCallback, caller: oCaller});
    var _this = this;
    var onWicketSuccessFn = function() {
        _this.handleResponse(oRequest, _this.responseArray, oCallback, oCaller, tId);
    };    
    wicketAjaxGet(this.callbackUrl + '&q=' + oRequest, onWicketSuccessFn);
};

Our implementation (override) of the “makeConnection” method uses the Wicket Ajax engine to GET data from a given URL and we pass a callback function that will call “handleResponse” once the response from the server is received. The value typed by the user is passed as as a query-string parameter "q" which will be read on the server-side.

Update: for more details on the lightweight Ajax engine and JavaScript utilities that come along with Wicket, refer this article by Nino Martinez: Wicket Javascript Internals dissected. The script.aculo.us "Drag & Drop ListEditor" example by Al Maw is another useful resource and you can get the slides and code from this page.

We could have used YUI itself to make the XMLHttpRequest but the nice thing about using the Wicket Ajax engine is that you can spy on all the action using the very nifty Ajax Debug Window in “development mode” like this:

ajax-debug-window

You may be now wondering how “_this.responseArray” gets initialized once the server request completes. The “YAHOO.widget.WicketAutoComplete” (below) is a JavaScript convenience object we define to represent and wrap a single AutoComplete instance (along with the DataSource):

YAHOO.widget.WicketAutoComplete = function(inputId, callbackUrl, containerId) {
    this.dataSource = new YAHOO.widget.WicketDataSource(callbackUrl);
    this.autoComplete = new YAHOO.widget.AutoComplete(inputId, containerId, this.dataSource);
    this.autoComplete.prehighlightClassName = "yui-ac-prehighlight";
    this.autoComplete.useShadow = true;
    this.autoComplete.formatResult = function(oResultData, sQuery, sResultMatch) {
        return oResultData;
    };      
};

So if an instance of “WicketAutoComplete” has been assigned to a JavaScript variable “foo”, the responseArray can be initialized by assigning something to “foo. dataSource. responseArray”. We will take care of this in the Java code of the Wicket component, coming up shortly.

The YUI AutoComplete expects data received from the DataSource to be a JavaScript array of items. The customized "formatResult" method override above just displays each item as-is. You could implement more sophisticated routines such as bold-ing the part that matches the user input, and you can refer the YUI examples for more details. For now, we are keeping it simple, but in the future you may want to consider things like returning a multi-dimensional array or an array of JSON objects etc. from the server.

Our “WicketAutoComplete” JavaScript object constructor takes the following arguments:

  • inputId: HTML id of the input text field (needed by the YUI AutoComplete control)
  • callbackUrl: URL where the Wicket component will listen for Ajax requests, used by our custom WicketDataSource
  • containerId: HTML id of the <DIV> where the autocomplete results will be rendered (needed by the YUI AutoComplete control)

Take the two javascript listings above ("WicketDataSource" and "WicketAutoComplete") and combine them into a single file called "YuiAutoComplete.js" within the "src/main/java/com/mycompany/yui" folder (or rather the "com.mycompany.yui" package). In the same folder, create "YuiAutoComplete.html" and "YuiAutoComplete.css" as follows:

<wicket:panel>
    <div class="yui-skin-sam">
        <div class="wicket-autocomplete">
            <input wicket:id="text"/>
            <div wicket:id="container"></div>
        </div>
    </div>
</wicket:panel>
.wicket-autocomplete { width: 15em; padding-bottom: 2em; }
.wicket-autocomplete div { font-size: 90% }

The HTML and CSS files are pretty straightforward. Setting the CSS "width" of an enclosing <DIV> is the recommended way of controlling the rendered size of a YUI AutoComplete control. The YUI CSS "skin" reference "yui-skin-sam" can be even kept at the <BODY> tag level (like in the YUI examples) but here we chose to have it self contained within our component.

And finally here is the code of "com.mycompany.yui.YuiAutoComplete" that ties everything together. A description of what is going on appears below the code listing:

public abstract class YuiAutoComplete extends FormComponentPanel {

    private TextField textField;
    private WebMarkupContainer container;

    public YuiAutoComplete(String id, IModel model) {
        super(id);
        textField = new TextField("text", model);
        textField.setOutputMarkupId(true);
        add(textField);
        container = new WebMarkupContainer("container");
        container.setOutputMarkupId(true);
        add(container);
        add(new YuiAutoCompleteBehavior());
    }

    @Override
    public void updateModel() {
        textField.updateModel();
    }

    private String getJsVarName() {
        return "YAHOO.widget." + textField.getMarkupId();
    }

    protected abstract String[] getChoices(String query);

    private class YuiAutoCompleteBehavior extends AbstractDefaultAjaxBehavior {

        @Override
        public void renderHead(IHeaderResponse response) {
            super.renderHead(response);
            response.renderJavascriptReference(new JavascriptResourceReference(YuiAutoComplete.class, "res/yahoo-dom-event/yahoo-dom-event.js"));
            response.renderJavascriptReference(new JavascriptResourceReference(YuiAutoComplete.class, "res/animation/animation-min.js"));
            response.renderJavascriptReference(new JavascriptResourceReference(YuiAutoComplete.class, "res/datasource/datasource-min.js"));
            response.renderJavascriptReference(new JavascriptResourceReference(YuiAutoComplete.class, "res/autocomplete/autocomplete-min.js"));
            response.renderJavascriptReference(new JavascriptResourceReference(YuiAutoComplete.class, "YuiAutoComplete.js"));
            response.renderCSSReference(new CompressedResourceReference(YuiAutoComplete.class, "YuiAutoComplete.css"));
            response.renderCSSReference(new CompressedResourceReference(YuiAutoComplete.class, "res/autocomplete/assets/skins/sam/autocomplete.css"));
            response.renderJavascript("var " + getJsVarName() + ";", getJsVarName());
            response.renderOnDomReadyJavascript(getJsVarName() + " = new YAHOO.widget.WicketAutoComplete('"
                    + textField.getMarkupId() + "', '" + getCallbackUrl() + "', '" + container.getMarkupId() + "');");
        }

        @Override
        protected void respond(AjaxRequestTarget target) {
            String query = getRequest().getParameter("q");
            String[] result = getChoices(query);
            String jsonResult = JsonUtils.marshal(result);
            target.appendJavascript(getJsVarName() + ".dataSource.responseArray = " + jsonResult + ";");
        }

    }

}
  • #01, #18: we extend FormComponentPanel instead of Panel so that we can seamlessly use our YuiAutoComplete component within Form instances
  • #09, #12: we ensure that HTML id-s are rendered and we pass them to the YUI AutoComplete control later
  • #14: automatically add the Ajax wicket behavior (explained below) to our custom component
  • #26: we define a method that subclasses can override to return data corresponding to user input
  • #28: we extend AbstractDefaultAjaxBehavior and we only need to override the "respond(AjaxRequestTarget)" method
  • #33 - 39: we ensure that the required JS and CSS files are contributed to the HTML <HEAD> of any page that contains our custom component. Tip: use "debug" versions of the JS files for e.g. "autocomplete-debug.js" instead of "autocomplete-min.js" to make debugging using FireBug easier. You probably don't need the "debug" versions for a "production" version of this component. The good thing about loading resources like this from the package / classpath is that you can simply JAR it all up for use by other teams.
  • #40: we output a variable declaration (global to the page) to hold a reference to our "WicketAutoComplete" JavaScript object - which can be referenced later during the Ajax request for passing data to the web page, we derive the name from the HTML id of the input TextField (#23)
  • #41: ensure that an instance of our WicketAutoComplete JavaScript object is instantiated (and assigned to the variable described above) when the page loads, note how the HTML id-s and Ajax "callback" URL are determined
  • #47: get the value of the parameter "q" in the incoming Ajax request
  • #50: ask Wicket to execute some JavaScript when the request completes which will (pass) assign a JSON array value back via our "WicketAutoComplete" object reference

Now the project within your IDE should look like this:

project-structure

Edit the "HomePage.html" and "HomePage.java" files to use an instance of our Wicketized AutoComplete component as follows:

<html>
    <head>  
        <title>YUI Autocomplete Demo</title>
    </head>
    <body>
        Enter Country Name: <span wicket:id="autocomplete"></span>
    </body>
</html>
public class HomePage extends WebPage {

    public HomePage() {        
        add(new YuiAutoComplete("autocomplete", new Model("")) {
            @Override
            protected String[] getChoices(String query) {
                return LocaleUtils.getCountryNamesMatching(query);
            }
        });
    }

}

Note how we have implemented the "getChoices()" method to return a list of country names in this case. That should be it! Start Jetty by using the "com.mycompany.Start" class that should be under the "test" source folder structure. Browse to http://localhost:8080/ and try out your shiny new Wicket + YUI AutoComplete component.

I've uploaded the source code here: myproject.pdf - just rename this to a *.zip after downloading. Do comment if you spot any mistakes or stuff that can be improved.

JSF sucks

This post is intended to be a reference for those evaluating or contemplating using JSF. Once in a while, I find myself having to convince people that there are far, far, better alternatives to JSF. With this blog post finally in place, from now on I will probably just refer people here. Please pass this link on to those you feel will benefit from this fairly large selection of links and real-life experiences collected from across the interwebs. And if you have any more such links, do let me know in the comments.

Update: [2010-01-23] – Ed Burns, co-spec lead for JSF has just posted a detailed response to this blog post here:

A Response to Peter Thomas’s JSF Critical Screed

Readers are encouraged to also read the other side of the argument there and form their own conclusions.

My 2c:
Clearly, many architects recommend JSF as a “safe choice” for new projects just because it is a “standard”. All I’ll say is that there is more than enough evidence to prove that JSF is flawed in some significant and fundamental ways – especially compared to available alternatives.

We all know what happened to EJB 1.X / 2.X. Will JSF go the same way?

You read and decide.

[2004-03-04] JCP Releases JavaServer Faces 1.0 – JSF 1.0 approval is announced on TheServerSide, not many people sound impressed. The negative reaction (along with quotes) is summarized in this Internetnews.com article: Programmers So Far Underwhelmed by JSF. Quote from the article:

The Java Community Process (JCP) has approved a standard for building Web applications at the presentation layer, but the reaction of some programmers so far is that it adds another layer of complexity while delivering nothing they can use.

[2004-03-05] JSF: The Ultimate in Flexibility? Or Complexity? – JDJ article by Steve Benfield. Quote:

What I see in JSF is overengineering. Let’s think of every possible usage pattern for Web pages and address them, not necessarily a bad thing. The resulting standard is one in which there are several layers of abstraction, many, many moving parts, and ultimate flexibility.

[2004-06-09] Improving JSF by Dumping JSP – O’Reilly / OnJava.com article on one of the problems that has plagued JSF for a long time and many unfortunate teams (who don’t use Facelets) face even today. Keep in mind that this article is from 2004. Quote:

Don’t get me wrong: I like JSP and I like JSF. I wouldn’t have spent so much time contributing to the specifications and writing books about these technologies if I didn’t think they had value. It’s the combination of these two technologies that I don’t like, because they don’t complement each other in a natural way.

[2004-08-06] My JSF Experience – blog post by Matt Raible. Some follow up discussion here where David Geary (JSF EG member) admits that JSF is not perfect. Quote from Matt’s blog post:

Whatever you do, don’t use JSF. Not yet anyway.

[2004-09-20] Boycott JSF – blog post by Hani Suleiman (who currently happens to be a JCP Executive Committee member). Quote:

So I beg of you all, don’t use JSF, boycott it, avoid it all you can. Do not let it thrive or prosper. We don’t want it improved or tweaked, we want it to die the horrible painful death it so richly deserves.

[2005-07-??] Gradebook – Taming JSF 1.1 – an article / wiki page by Ray Davis detailing the problems faced by the Sakai project and how they had to work around some of the issues faced. The content here can be considered somewhat outdated (relates to JSF 1.1) but serves to highlight the elementary problems that JSF has had in initial versions of the spec itself. Some commentary also on other blogs here and here.

[2006-01-20] JSF Burrito: More Complete List – commentary and a list of JSF pain points by Tim Shadel. Part of a series of blog posts – read the others here, here and here. Quote:

Ultimately, JSF provides a Leaky Abstraction that (in spite of its promise) still requires all developers to understand Request-Response in addition to the 6-layer lifecycle. (”Response already committed” error, anyone?)

[2006-02-10] JavaServer Faces – why? – discussion thread at “Joel on Software”. Quote:

I’m a complete JSF newbie, and I’ve been trying to hack together a small demo app. I’ll spare you all the gory details but long story short I _hate_ JSF. Hate it, hate it, hate it. I honestly can’t imagine how anyone at Sun could ever imagine this as a competitor to ASP .NET.

[2006-02-21] Usability problems in JSF – blog post by Adam Winer. Quote:

A second category of annoyances in JSF consist of “nothing happened” problems. For example, if a validation error stops you from going on to Invoke Application, but you’ve forgotten to add an tag or something similar to your page, all that you see is – nothing.

[2006-05-03] Where JSF and Portlets went wrong… – blog post by Jevgeni Kabanov, founder of the company that makes JavaRebel JRebel. Some follow up discussion on JavaLobby here. Quote:

What’s worse, JSF have imposed on us a highly complex and clumsy API, that one needs to follow to achieve even a little reusability and broke the familiar way of capturing logic in custom JSP tags.

[2006-05-19] JavaOne: Google Web Toolkit vs. JSF – blog post by Bob Lee, creator of Google Guice. You can’t help thinking – if JSF is so great as the vendors / authors / evangelists would have you believe – why are there so many competing Java web-frameworks? Quote:

For the majority of intents and purposes, GWT invalidates JSF. Both frameworks seek to isolate web developers from HTTP, but due to the fact that Google built GWT from the ground up with AJAX in mind, GWT offers a cleaner abstraction, better type safety, and a lower learning curve. When it comes to AJAX and JSF, you’re at the mercy of which functionality your JSF components offer.

[2006-06-19] JSF Rough Spots – blog post by Don Brown compares JSF and Struts 2, talks about how JSF is more verbose and cumbersome to use.

[2006-06-20] RE: What Web Application framework should you use? – blog post by Matt Raible, and the comments are well worth reading. Quote:

JSF continues to be the most over-hyped under-used framework in Javaland. If you read the blogs of first-time users, you’ll find many complaints and issues on how things work.

[2006-09-08] JSF and RSFHistory – wiki page detailing some of the issues with JSF that led to the creation of RSF (Reasonable Server Faces). Quote:

I could go on about JSF’s other architectural deficiencies (firstly the existence of FacesContext, and secondly the global access to it which is the most utter destroyer of testability, thirdly the crazy table rendering model, fourthly the fragile and untrustable PhaseListener system, fifthly the lack of any coherent policy wrt. exceptions &c), at some length, but I will move on :P

[2006-09-13] Geebis Blog: Wicket – blog post by Caleb(?) that discusses experiences with Seam / JSF and how Wicket appears to be better. Quote:

The biggest reason is that creating custom components in JSF can be difficult, especially if you want your components to have lots of javascript/css that it contributes to the page. JSF requires that you use a writer to send your component’s HTML to the browser. With this system you end up with spaghetti code that’s hard to debug, and hard to test. Add ajax functionality to the mix and you have a featureset that JSF just can’t handle in the current version.

[2006-09-16] Tinman and the Scarecrow – blog post by Dhanji Prasanna, Google Wave Core Engineer and creator of the Google Sitebricks web-framework. Quote:

It is no secret that JSF is made for tool vendors. However, it is somewhat possible to get away with working with JSF by hand only (in fact Ive done a fairly large project this way), though this is neither on par with using tools nor easy as many proponents claim. Principally, it is not fun and doesnt offer as much reward to a developer for effort spent hitting keys.

[2006-10-19] MyFaces: The emperor has no clothes – a detailed blog post by Ignacio Coloma. Of all the many rants against JSF out there, I would pick this as my favorite. It deals with the author’s experiences with JSF on a real-life project and goes into the technical details of various issues. A must read. It looks like Ignacio Coloma was so disgusted with JSF that he later decided to create a new Java web-framework called Loom. Quote:

I do not have enough space here to explain the hell that developing a custom component is, so will leave a short summary: you will be fine if you are doing a simple stupid component that is shown as a single textfield, and there are big, red, horny demons in your way if you try anything more sophisticated.

[2006-12-15] Nightmares on JSF Street in Trinidad – blog post by Rainer Eschen. Quote:

If you keep in mind that Sun started in 2003 to talk about the JSF specification in the public, we hear and talk about JSF for three years now. If I have a look at the results, I’m a bit disappointed. This is comparable to the Swing development and the missing practical GUI designers (for years).

[2006-12-19] Reasons to choose Wicket over JSF and Spring MVC – InfoQ article on experiences evaluating web-frameworks. Quote:

I liked [JSF's] form handling and navigation support but I did not like all the javascript and extra markup that was inserted into every page without me asking for it.

[2006-12-26] not enamored by JSF 1.1 – great rant by Timothy Stone on the JavaRanch forums. The whole thread is worth reading. Quote:

The RI of JSF v1.1 hijacks and pollutes the id attribute of HTML for its own use, thus rendering CSS stylesheets almost useless and making work with the DOM in Javascript a PITA. This is probably the single greatest problem I’m staring down the barrel at.

[2007-01-01] JSF in 2007 – O’Reilly.net / ONJava article by Shashank Tiwari. This promptly triggered a lively debate on TheServerSide here.

[2007-01-18] Tech Talk: Ed Burns on JSF 1.2 yet another discussion of JSF issues ensues on TheServerSide.

[2007-02-19] JSF is cool but it is too young and it has too many bugs! – yet another forum thread on JavaLobby. Quote:

I’m very tired, I spend the double of the time to develop this because of the problems I had to check out on the net, maybe I will wait for JSF to become better and for now use other technologies.

[2007-02-28] JSF Anti-Patterns and Pitfalls – article on The Server Side and discussion here. The article opens with these words:

This article covers anti-patterns and pitfalls of day to day JSF development. Most of these issues have kept the author up at night; some of these are the same old challenges with a new face, pun intended. These challenges include performance, tight coupling, thread safety, security, interoperability and just plain ugliness.

[2007-03-17] JSF – Still pretty much a steaming pile of donkey turd – another classic rant by Wille Faler. Wille has since embraced Wicket and went on to initiate the Wicket RAD project. Quote:

The end impression is that it is a horribly convoluted, over-engineered framework that goes to great lengths to replace existing, well functioning technologies without addressing any of the pain-points at all.

[2007-04-16] JSF still sucks? – by Matt Raible, creator of AppFuse and someone well respected in the Java community especially for his web-framework comparisons. Quote:

Conclusion: don’t use JSF simply because it’s a “standard”. Use other frameworks that are more actively developed and designed for the web. For component-based frameworks, the most popular are Tapestry and Wicket. Less popular ones are RIFE and Click.

[2007-04-26] Creating a jsf div component – blog post by Andrej Koelewijn. The amount of code and effort that is required for just creating an HTML DIV is to be seen to be believed. Discussion on TheServerSide here.

[2007-05-14] A Wicket user tries JSF – a side by side comparison of JSF (MyFaces) with Wicket by Peter Thomas. Lots of discussion in the comments. Quote:

JSF is supposed to be a component oriented framework but I wouldn’t call them Java components and definitely not Object Oriented.

[2007-05-22] Rethinking JSF – The Real Problem – after a flurry of JSF-bashing blog posts appearing in early 2007, Joseph Ottinger (then editor of TSS) attempts to do some damage control. But the ensuing discussion thread is a good read with some gems in it like this one comment by Leo Lipelis that does a great job of listing and explaining a bunch of JSF issues. More discussion can be found here on the Artima forums. Quote (Leo Lipelis):

JSF multi-rendering capability — it’s an API bloat the weight of which you feel when designing custom components. Whether a project will benefit from multi-rendering or not is questionable. Why should I pay the price in terms of conceptual complexity of an API when I may not even need to use it in 99.9% of the use cases?

[2007-05-23] Six Things JSF Breaks (and How To Fix Them) – blog post by Josh Justice, title is self explanatory. Quote:

This is certainly no small list of challenges! JSF was built in a time when fewer client-side technologies were available, but it also seems to be targeted to projects that require less client-side interaction. If you are developing the next great web 2.0 application, you may want to consider a framework that intrudes less into the markup of the page, such as Struts or Spring.

[2007-05-25] JSF and real stuff – yet another laundry list of JSF problems outlined in this JavaLobby thread.

[2007-05-28] anti-JSF thoughts – blog post by Mert Can Akkan.

[2007-06-05] Re: Rod Johnson: “Java EE 6 Gets it Right” – in response to a comment I made on a TSS thread, Rod Johnson says this:

I still haven’t made up my mind about JSF, but we have people in our community who want to use Spring (and Spring Web Flow) and JSF, and it’s important that we accommodate that.

To put that quote in context, note that three years prior, Rod Johnson and Juergen Hoeller (Spring Framework #1 and #2) had this to say about JSF on page 408 of the book “Expert One-on-One J2EE Development without EJB” [2004, Wiley]:

Java Server Faces has been hyped as the next big thing in J2EE web development for more than two years and is now taking shape. In its current incarnation, JSF is a JSP centric affair that is heavily targeted toward GUI builder tools, resulting in code that gathers all sorts of concerns in the web page. There is no notion of view-agnostic controller and model, and no concept of pluggable views. With this programming model, JSF is well-suited for attracting .NET and other RAD developers, but not for becoming the de-facto standard web MVC framework in the Java world.

We expect to see a massive vendor marketing push behind JSF. However, we are not convinced that JSF will represent a real advance on existing open source solutions such as Tapestry, WebWork, and Spring web MVC.

[2007-06-07] c:forEach vs ui:repeat in Facelets – blog post by Roger Keays. Facelets is supposed to rescue JSF from JSP but it is not without its share of quirks !

[2007-06-11] the death of reason, professional addition – yet another blog post that suggests JSF is guilty of driving a fair number of developers away from Java. Quote:

i’ve been in a JSF class this week that has only reinforced my opinion that java web development sucks. it’s an over-engineered amalgam of crud. what i’m noticing, too, is that JSF is way behind the curve on annotations-is-the-new-xml java craze. this class has more than doubled my appreciation of ASP.NET.

[2007-06-27] Prefer RIFE,Stripes,Wicket to JSF – blog post by Frederic Daoud. Quote:

I recently worked on a professional project with JSF and ran into several problems. Don’t think I didn’t try “extras”: Facelets, Seam, … In the end it just piles on complexity without solving the problems, or solving them but introducing new ones.

[2007-09-07] Re: Java’s Fear of Commitment – O’Reilly / OnJava.com article by Robert Cooper. Quote:

I think JSF blows chunks.

I think Seam blows chunks squared.

While I can appreciate the design ideals of component based development on the web, each of these technologies, and especially stacked, represent an abstraction above and beyond what HTTP really is that makes me sick to my stomach to think about.

[2007-10-25] JSF Today: Standards versus OSS – blog post by Bruno Borges. Quote:

JSF 1.2 (JSR 252) is targeted for JavaEE 5.0. And I don’t even see JEE 4 in every customer I go, just like JSE 5, so try to imagine when JSF 1.2 will be world wide deployed. Again, standards are cool, but they lose speed. This spec was delivered at December, 19, 2006 and alternatives like Tapestry, Echo and others, including Wicket, are improving faster than JSF since that time.

[2007-10-27] JSF First Impressions – blog post by Keith. Quote:

[...] with JSF — you’re farther away from the final HTML. Its the components you include on the page that generate DIV tags and so forth. Having accrued 10+ years experience working with HTML, I find this the most frustrating aspect of JSF.

[2007-10-30] Xebia Web Framework Contest – a contest where different teams had to develop the same application using different Java web-frameworks. The team using JSF really suffered. Some follow up discussion here on Matt Raible’s blog. Quote: (‘Google translated’ from French):

JSF is clearly not the most productive framework, at least not on a day because the entry cost is heavy. And even once used to the framework, one may wonder how to be productive without error recovery and ask what limits the buffer management in the framework of a real project?

[2007-11-22] I’m a nerd. Or do I mean geek? [...] – blog post by Noah Sloan. Quote:

The problem with all that is that the JSF Ajax implementations suck. And the learning curve for JSF (much less components) sucks. It’s just too quirky. Hopefully JSF 2.0 will make component creation easy, enable RESTful services, and will make it easier for newbies and old hands to just get things done. I’d like to hope all of that, but the only positive things I tend to hear about 2.0 are from Ed Burns, who seems like a very nice guy, but whose rhetoric reeks of corporate “gotta toe the line/I think my company is the best ever [...]“

[2007-12-26] JSF 2.0 Faces Disjointed Components – SD Times article on how the “next version of JavaServer Faces aims to reduce configuration headaches”. Quote:

Sometimes, the cure for one’s woes is a hard look in the mirror. JavaServer Faces is facing up to its own configuration problems with JSR 314, the specification for JSF 2.0

[2008-01-04] Nobody Uses JavaServer Faces – blog post by Matt Long. Quote:

The bottom line is I’ve done a lot of web applications in my career, and I would *never in a million years* choose JSF to build a web app. It’s nearly unusable. Don’t get me wrong. I am getting the project done, but that’s a testimony to my own development skills, not how great the technology is. JSF stinks.

[2008-01-11] A Year of Wicket – blog post by Julian Sinai who evaluated web technologies and chose Wicket over JSF and other contenders like Tapestry. Quote:

I also took a close look at JSF. It seemed overly complex to me, and not much of a departure from the Struts era. It came across as a technology designed by committee, with the combination of several complementary libraries required to get the job done, and there are still too many configuration files.

[2008-01-28] Choosing a Java Web Framework – blog post by Ryan Sonnek. Quote:

Considerable ramp up time and tool support is a requirement to be productive. Instead of just working with standard Java and HTML, you end up locking into a particular toolset. The tools get you up and running very quickly, but you pay for the convenience since you can only build what the tool supports and they restrict how much you can do with the internal framework.

[2008-03-02] [OT] JSF vs. WebObjects – thread on Apple mailing lists. Quote:

As a final word i’d say that I won’t choose JSF for new project, i’d rather choose other frameworks like wicket or tapestry which are far more mature.

[2008-04-01] Thoughts on Java web frameworks and RIA – blog post by Sanjiv Jivan, creator of GWT-Ext and SmartGWT. Quote:

I’ve said this before that I feel that JSF is an incarnation of EJB 1.x which is overengineered and too focused on “enterprise patterns” making the simple things not so simple to implement.

[2008-04-10] JSF: A Wish List – Java Developer Journal article by Shay Shmeltzer. Quote:

Since the JSF specification doesn’t include a definition of how AJAX should be incorporated into the JSF lifecycle, each vendor/framework has its own approach to handling AJAX events, usually involving extending the JSF lifecycle. The result is that developers end up with one set of components that collides with the architecture of another set because they have different lifecycles. This must be addressed in the next release of JSF.

[2008-04-28] JSF2 – wiki page maintained at the Seam web-site on all the stuff in JSF 1.X that needs fixing in 2.0. It is painfully clear from this list how much of a raw deal JSF 1.X is. And *another* page of things to be fixed in JSF2.1 exists! Look for it somewhere below.

[2008-05-03] Game Over Java Server Faces – this was a great rant that suddenly does not seem to exist on the web anymore – so I’ve linked to the DZone entry for now. If anyone knows where this blog post can be found now – do let me know!

[2008-05-14] Developing long term strategies for using Java EE technology – a very telling quote from this IBM DeveloperWorks article goes like this:

JSF is still a relatively new technology. JSF is undergoing a major revision for the next round of specifications with an expected integration between JSF managed beans and Enterprise JavaBeans™. The risk of changes affecting existing applications will be higher here than with other presentation technologies. IBM does have representation on the JSF expert group and will keep a watchful eye out for problems.

One area of future concern is be how well Ajax support in JSF will follow the specifications for the OpenAjax Alliance. Through its participation, IBM will try to ensure that compatibility is maintained as the standards move forward. Ajax support in JSF will be new (when it appears) and use of that feature will be at a somewhat higher risk than other parts of JSF. More details will be known in early 2009.

[2008-05-14] JSF Issues – blog post by Phill. Quote:

Although JSF does make some development quicker, the amount of time you lose to stupid problems like this probably negates any gains you made originally.

[2008-05-29] At RailsConf 2008 [new] – I think the commenter that submitted this link (Ignacio Coloma) says it best:

I love the part where Craig McClanahan pulls JSF out of a hat, throws it to the crowd, then moves on to develop Rails applications.

[2008-06-06] Has anyone noticed? JSF components are hard even when they are easy… – blog post by Jesse Sightler. Quote:

Ever since I’ve had the experience of using ASP.Net and comparing it to JSF, I’ve been hoping that someone would come up with a way to improve the sorry state of affairs that is JSF component creation. Far too much time is spent on complex components and supporting a billion renderkits, when most of the time, I just want to be able to composite a couple of preexisting controls.

[2008-07-10] Seam, a second look at JSF – blog post by Petrik de Heus. Quote:

I actually forgot how much JSF sucked (I remember it was hard to test). The biggest problem is that it’s been developed by someone who doesn’t use it to write real applications. It’s full of crappy implementations of concepts that seem like a good idea from an ivory tower.

[2008-07-11] Java Frameworks – JSF vs Wicket, etc – discussion on Ars Technica forums. Quote:

No, you aren’t missing anything. JSF sucks huge monkey balls. The worst part is the convoluted, and heavy-weight response life-cycle. When it works, everything is wonderful and magic. When it doesn’t work, good luck figuring out why.

[2008-07-25] Wonderful Wicket – blog post by Sergey Grigoriev. Quote:

After I had read a book on JSF, I had impression that JSF is overcomplicated technology. Nevertheless I downloaded the latest release of ICEFaces and tried to write a simple “hello world” application with a singe button and a message area. I’ve spent two hours configuring it and six hours figuring out how to eliminate an exception.

[2008-08-25] JSF: The Good, the Bad, and Yes, the Ugly – article by Rob Williams. Quote:

In the most recent JSF tour, we were doing a wizard and had to bind to checkboxes. That turned into a nightmare, and for all the typical JSF reasons. JSF gets a low grade for heuristics (intuition is rarely the road to figuring things out).

[2008-08-31] A rant on Java standards – blog post by Jose Noheda. Quote:

How can something like JSF be promoted to be the standard? A component framework that lacks even one interesting component! That relies on third party libraries (many OSS) that are, of course, incompatible between them. Each one with a different AJAX approach (as the specification says nothing on the topic). And, worst of all, incompatible with JSP/JSTL and portlet development.

[2008-09-22] Fundamental Failing of JSF, Some Ideas for Overcoming – blog post by Rob Williams.

[2008-09-25] More Suggestions for Suturing JSF Breach – blog post by Rob Williams.

[2008-10-04] Web Framework Project Comparison Matrix – quote:

Users say, JSF “is the EJB of web frameworks. Cool in theory. Hell in practice.”

[2008-10-26] JSF is Not Fixable – blog post by Subbu Allamaraju, author of “RESTful Web Services Cookbook“.

I have not read the latest JSF 2.0 draft thoroughly, but upon a quick reading of all the changes, I don’t see anything to address the basic web usage. Unless there are more changes coming that will magically fix the core without an overhaul, JSF should the follow JAX-RPC into the JSR-graveyard.

[2008-11-03] “Simple” JSF 2.0 Component vs. Tapestry – article by Howard Lewis Ship. Yes, even in the not-yet-final JSF 2.0 custom component creation leaves much to be desired. Hope this answers JSF apologists who would complain about the above list of links claiming that it is outdated and that JSF 2.0 fixes everything etc.

[2008-12-18] JSF with a Web Designer

We’ve done only the first page of our application, and I’m really wondering if we took the right library. I believe now that in case you have a web designer in your team, you shouldn’t use libraries that generate HTML for you, like JSF or gwt, but instead use a framework allowing to generate the precise HTML the designer wants

[2009-01-14] Seam / JSF vs Wicket: performance comparison – performance and memory usage comparison of Seam / JSF vs Wicket by Peter Thomas. Quote:

I think we can safely blame JSF for the lion’s share of memory usage [...]

[2009-02-09] The Web Framework Evaluation – Part 03 – article by Sebastian Hennebrueder. Quote:

Do you understand the JSF request phases? On a first look they look simple but in fact it is a nightmare of things happening and being dependent on each other. It is not at all easily to hook in and change the behavior.

You like JSF and you are not convinced? Then try to write a library which caches a part of your component tree to render the page faster and make sure that it works with GET and PUT requests. You will have fun, believe me.

[2009-02-15] Un-Documented JSF: Reference – community contributed list of JSF “gotchas”.

[2009-02-25] JSF 2.1 – similar to the “JSF 2″ page mentioned earlier, another page on the Seam wiki details stuff that needs to be fixed in JSF 2.1 – perhaps these are things that did not make it into 2.0 ?

[2009-04-29] Shale in the Attic – the project that Craig McClanahan (spec lead of JSF 1) started as a supplement to JSF goes “where other projects go to die”. Also see the link dated 2008-05-29 for more background. Quote:

What happened? The answer is quite simple: Craig lost interest and left the community.

[2009-05-01] JSF: Suggestion for Performance Improvement – blog post by Nicholas Hagen expressing concerns with performance implications of JSF state saving.

[2009-05-11] JSF Nonsenses – Matthias Hryniszak starts an entire blog at http://ihatejsf.com dedicated to documenting his struggles with JSF. In his first post, he says:

Welcome to this new place in virtual space where you can express your darkest feelings about the sole nature of JSF (Java Server Faces) and other technologies that are connected to it (Facelets, JSF libraries and the like).

This blog has arose from the need to express my personal dislike for that glorious set of utilities that have made my life a misery.

[2009-05-12] JSF 2 fu, Part 1: Streamline Web application development – IBM developerworks article on the spanking new JSF 2.0. In the beginning of the article, David Geary (JSF EG member) admits that JSF 1.0 wasn’t that great. It is worth mentioning that JSF 2.0 is still not yet approved at the time of this blog post! Quote:

JSF 1 was developed in an ivory tower, and the results, arguably, were less than spectacular.

[2009-05-15] JSF Sucks (Compendium of JSF rants/reviews) – link to this blog post on DZone where there is some active discussion and also do consider voting up this link! The number and ratio of upvotes speaks for itself.

[2009-05-15] Reasons why not use JSF – someone posted a link to this blog post on the Seam forums, some discussion there. Look out for the comments from Francisco Peredo, for example this one.

[2009-05-16] “JSF sucks” on Reddit – wow, that brought a lot of traffic! Some good discussion there as well.

Update 1:

[2009-07-27] U, I and JSF – still painful after all these years – detailed article by Karl Banke. His conclusion:

[..] it is not a proper component framework, let alone a complete one. It is intrinsically over engineered, yet critically underspecified. As such, it can serve as a powerful basis for a real component framework. Because of the critical parts missing it is essentially impossible to mix JSF components from various providers without including a lot of overhead and loosing a lot of consistency. Frameworks like JSF should essentially make easy things easy and hard things possible. Yet JSF’s standard components, even in JSF 2.0, fail to deliver basic One-O-One web application features from 10 years ago. It is a remarkably complex specification that delivers pretty much nothing out of the box.

[2009-11-10] JSF 2 – evaluation and test – very detailed evaluation of the brand new JSF 2.0 reference implementation (Mojarra) by Sebastian Hennebrueder and Holger Brade. Sebastian’s conclusion:

JSF looks like an old castle, where every generation added pieces, towers and buildings. I don’t blame the developers for this, as the code shows, that they know how to do a proper job. I believe that the reason for the current status of JSF is that the features are defined by a specification. The specification is industry driven with a focus on being backward compatible instead of being technology driven. Everything works somehow but always rather complex than simple. Every release makes it worse as nothing is dropped. I am sorry, but I can only see a bad ending for such a strategy.

Pages are extremely verbose. Using it make you feel being unproductive most of the time. JSF 2 brings some innovation but in a lot of areas it doesn’t even catch up with the current status of other frameworks. It is likely to be outdated before it is actually stable.

I wouldn’t use it for new projects and especially not for large enterprise projects.

[2010-01-29] What’s new in Alfresco Enterprise 3.2? – some insights into why popular open-source ECM vendor Alfresco is dropping JSF in favor of a more Web 2.0 oriented approach:

Alfresco has been fairly open with the fact that their ‘Explorer’ client which is based on JSF technology is no longer being actively developed. While JSF is still around and actively used at a lot of places, it is a ‘heavier’ technology compared to a lot of whiz-bang Web 2.0 stuff. Alfresco is now investing development cycles in Alfresco Share.

Update 2:

[2010-09-09] RichFaces 4.0.0 Release Plan Updated – the long awaited release of RichFaces 4.0 final (which is supposed to support JSF 2.0) is further delayed to Feb 2011 because of “issues in the JSF specification”. Note that as of September 2010, only ONE production ready JSF 2.0 component library exists. The JSF 2.0 spec was approved well over a year back (May 2009) and was available in a draft form much earlier as is typical in the JCP.

We had hoped to get the final release of 4.0 out before the end of the year, but as mentioned previously we have run into various hurdles: These include identifying issues in the JSF 2 specification, and implementations (JSF RI, MyFaces).

[2010-10-16] RE: Moving from Spring to Java EE 6: The Age of Frameworks is Over – Matt Raible’s observations on “standards” vs frameworks:

Another reason I don’t like JSF: there’s very few developers in the wild happy with it. The major promoters of JSF are book authors, trainers, Java EE Vendors and MyFaces developers. Whenever I speak at conferences, I ask folks to raise their hands for the various web frameworks they’re using. I always ask the JSF users to keep their hands up if they like it. Rarely do they stay up.

Update 3:

[2010-10-22] Java EE, Spring, and why I care – a rant on Java EE vendor FUD by Papick G. Taboada:

Take a look at JSF. JSF is obligatory part of a full stack application server, but JSF gives you nothing. Again, you have a component model, and each vendor will provide the required runtime API. But you won‘t be happy with that, you will need a JSF library like RichFaces, ICEFaces, PrimeFaces, MyFaces, etc.
Take a good look at those. You will realize that, once you start using JSF, you are not standard anymore, you are bound to the JSF library vendor. The programming models for the components are different, the tags have different name. Switching or mixing JSF library ranges from very hard to impossible. So what good is the JSF standard for? Why is RichFaces for JSF 2.0 taking so long and how many people are developing it? Will it be there tomorrow? Will it be continued? JSF surely, but RichFaces, ICEFaces? Who can assure that?

[2010-10-26] JSF Expert Group Disbanded With No Successor JSR – pretty damning when folks outside of Sun / Oracle who have been trying heroically to fix JSF and rally the community – say that they have almost given up. If you thought that the JSF spec would get any better in terms of reducing the need for vendor-specific and proprietary extensions, think again.

According to Balunas, the expert group was still very active in their communication and development, and he doesn’t believe that dissolution of the group was necessary. He says that it will now be “very difficult” to continue supporting the Java Server Faces specification without an official JSF and EG in the JCP, mainly because there are no longer intellectual property and governance guarantees involved in JSF development if there is no current or successor JSR for JSF.

Update 4:

[2010-11-18] “I hate JSF with a passion” – James Gosling speaking at a Silicon Valley JUG event, skip to 47 minutes into the video below or use this direct link: http://www.youtube.com/watch?v=9ei-rbULWoA#t=47m

I hate JSF with a passion. And JSF was done, you know, there are a few things that were done for, I don’t know whether they were stupid reasons, they’re just, it’s just the way the world is, so, Microsoft had this thing called ASF which was angle brackets and percent signs with BASIC code there, then they are [gestures] “in-between”, right, and they go on a marketing campaign saying, “this is the greatest thing since sliced bread”, they get all the journalists to go, “ohh, that’s the greatest thing since sliced bread”, they come to us and they say, “ooh, angle brackets and percent signs and code in between, isn’t that the greatest thing since sliced bread?” What’s your answer to that? And if your answer is “that’s stupid – you know, there’s a better way to do that”, the press by and large can’t parse your sentences. And so we did do JSF as basically a clone to ASF just because it was easier to explain to the press. And then it wouldn’t die.

How to start and stop Jetty – revisited

I mentioned in my previous post that I would blog about some of the things I learnt while putting together the Seam / JSF versus Wicket “perfbench“.

A while back I posted about how to start and stop Jetty from Ant – useful for those using the Jetty downloaded distribution. In this post I show how to cleanly shutdown a Jetty instance started in “embedded” mode. This tip may be useful for those using Jetty in a continuous integration build – for e.g. when Selenium tests are involved.

Info on starting an embedded Jetty instance is out there but I was not able to find ways to cleanly shutdown – other than hacks like this.

Update 2009-04-07: just found a blog post by Stephen Haberman that has a detailed explanation of WAR-less Development with Jetty

Here’s the code to start Jetty. The trick is to spawn a thread with a socket listening on another port (8079 in this case) that we can connect to later:

package mypackage;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

public class Start {

    private static Server server;

	public static void main(String[] args) throws Exception {
		server = new Server();
		SocketConnector connector = new SocketConnector();
		connector.setPort(8080);
		server.setConnectors(new Connector[] { connector });
		WebAppContext context = new WebAppContext();
		context.setServer(server);
		context.setContextPath("/wicket-jpa");
		context.setWar("src/main/webapp");
		server.addHandler(context);
        Thread monitor = new MonitorThread();
        monitor.start();
        server.start();
        server.join();
	}

    private static class MonitorThread extends Thread {

        private ServerSocket socket;

        public MonitorThread() {
            setDaemon(true);
            setName("StopMonitor");
            try {
                socket = new ServerSocket(8079, 1, InetAddress.getByName("127.0.0.1"));
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public void run() {
            System.out.println("*** running jetty 'stop' thread");
            Socket accept;
            try {
                accept = socket.accept();
                BufferedReader reader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
                reader.readLine();
                System.out.println("*** stopping jetty embedded server");
                server.stop();
                accept.close();
                socket.close();
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

}

The "MonitorThread" in the inner class above stops the embedded Jetty server if a line feed is received. So the code to stop Jetty is pretty simple. Here we duly send "\r\n" to port 8079:

package mypackage;

import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class Stop {

    public static void main(String[] args) throws Exception {
        Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 8079);
        OutputStream out = s.getOutputStream();
        System.out.println("*** sending jetty stop request");
        out.write(("\r\n").getBytes());
        out.flush();
        s.close();
    }
    
}

So how does one use this from Ant? Easy !

<target name="jetty-cycle">               
    <parallel>
        <java classname="mypackage.Start" classpathref="test.classpath" fork="true"/>
        <sequential>
            <waitfor>
                <socket server="127.0.0.1" port="8080"/>
            </waitfor>                
            <antcall target="my-tests"/>                            
            <java classname="mypackage.Stop" classpathref="test.classpath"/>                 
        </sequential>
    </parallel>
</target> 

Full disclosure: I adapted the approach from the Jetty code you can find over here ;)

Seam / JSF vs Wicket: performance comparison

A while after Seam support for Apache Wicket was announced, I downloaded Seam and took a look at the Wicket example. Then an idea struck – how about doing a performance comparison – I mean, here was the very same application implemented in JSF and Wicket – right? So I decided to write a JMeter script for both the JSF and Wicket versions of the Seam “hotel booking” example and compare results. I started right away but very soon got tired of waiting for app-server re-starts on my trusty laptop (Jetty has really spoiled me) – and it kind of bothered me that the Seam examples were not in Maven 2 layout. Anyway, at some point I decided to re-write an “EJB-free” version of the Seam booking example using just Wicket and JPA. And use Maven and Jetty. And… one thing led to another – and what I ended up doing is this:

  • Adapted the Seam JPA example (the one that does not use EJB) as the baseline application. Converted it into a Maven 2 WAR project which can run on Jetty.
  • Implemented what I hope is the exact equivalent of the above using only Wicket and JPA, also Maven-ized and Jetty-fied. Decided to also experiment with some of the ideas in this blog post.
  • Wrote a JMeter script for both applications taking care to exercise identical functionality.
  • Used an Ant script to run the JMeter scripts in batch mode (passing number of concurrent users as a parameter) and start / stop Jetty in sync.
  • Automated the entire cycle of running the load test for 1, 5, 10, 15 and 20 concurrent users including some code to parse the JMeter logs and generate a CSV file of tabular results.
  • Also included an Ant target that takes a JVM heap dump at the end of the load test – just before the users are logged out and the HTTP sessions killed.

I was able to re-use the official Seam Wicket example to some extent, mainly the HTML files – but the Java side is almost completely re-written. The Seam booking example covers quite a bit of ground from the framework comparison point of view – for example:

  • Security – some pages are secured and redirect to a login page
  • Templating – some pages inherit from a common layout with a header / footer defined
  • Ajax
    • hotel search results refresh as you type and a “busy” image is shown during the Ajax request
    • form field validations occur as soon as the field loses focus
  • Session scope – some state is stored and retrieved in the session
  • Page navigation / state
    • user navigation state transparently managed by the framework
    • user should be able to work in multiple concurrent conversations (browser tabs)
    • the browser back button should work as expected
  • JPA – getting access to the entity manager and transaction management
  • Forms – binding, validation and displaying error / info feedback to the user
  • Hibernate Validator – annotations on the JPA entity classes are re-used for form-validation

Both sides use the exact same entities, persistence.xml and initial HSQLDB import. I’m using the latest Seam 2.1.1-GA and Wicket 1.3.5. Disclaimer: my Wicket code may not be ideal, and I’ve also experimented with a custom RequestCycle for JPA and tried to use inherited models as far as possible. Instructions on how you can download the source and run the scripts on your local machine are at the end of this blog post.

I may do some follow up blog posts on how the code compares between the Seam / JSF and Wicket implementations, and also share some tips on writing JMeter scripts and automation using Jetty, Ant etc. I’m also expecting to have to make corrections and changes to the code based on feedback. For now, I’ll summarize my observations on performance and memory usage.

Performance:
In the JMeter script, except for the login and logout (first two rows and last row), the actions are executed in a loop ten times for each concurrent user. So if the number of concurrent users is 20, the login and logout actions happen 20 times and the rest 20 x 10 times. The numbers below are average page response time in milliseconds.

performance2

Wicket appears to be faster by a wide margin. For two pages (“ajax post search” and “post confirm booking”) the results are a bit closer. This can possibly be explained by the fact that these particular actions display the results from a relatively expensive database query. My amateur profiling attempts suggest that the database query is taking most of the time here.

One thing I have to mention: the “cc number” and “cc name” requests are simulations of the Ajax validations of the credit card number and name fields on the booking form. For these particular requests on the JSF side, the entire form is being POST-ed instead of just the value of the form field being validated when the user tabs out (onblur). So the difference here is quite dramatic. I did try adding ajaxSingle=”true” in the JSF view but it did not appear to work (I used HttpFox while building the JMeter scripts). I can re-post the updated results if someone lets me know what changes need to be made to “book.xhtml” to get the Ajax validation to work as expected.

Memory Usage:
The JMeter script can be told to skip the logout page and I wired up one of the Ant targets to take a JVM heap dump / snapshot as soon as the JMeter script completes. So I can compare what the heap looks like just after a load test when all the concurrent HTTP sessions are alive.

I’m very much a NetBeans user but I have to say that the Eclipse Memory Analyzer is far better than what the built-in NetBeans Profiler offers for looking at JVM heap dumps. Here are some side-by-side screenshots of the heap analysis after running the JMeter script for 20 concurrent users.

“Top Consumers” report below showing the classes that dominate memory usage:

top-consumers2

The “dominator tree” report below is very useful to see which objects hold on to the most memory directly as well as indirectly. The column headings after “Class name” are Shallow Heap, Retained Heap and Percentage. Shallow Heap means the memory consumed by a single object and Retained Heap is the sum of shallow sizes of all objects that will be garbage collected if the given object is garbage collected.

dominator-tree

Looking at the above two reports we can infer that on the Seam / JSF side, the 20 sessions each take up about 800 KB adding up to around 16 MB total. On the Wicket side the 20 sessions add up to around 1.5 MB. On the Wicket side it is the DiskPageStore that appears to hold the most memory and we can see what is going on here after drilling down a little:

diskpagestore2

The Wicket DiskPageStore uses SoftReference-s to serialized pages so the memory will be reclaimed by the JVM if needed. And the SerializedPageWithSession holds a WeakReference to the actual page instance (MainPage). You can also spot the byte-array which is the result of page serialization. If a serialized page is requested (perhaps the user hit the browser back-button) and the page is no longer in memory because the SoftReference has been GC-ed – it will be restored from the temp file that the DiskPageStore has been saving pages to.

I’m totally impressed by the Eclipse Memory Analyzer. Here we can see the break-up of the contents of the largest HTTP session on both sides. I think we can safely blame JSF for the lion’s share of memory usage on the left:

session-dominators

Finally, a summary of the heap-dump comparison (for 20 users) collated from the various reports:

heap-summary

Instructions:

Prerequisites:

  • JDK 1.5 or greater installed
  • Apache Ant installed
  • JMeter 2.X available unzipped somewhere (better use latest 2.3.2)

Steps:

  • Do a Subversion check out of the source from here: http://perfbench.googlecode.com/svn/trunk/perfbench/
  • Create a perfbench/build.properties file that points to your JMeter installation. You can look at the comment in perfbench/build.xml for an example.
  • Open a command prompt, change directory to perfbench/seam-jpa
  • If running for the first time, use the command “ant jmeter-cycle”. The build script would prompt for the number of threads, so enter “1”. It may take time for all the required JAR files to get downloaded. Once you see Jetty start and stop successfully, you should be all set to run the actual benchmark.
  • To start the benchmark run “ant jmeter-cycle-full”. This should take 2 – 3 minutes to run a series of tests for 1, 5, 10, 15 and 20 concurrent users. Results will be dumped into perfbench/target. You can look at the *.csv file at the end for the results.
  • You can also run a load test which saves a snapshot of the heap dump towards the end by running “ant jmeter-cycle-heapdump”.
  • Repeat the previous 3 steps after changing working directory to perfbench/wicket-jpa

Update: perfbench/build.xml starts Jetty with JVM options “-Xms64m -Xmx64m” and you may need to change this if you want to experiment with more concurrent users.

Wicket and GWT compared with code

I have been using Wicket for a while now and I’ve occasionally wondered if GWT provides any kind of advantage over Wicket. Recently I got a chance to do a comparison and instead of coding a simple “Hello World” kind of example, I decided to try something a little more complex. Hopefully this brings out the differences between Wicket and GWT more clearly.

Functionality

The target functionality is a one-page application that shows data in a single table. Item counts are displayed categorized under multiple “spaces” (workspaces). There is a summary row. The user can click on a space to expand the count of items grouped by status. The screenshots below show how the table looks when fully collapsed and then when one or more spaces are expanded.

It may look simple, but some of the tricky parts are:

  • The number and names of the possible status types can be different for different spaces. For example, the first space above has 3 status types and the second 2. This means that we can’t use different columns to group this data. Multiple rows are used instead to display the break-up when expanded.
  • Some of the table cells have to be merged to represent the grouping by space and then by status. In HTML terms, this requires some careful control of TD “colspan” and “rowspan” attributes.
  • In addition to the cell merging described above, the style / color of the different cells has to be controlled to differentiate the total count from that grouped by status. For example, the grand total on the last row is in bold. In HTML terms, this requires control over the CSS “class” attribute, coordinated with a style-sheet.

First, let us look at the Java code common to the GWT and Wicket implementations.

The “Space” Domain Object

The class above represents a “space” and it internally uses a Map to hold status names and corresponding counts. There is a method that calculates the total count, a getter for the space name and list of states, and helper methods to add and get status data.

DashrService.java

As the functionality is kind of a ‘dashboard’ view – and inspired by the “Cheesr” example that the Wicket In Action book uses, I decided to call this application “Dashr”. “DashrService.java” is a singleton that returns a list of spaces with dummy data. The relevant code is shown below:

So on to the comparison then. In the side-by-side layouts below, GWT is on the left and Wicket is on the right.

Project Structure

Although it is not really a domain class, “DashrService.java” has been kept in the “domain” package along with “Space.java” to keep things simple.

On the GWT side, the recommended package structure and naming conventions (“client”, “public”, etc.) are being used. Our example is a pure client-side application and server-side communication or RPC is not being used at all. All the client-side code and behavior is in “DashrEntryPoint.java” itself. “Dashr.html” simply serves as a placeholder for the rendered application.

It may first appear that Wicket requires more files than GWT but one difference is that the GWT code is not communicating with any server-side functionality at all. Wicket would feel more natural to Java web-app developers familiar with web.xml and the like, and integrating additional server side code or frameworks such as Spring or Hibernate would be much more straightforward.

Another thing is that the Wicket application has been modularized into multiple Java components and corresponding HTML files. It was not really possible to do something similar for the GWT application which has all the UI code in a single file. The reasons for this difference will become clear when we look at the code in detail.

Framework Configuration

GWT needs to be told where to find the Java classes that have to be converted into JavaScript. If this path is not explicitly set using an XML element called “source” it defaults to “client” – which is the GWT recommended convention. Our main module config file “Dashr.gwt.xml” does not have the source path declared. So this means that all the Java code in the directory “dashr/gwt/client” (and any sub-directories) will be processed by the GWT Java to JavaScript compiler.

Since “Space.java” and “DashrService.java” are dependencies for our GWT based UI code, we need to ensure that they are included in the Java to JavaScript conversion as well. So in addition to the “User” core framework module that all GWT apps must inherit, we have a reference to a custom module – “dashr.domain.DashrDomain”. “DashrDomain.gwt.xml” declares the source path to be an empty string which in relative-path terms works out to be the same folder the XML file is in – and this is how the “dashr/domain” directory is included for our example. Those who intend to use GWT to connect to server-side Java code would need to do something like this – i.e. include all dependencies needed by UI code, typically domain objects that happen to already exist – like in our example.

The UI class that acts as the “entry point” has to be configured for a GWT application. In our example we have only one UI class and this itself will be the entry point.

One more thing the main GWT config does is declare “Dashr.css” as the CSS file for our application. A GWT convention-over-configuration rule applies here as well which is that resources like CSS files and images are looked for in the “public” folder relative to the XML file by default.

For Wicket, there is no XML configuration but an “application” class that can hold configuration in Java code. The web.xml file is not really Wicket configuration but it is shown above for completeness and it names the Wicket “application” class used by the framework servlet / filter. In our example, “DashrApplication.java” is just pointing to the designated “home page”. Our home page is “DashrPage.java” for which the HTML markup is in “DashrPage.html”. The Wicket “home page” can be considered equivalent to the GWT “entry point”.

UI Implementation

Because of the differences between GWT and Wicket – the code below does not really line up side by side. To make it easier to see how the code compares – some key sections from the GWT side have been mapped to the Wicket side using blue arrows. I have not mapped every possible thing because then the picture would be out of control! You can click on the picture to view a bigger version

Observations:

  1. Wicket gives you complete control over the HTML. To render a table we use a “ListView” repeater control [DashrPage.java:18] which manipulates a <TR> section. In the case of GWT however, we have to use an abstraction over an HTML table either HTMLTable or FlexTable. Since we require control over the table “colspan” and “rowspan” attributes, we have to use the GWT “FlexTable” as the basic “HTMLTable” does not support this. What I experienced is that having to use the GWT API to output HTML limits you in certain ways, for example on the Wicket side I was able to freely include <TH> cells with <TD> cells but within the GWT table I could not mix <TH> cells. This may explain why the GWT “Dashr.css” file has an extra CSS class called “header” defined to compensate.
  2. Using Wicket’s built-in Ajax support, getting the expand / collapse functionality to work was very easy. It was a simple matter of replacing one (or more) rows of the HTML table over Ajax [RowCollapsedPanel.java:19, RowExpandedPanel:29]. Trying to do the same thing using GWT turned out to be quite a puzzle-solving exercise. To dynamically add or remove rows on a GWT table you have to know the row index and in our case the number of rows in the table changes dynamically. I ended up using a HashMap [DashrEntryPoint.java:21] to track the table row for each Space. This explains the mysterious code you see at lines 98 and 124 in DashrEntryPoint.java to update the Map when the table is changed.
  3. To dynamically set the contents of a table cell in GWT, you have to explicitly get a reference to the cell using the row-index and column-index. But in Wicket it is very easy to add or replace text as long as you know the wicket:id of the HTML element and it works fine for <TD> as well.
  4. One of the biggest problems I found with GWT is the poor separation of concerns. You can see a lot of code in DashrEntryPoint.java doing CSS styling on the HTML table and cells, for e.g. the calls to getRowFormatter() and getCellFormatter(). GWT does allow you to use a standard CSS file but you have to programmatically set the styles on your widgets in Java code. You can see for example how lines 42-43 in DashrEntryPoint.java map cleanly to markup and code on the Wicket side. The Wicket implementation does not have any CSS mixed in the Java code at all – it is all in the HTML where it belongs, and where web-designers can work freely. Most GWT widgets make use of pre-defined CSS names so this may not be a big problem for simple applications, but the web-designer would still need to know which CSS class names to use.
  5. This example only has a single widget on one page, but when you place multiple widgets on a screen, you have to think in terms of layout managers just like Swing. I have not gone into what GWT provides in detail but it looks suspiciously like the days of struggling with GridBagLayout :) I prefer the much simpler and effective Wicket approach of managing layout using standard HTML and I personally feel that web-designers need to be able to work directly with the HTML (and CSS) and have better control over things like cross-browser rendering quirks.
  6. On the GWT side Dashr.html is just a placeholder for all the JavaScript stuff that will happen at run-time. So when testing or debugging, if you do “view source” you see nothing, just the skeletal Dashr.html! This was a real pain when I was trying to tweak things like the CSS styling by trial and error. Especially when you are using hosted mode you can say goodbye to things like the web developer FireFox extension. When it comes to Wicket, you are dealing with a “normal” web-app and being able to look at the rendered HTML or DOM at any time is something you take for granted.
  7. One of Wicket’s strong points is that you can take chunks of HTML and model them as reusable panels. This makes the code modular and easier to read and it is obvious what the intent of “RowCollapsedPanel” and “RowExpandedPanel” is. Maybe with some more thinking and effort on the GWT side I could have had the inner classes ExpandClickListener and CollapseClickListener in separate files. But the code in the “onClick” event handlers is tightly coupled to the “table” and “spaceRowMap” properties of the enclosing class. I considered passing these as parameters in the constructor but decided it wasn’t worth the extra complexity and that the readability of the GWT code would reduce even more.
  8. The big difference between GWT and Wicket is of course that at run-time, all the GWT code becomes JavaScript and executes on the client browser. This may require the developer to think a little more about the implications of certain design choices. For example on lines 51 and 83 of DashrEntryPoint.java, a new instance of a ClickListener is being instantiated for each Space. On the server side, I wouldn’t think twice about dynamically instantiating many objects to render a page but in GWT I would have to start thinking about the impact this would have especially when everything ultimately becomes client-side JavaScript. The GWT tutorial also has some recommendations regarding this.
  9. The GWT host HTML page Dashr.html contains a hidden IFRAME to support use of the browser back-button. To be able to use this feature properly requires some extra effort as detailed in this page of the GWT documentation. I did not spend time trying to understand this and I simply used null for the “state token” on lines 50 and 82 of DashrEntryPoint.java. The Wicket application transparently supports the browser back-button. If you really need bookmarkable URLs, you then need to do some extra work in Wicket just like you have to do in GWT.
  10. The conversion to JavaScript takes more time than normal Java compilation. I found a mention of a real-life project experiencing GWT compile times of up to 18 minutes.
  11. On a more positive note, I used the latest GWT 1.5 and whatever little Java 5 features I used (generics, enhanced for loop) worked fine. You still need to be aware of some gotchas though.
  12. The GWT code does not communicate with the server at all which can indeed be considered one of the advantages of GWT because of performance. But it depends. What if I really wanted the data to come from the server? Then I would need to understand how to make server calls and perhaps even GWT serialization. The “Dashr” requirement is not something I cooked up and I am using something similar in an actual project. In the real-life requirement when a Space is expanded, the data has to come from the server (over Ajax) because it is an expensive “count (*)” kind of query in the database. In other words, the expanded data for all spaces cannot be loaded upfront in one go. Handling this kind of stuff in Wicket comes naturally, you *are* on the server all the time. And if you use Hibernate you have to be aware of certain issues with GWT. I hope to expand this example with RPC into another blog post soon and also explain why I think concepts like SOFEA have drawbacks that need to be taken into consideration.
  13. A few other points worth noting that are not addressed in the example, I personally find GWT’s approach to JavaScript integration, unit testing and especially internationalization more complicated than Wicket.

Overall, a perception of GWT I couldn’t get rid of while working with it is that it feels like a hack – but of course, a very well engineered hack. Maybe if you really have a lot of stuff you want to do on only the client side, it is fine. From the perspective of someone used to Java server-side programming, there are too many things about the unique approach that leak through – not being able to do “view-source” and the added complexity of RPC being some of them. And for example here below is a screen-shot of what I get when I “compile” the GWT application into JavaScript:

It is quite weird to see a one-page application result in a bunch of files like this. There is one JavaScript file but even the HTML files contain almost nothing but JavaScript. All the JavaScript is mini-fied and heavily obfuscated. I guess one can get used to it :P

You can’t do this using Adobe Flex!

I initially had an ambitious plan to include Adobe Flex and make this a three-way comparison. But as far as I can tell, there is simply no way to get the exact table grid behavior we require using Flex! Simple things like “rowspan” are simply out of the question. Some more recent Flex widgets like the Advanced Data Grid support grouping of data and expanding grouped items etc. – but come nowhere close to the requirement outlined at the beginning of this post.

I may have missed something, so do let me know in the comments.

Related previous blog post: A Wicket User Tries JSF – comparison of Wicket and JSF using a simpler example.

An alternative Maven plugin for Ant and NetBeans

A while back I wrote a custom Maven plugin to “escape” from Maven because I personally prefer Ant for build scripting. I now generally use Maven only for JAR file dependency management and my plugin acts as a bridge between the Maven and Ant worlds. The plugin can automatically generate an Ant build.xml file from the Maven pom.xml file and it supports web-application (WAR) projects. A few people aware of the existence of this ‘underground’ plugin have been asking me for more details, and since I got a chance to tweak things recently, I’m putting down some information in this blog post on how to get the plugin and try it out. Maybe you will find it useful.

Some of the features the plugin provides are:

  • Generated build file takes care of WAR packaging and deploying to Tomcat
  • Once generated, Ant build is independent of Maven and offline
  • Build file is IDE-independent, portable and includes targets for running JUnit tests as well

NetBeans users may find some of the advanced features interesting:

  • Generation of the following different types of NetBeans projects:
    • Java Free Form Project
    • NetBeans ‘native’ Java SE Project
    • NetBeans ‘native’ Java EE (web) project
  • The Ant build (for Free Form project mode) is simple, human-readable and easily customizable instead of the horribly complex “build-impl.xml” that NetBeans users are familiar with
  • In addition to the standard clean, compile, run actions etc., the generated Free Form project supports the following NetBeans-specific IDE-integration when a file is selected in the project explorer window:
    • run single file
    • debug single file
    • run JUnit test for single file
    • run JUnit test in debug mode for single file
    • debug web application
    • Hot Deploy single file into debug session

You just need the light-weight Java SE version of NetBeans in order to start and stop Tomcat, debug and even hot-deploy classes for your web-app. No extra plugins are required for e.g. Maven or Tomcat support. You can try this out for yourself by following the instructions below.

I’ll use the Wicket “quickstart” Maven Archetype as an example of how you can quickly get up and running using Ant on a Maven web-project. You need Maven 2 installed as a pre-requisite. The Wicket “quickstart” can be found here:

http://wicket.apache.org/quickstart.html

Open a command prompt, cut and paste the magic command and you get a simple web-application project along with a Maven POM definition, ideal for testing out the plugin features. This is the command I used for this example:

mvn archetype:create -DarchetypeGroupId=org.apache.wicket -DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=1.3.4 -DgroupId=com.mycompany -DartifactId=myproject

This will create a directory called "myproject" which contains a "pom.xml" file as well as some source code. We need to add a few lines to the pom.xml in order to use the custom plugin. First declare the repository for the plugin as follows by adding this snippet just above the <dependencies> section:

<pluginRepositories>
    <pluginRepository>
        <id>jtrac.info</id>
        <url>http://j-trac.sourceforge.net/repository</url>
    </pluginRepository>
</pluginRepositories>

And within the <plugins> section, just add these four lines:

<plugin>
    <groupId>info.jtrac</groupId>
    <artifactId>maven-antprops-plugin</artifactId>
</plugin>

That's all that needs to be added to the POM, just 10 lines that don't get in the way of any other Maven stuff you may want to do. To generate the Ant script, change to the newly created project folder and run the following command:

mvn antprops:generate

This will create a build.xml file and a "build-deps.properties" file. The properties file is a Plain Old Java Properties file that contains classpath information extracted from Maven as well as a list of dependencies with "runtime" scope which is used to create the "WEB-INF/lib" part of your WAR.

If you have Tomcat and Ant available on your system you can start Tomcat and deploy the WAR right away from the command line. But first you will need to point the build-file to where Tomcat is installed and this is a simple one-time matter of creating a "build.properties" file with a single line on it. Something like this:

tomcat.home=C:/peter/opt/apache-tomcat-6.0.14

From the command prompt, change to the "myproject" root directory (which should contain build.xml and build.properties by now) and type the following command:

ant tomcat-start-debug

Once Tomcat starts you should be able to verify that the app was successfully deployed by pointing your browser to: http://localhost:8080/myproject/

Eclipse users can use the "mvn eclipse:eclipse" command to open the project in Eclipse and start working with the Ant targets.

The command to create a NetBeans free-form project from the Maven POM is as follows:

mvn antprops:nbfreeform

This will create the "nbproject" folder and the NetBeans project file as well as an extra Ant script for NetBeans integration targets. Now you can open "myproject" as a NetBeans free-form project.

The "tomcat-start-debug" target is conveniently mapped to the NetBeans "run" IDE action, so just clicking on the big green "play" button should deploy the web-app running on Tomcat. If you right click on the project root "myproject" node, a "Stop Tomcat" context menu item should helpfully appear as well.

You can try the clean, compile, and war Ant targets etc. - which should work. The Wicket archetype includes a sample JUnit test also in "TestHomePage.java". After clicking on this file to select it within the NetBeans project explorer window - go to the Run --> Run File --> Test "TestHomePage.java" toolbar menu (or hit CTRL + F6) and you should be able to run only the selected test. But it will fail now with a "java.lang.NoClassDefFoundError: javax/servlet/ServletException".

This problem actually gives us a good example for demonstrating how the "build-deps.properties" file can be updated when dependencies change or are added to the POM. Now add the missing Servlet API dependency to the "pom.xml" file by adding this snippet within the <dependencies> section:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.4</version>
    <scope>provided</scope>
</dependency>

Then re-run the command to generate build-deps.properties. Note that this command is designed so that if a "build.xml" file already exists, it will not be over-written.

mvn antprops:generate

Now run the test case again from NetBeans and it should pass. Unit testing a UI component is easy with Wicket!

One of the neat things about the Wicket archetype is that it embeds a Jetty web-app server using a small Java class called "Start.java" lying in the "test" source structure. The POM is already set with the right dependencies for Jetty and so you can simply right-click on this Java file within the NetBeans project explorer and choose "Run". This will start a Jetty instance and deploy the WAR as well. You will be able to see the app running at http://localhost:8080/. Look ma, no Tomcat!

One more thing you can try is right-click on "Start.java" and do "Debug" instead of run. This will kick off a proper NetBeans debug session bringing up some sub-windows for viewing breakpoints, call stack etc. You can now try hot-deploying a single class without re-starting the app-server (Jetty). Try changing the text of the Label in HomePage.java to something else and saving the file. With the file selected in the NetBeans project window, look for the "Apply Code Changes" menu option - one place to find it is within the "Run" toolbar menu. A message should appear in the log saying that a class was reloaded. Refresh the browser and you should see the change in the text displayed.

Hot deploy should also work with Tomcat after initiating a debug-session (Attach Debugger) and then using the "Apply Code Changes" menu option.

The plugin is still experimental so if you find problems, do let me know in the comments. The commands for creating "native" NetBeans projects are "mvn antprops:nbjavase" and "mvn antprops:nbjavaee". You need NetBeans with Java EE support to try the second option.

The plugin also should make it possible to package a project along with dependencies and hand-off to someone without Maven or internet access - but I haven't completed this part yet.

A Wicket user tries JSF

A year or so back I attempted to learn JSF and even bought one of the recommended books. But after reading through the first hundred or so pages, I came to the conclusion that it was too complicated and un-intuitive. The code samples looked ugly to me in a way that was difficult to explain. The fact that there was a different expression language (with a ‘#’ instead of ‘$’) to get used to when I was just getting comfortable with JSP EL did not help either.

So I gave up trying to learn JSF and decided to concentrate on Spring MVC at that time.

Fast forward to today and the main trigger for my current experiments with JSF is because after my recent blog post on migrating from Spring MVC / WebFlow to Wicket, I am increasingly being asked whether I ever tried JSF.

So I have attempted to write a very simple application (based on MyFaces) and I will try to compare it side by side with the exact same functionality implemented in Wicket. I just started with JSF a couple of days back so feel free to comment and let me know if I missed something fundamental and I will update things either in this post or the next.

Functionality
This is supposed to be a “discussion forum” application and there is only one domain object called “Forum” with two String fields “name” and “description”. Maybe in the future I will include “Topic” and “Message” objects but for now I’m trying to keep things as simple as possible.

screens.png

There are only two screens. The home page is a list of Forum(s) in the system. There is a link to create a new Forum. This brings up the other screen which is a form with two text fields and a submit button. After a successful submission, you are taken back to the home page and the newly created Forum appears in the list.

Environment
NetBeans 5.5 is being used. I deploy to a Jetty instance that I set up manually because I want to also compare the Jetty “footprint” required for Wicket vs MyFaces. With some digging I’ve tried to arrive at the bare minimum “quickstart” config required, for example the web.xml file cannot be possibly smaller. I’m using Maven2 directory and naming conventions. Defaults are used as far as possible. In the side by side comparison images below JSF is on the left and Wicket is on the right.

So here goes:

Project Structure
project-structure.png

  • Wicket does not require any extra XML config like you have faces-config.xml for JSF
  • Wicket does not require JSPs
  • By default, Wicket expects the markup (*.html files) to be side by side with the *.java files corresponding to components – e.g. Page(s). Some people find this a bit odd but this keeps things simple and there are some very good reasons for this. You can change this convention if you really want to.
  • The MyFaces application requires an “index.jsp” welcome-file to redirect to the virtual home page URL

Jetty Footprint
jetty-footprint.png
Since Wicket does not require JSP support – the Jetty footprint is much smaller – the contents of the Jetty “lib” folder come down from 6.16 MB to 692 KB

Library Dependencies
dependencies.png
Even without using Tomahawk etc., MyFaces requires far more dependencies than Wicket i.e. 10 vs 4 JAR files

faces-config.xml
faces-config-xml.png
Wicket does not require any kind of XML configuration at all and the “faces-config.xml” file does not have any equivalent. Navigation logic is performed in pure Java code which is much more flexible and type-safe and you don’t need to synchronize multiple files.

web.xml
web-xml.png
A servlet filter handles all the framework stuff in Wicket. This has some advantages like you can map the root of your context path “/” to the home page. Anything not meant for the Wicket filter like images, css reources etc. will be ignored by the filter.

You need to tell Wicket where your “Application” class is located. This Application class is used primarily to point to the designated home page.

The Wicket Application Class
wicket-application-class.png
In a real life application, this is where you would manage references to the service-layer, configure security and various other things. Here we are just configuring the home page.

The “List Forums” Screen
forum-list-screen2.png

  • The wicket markup is pure HTML but the MyFaces JSP is a mixture of JSP, HTML, JSF tags and JSF EL
  • In the case of Wicket you can see that the complexity clearly moves out of the markup into the Java code. In the JSF version, the only thing the backing class is doing is setting up the model / list
  • You don’t need a specialized IDE to edit the Wicket version – HTML editing and Java editing support is sufficient. In the case of JSF you have to rely on IDE support when the UI gets complex
  • If you make a spelling mistake in the JSF EL expressions – you won’t know until run time – but the Java code that renders dynamic data in the Wicket version does not have that problem, you benefit from your IDE syntax coloring, refactoring suppport etc.
  • The JSF version is using a “dataTable” control. For Wicket we are using a ListView repeater control and creating a table manually. Even then, this is very simple code and you have much more control over the markup. The JSF dataTable documentation is not for the faint of heart and runs into a few pages. That is a lot of complexity you don’t need most of the time. BTW Wicket does provide a range of grid controls in the Wicket extensions project
  • Instead of navigation rules defined in faces-config.xml and the need to synchronize this with the action /event names you use in your JSP or backing class – in Wicket you can easily navigate from page to page by using the right “Link” components or setResponsePage()
  • Instead of using “id” which has a lot of significance in terms of (X)HTML – Wicket uses a namespace so “wicket:id” is the attribute you use to link your Java code and markup. Relying on the “id” attribute can lead to all kinds of unpleasant name collisions in JSF.

The “Create New Forum” Form
forum-form-screen3.png
In addition to the points in the previous section:

  • In JSF you declare and configure components in the markup and you have to use the right tags (e.g. h:form, h:inputText, h:commandButton) and the right attributes (e.g. to mark an input field as “required”). JSF is supposed to be a component oriented framework but I wouldn’t call them Java components and definitely not Object Oriented.
  • In Wicket you use normal HTML tags in the markup and in the Java code, you instantiate and attach the core components (e.g. TextField) or extend them as required (e.g. Form). All the behavior, and things like setting a field as “required” happen in pure Java code.
  • In this case for Wicket the value of the “wicket:id” attribute on the input text fields also serves as OGNL notation for HTML form –> POJO binding – which reduces the amount of configuration.
  • Rather than rely on a h:panelGrid to layout the form fields it is easier and more intuitive to use plain old HTML tables for this purpose.
  • The screenshot below demonstrates how the “ForumFormPage.html” file looks like when opened in a browser. Being valid HTML, Wicket markup files can be previewed and edited as such. Wicket provides for true separation of concerns and HTML screen design and layout can *really* be done by a team separate from the Java development team

browser-preview.png

Generated HTML
The HTML generated by MyFaces is unbelievably verbose and contains all kind of strange javascript which I never, ever would have expected. If there is one reason to stay away from MyFaces, this is it.

You can click on the links below to see the output. If your browser renders the HTML instead of displaying the raw text, just do “view source”.

For Wicket, the generated HTML is clean like you would expect. And note that the Wicket specific attributes like “wicket:id” will be stripped in PRODUCTION mode.


Update [2007-06-10]: Simplified the wicket code for the “Create New Forum” form after it dawned on me that the existing POJO is more than sufficient for form binding. The older version can be found here: forum-form-screen2.png

The Java code for the Wicket form page can be made even more tighter using an anonymous inner class for the form. This is a nice example of how Wicket gets you to exercise the Java OO parts of your brain, and it is worth comparing this with the “ForumFormPage.java” above.

Update: I uploaded the Java and HTML source for the 2 Wicket pages. Since WordPress has restrictions on uploads (no *.zip allowed for e.g.), you have to rename the files correctly if you download them – Forum List Page: HTML / Java | Forum Form Page: HTML / Java

Using JMeter RegEx for handling dynamic / generated URLs

I recently contributed a section to the Wicket wiki on how to use JMeter’s Regular Expression support to test Wicket applications. Some of it should be useful for anyone having to test web applications where the URLs for hyperlinks and form submissions are dynamically generated and known only at runtime. For example, I used this technique earlier for testing an app using Spring WebFlow – so I was able to grab the value of the “_flowExecutionKey” parameter, which is typically a hidden form field.

Link: Wicket and JMeter with Regular Expressions

Follow

Get every new post delivered to your Inbox.

Join 29 other followers