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

JTrac UI makeover

After migrating to Wicket I spent some time on the long pending UI makeover. And as expected, Wicket made tweaking the UI a lot easier. Here’s the obligatory before-and-after screenshot:

old-field-level-permissions.png

Ugh. What was I thinking. With that shady background image, the oh-so-retro html horizontal rule etc. – no wonder JTrac was pulled up by the style police :)

new-field-level-permissions.png

A few open-source icons and a cleaner color scheme can make a big difference.

The love-affair with Wicket is still going strong. If you are interested, you can have a look at the JSP source of the old screen and compare it with the new HTML one.

Being a somewhat complicated screen – this may be a good example. There is a fair amount of merging of table rows and columns, and a large number of submit buttons have to be handled. A bunch of javascript appears at the start of the JSP to make handling the submit buttons easier as well as a few hidden form fields at the end – all of which are gone in the Wicket version. Then there is lots and lots of JSTL – sprinklings of c:if, c:choose etc and a staggering amount of nesting in the c:forEach loops – all crying out to be done in pure Java instead.

It is worth pointing out the significant amount of logic in the JSP – for example:

<c:when test="${stateRowEntry.key == 0 && stateColEntry.key != 1}">

And this part especially looks much better in the Wicket version because I could use constants:

if(stateKeyRow == State.NEW && stateKeyCol != State.OPEN) {.

The HTML is well – just plain old HTML with wicket:id attributes. As you can imagine – it was much easier to work with this and just plug the images into the right places.

If you are working with JSF or JSP – are you envying me yet? :P

Wicket Impressions, moving from Spring MVC / WebFlow

[update 2008-05-27: A detailed presentation that summarizes this blog post along with visuals and code snippets is now available]

For quite a while, I was trying to ignore the increasing buzz about Wicket, convincing myself that I don’t need yet another MVC framework (there are too many of them anyway), but somewhere between the Javalobby articles, the InfoQ article and the O’ReillyNet article – my resolve cracked and I took a closer look.

It looked interesting and so I decided to try and migrate a selected few JSP screens of an existing Spring MVC + Spring WebFlow application to Wicket. This went much better than I expected and two months later (not full time) – I completed migrating the entire app to Wicket and it is now ready for a new release as a 100% JSP free application. I’m now trying to convince my colleagues to try Wicket and they give me strange looks because I was an outspoken Spring MVC / WebFlow fan not so long ago : )

So is Wicket the one true MVC framework that a lot of us have been hunting for? At the moment, I tend to think so. Of course I have not tried GWT, Tapestry, RIFE, Stripes, JSF, Seam, Echo2 and the other usual suspects. And how is Wicket better than Spring MVC and Spring WebFlow? Having used both, I will attempt to elaborate below.

[update1: I tried JSF, and you can read my comparison of Wicket with JSF]

[update2: I also tried GWT and here is my comparison of Wicket vs GWT]

[update3: Detailed performance & memory usage comparison of Wicket with Seam / JSF]

Lots of information is already available on Wicket and how it compares with other frameworks in general, so here I will try to focus on what I experienced when I moved from JSP + SMVC + SWF to Wicket. The way I had to throw some of my pre-conceived notions about Java web-app development out of the window may be of interest to you. This is not a very structured list, but I’ve been meaning to put down these first-hand Wicket impressions for a while, so here goes:

Pure Java
If you like Java you will really like Wicket. Over the last two months, I was surprised to learn a few Java-isms that I was not aware of – such as some subtleties when using anonymous inner classes etc. To be really productive with Wicket I think that your Java fundamentals do need to be sound. But that is a good thing.

Great component model
The application that I migrated is a reasonably complex one, with a few CRUD screens, forms, search results etc – and Wicket offered almost everything I needed – and more. I was able to easily create a couple of custom components like:

  • a date picker (Wicket has one but I really wanted to write my own)
  • a variant of a multi-select check box where if there are pre-selected values, they “float” to the top of the list. It was very easy to create this by extending the Wicket multi-select checkbox.

Once you get used to components (even a web page is a component) as opposed to URL mappings and MVC actions, you can develop at a very fast clip. After experiencing the elegance of this kind programming model where you can show or hide components and control all this in pure Java code as opposed to hacking in JSP or JSTL, you really won’t feel like going back.

I used to hold the opinion that people new to Java who need to learn how to create web-applications could probably skip most of the Swing sections in the typical introductory course material and get straight on to Servlets and JSPs. Now I have completely reversed this thinking. Swing-style coding is the future for web-applications, I can feel it :)

In the old app I had written a custom JSP tag for the special multi-select checkbox list and was quite pleased with the result. I used to think that JSP tags were more than sufficient to create re-usable components and using Prototype directly was enough do fancy Ajax things etc. Now I have revised that opinion as well.

*Real* separation of concerns
Because the application I was developing had zero JSP scriptlets and strictly used JSTL, I was under the impression that I had reached nirvana in terms of separation-of-concerns.

Of course I was wrong again. In Wicket, all layout is controlled in good old HTML files. And Wicket has some neat-o ways to do markup-y things in the Java code itself – like for instance how you can color alternate rows when rendering an HTML table.

If you have a separate team doing the presentation look and feel work, they can truly work in isolation and their output can be used as-is. Although I don’t care about this at the moment (in my case, the UI designer and Java developer is the same guy), I’m sure that this is a big deal for most development shops. I am aware that Tapestry promises the same thing.

So this is a key difference from Swing where you have the concept of layout managers. As far as I know this is where frameworks like GWT and Echo2 are different from Wicket because they also have layout controlled in Java code. IMHO the Wicket approach is the right one because you get the separation of concerns advantage. And I personally like complete control of the markup. I mean, with all those silly cross-browser incompatibilities and the need to finely adjust spacing, padding, coloring and the like, this seems to be a good thing.

No JSPs
This is very nice because:

  • You can do things much more easily and efficiently in pure Java than in JSP and the limited syntax of JSTL. Ever had that nagging feeling that your JSPs were getting un-maintainable? Try Wicket!
  • You can refactor confidently and catch problems at compile time which are not possible with JSP. For example if in JSTL you were referring to a non-existent Javabean property, you may not know until the page renders.
  • Pages are no longer slow the first time you access them because there is no more JSP compilation step
  • in my case, the app embeds Jetty and now I don’t need the JSP jar dependencies any more. This cuts the Jetty footprint from about 7 MB (including Ant and the Eclipse Java compiler) to about 1.3 MB. I had tried JSP pre-compilation earlier but gave up because of differences in how Tomcat / Jasper does things vs the Glassfish JSP engine. Jetty + the web-app requires only a JRE to run if there are no JSPs.
  • A nice side-effect of using wicket is that your pages are guaranteed to be XHTML compliant

The downside is of course that you have to recompile a little more often than if you were using JSPs. Wicket does allow you to change the markup on the fly and refresh in debug mode. Also, Wicket provides out of the box, a very detailed error page with some nice syntax coloring telling you exactly where the problem lies in your markup or otherwise – which is very, very cool.

Re-usability
Ah, again, *really*. Re-usability in the JSP world is a custom tag or a hack-y include file.

I already mentioned how easy it is to extend (yes, extend as in the Java keyword) a Wicket component to customize how it behaves. And once you get the hang of the Wicket way of doing things and how to use anonymous inner classes to your advantage, life is good :)

So compared to doing things in JSP, it is far less work in Wicket to create a component that is truly re-usable, say across all the pages of your application. And unlike JSP tags, you get the full benefit of the Java OO features. Did I mention that the design of the whole Component class hierarchy in Wicket feels very nicely done?

Wicket also has a Panel concept where you can group custom markup + components and re-use the group as a single unit to your hearts content. IMHO you really don’t need any “tiles” kind of framework anymore, just create panels and instantiate them at will.

Templates for web pages
Something I really missed in the JSP world was the ability to have all pages have a consistent header and footer and I really hated having to add includes to all JSPs to achieve this. Not any more. Wicket has a brilliant markup inheritance concept that simply works.

Ajax
I’m guessing that this is the killer feature of Wicket. Control freak that I am, I was at first concerned that Wicket comes along with its own basic Ajax implementation, or in other words it provides a replacement for say Prototype or Dojo out of the box. I initially tried to use Prototype from Wicket and was pleasantly surprised when that proved really easy. Adding on Scriptaculous effects was no problem either.

But after trying the Ajax support in Wicket I was really impressed and soon decided to do away with all those *.js files lying around in my web-app. The very useful Ajax debug popup that automagically appears on your web pages in debug mode is one good reason to rely upon Wicket’s built in Ajax. Now I feel confident that I can implement any kind of fancy Ajax on my screens, so bring it on! One example that I tried and can mention here: it was very, very easy to create a page that runs a long running process in a separate thread and updates a progress indicator through Ajax every few seconds or so.

So using Ajax is as simple as telling Wicket that instead of showing or hiding a component using a full-page refresh, do that using Ajax partial-updates to a page. And it just works on any kind of component. And when you use Wicket’s Ajax features you typically never need to write a single line of Javascript.

I came across this quote that Ajax in Wicket is possibly better and much easier when compared to how you do it in Ruby on Rails, and I wouldn’t be surprised if this is true.

Form Binding and Validation
Spring MVC is extremely good at binding HTML forms to POJOs, (a far cry from Struts 1.X) -so can Wicket be any better? I really think so. Just like Spring MVC, as long as you have POJOs and you bind in terms of OGNL, you are fine. I was able to bind almost all of the POJOs that I was using in the earlier Spring MVC app to Wicket forms without any problem. Some things felt really cleaner – like how to have multiple submit buttons on a form.

When it comes to Form validation and displaying validation errors, there are so many options and great possibilities. By default, you can display errors in a section (feedback panel) at the top of the form. I was also able to create a Wicket “behavior” that would highlight the offending widget on the screen by applying a red CSS border around it. Lurking on the Wicket mailing list, I can see folks trying all kinds of cool things such as Ajax-ified feedback messages etc. The Wicket mailing list is a friendly source of help btw, and I got quick responses to all my newbie questions.

Other Neat Stuff
Wicket has some goodies and some of the ones that I ran into (there must be many more) were these:

  • File upload: After using Spring MVC where you have to choose say commons-fileupload and manually include the JAR, I was pleasantly surprised to see that Wicket supports multipart forms / file uploading out of the box.
  • File download: Wicket has a special “Link” class specifically for the purpose of downloading files. Wicket takes care of all the low-level details such as setting the right content-type for the browser – so you end up doing the Right Thing. You don’t need to deal directly with the HttpServletRequest or Response objects at all.
  • Buffered Image: I use JFreeChart and in the old app I had to hack around a bit to get a server-side created chart streamed into an IMG tag. Wicket has an Image component that works with a buffered image. Perfect!
  • URL Mounting: You can get those bookmarkable “friendly URLs” you want with this feature. I liked the support for “REST-ful” URLs out of the box: e.g: /foo/bar/param1/param2 – and how easy it was to use.

Security (Acegi) and Wicket
The old application was using the Acegi security framework. I started out retaining Acegi for authentication and co-existing with Wicket, which was easy. I soon realized that Wicket has a very simple authorization strategy and I was able to plug in custom code to check if a user is not logged in, redirect to a login a page etc. I was also able to easily handle an auto-login using a “remember-me” cookie.

An interesting thing from the security point of view is that the URLs that Wicket generates are inherently secure. In other words it is near-impossible to predict them as they are tightly tied to a user’s session. I came to the conclusion that simply programmatically hiding / unhiding links to secure pages based on the currently logged in user’s role would be sufficient for role-based access-control kind of security.

Acegi is very useful in a URL to MVC-action mapping situation because you can restrict URL patterns to roles – e.g. you can enforce URL wildcard rules like “/admin/**” can be viewed only by ROLE_ADMIN. I will probably continue to use Acegi for a planned remote REST/POX API to the app and for the LDAP and CAS support that it comes with etc. But I’m almost convinced that Acegi is overkill for a basic Wicket app. I am still going back and forth on this – so do let me know what you think.

Integration with Spring
This was easy. I was able to manage without the recommended wicket-spring integration JARs and went with a relatively simpler (and arguably less-elegant) approach – plucking the Spring context out of the ServletContext. In case you were wondering – I have so far used only the core wicket JAR and have not even used wicket-extensions. But I’m sure I’ll start using wicket-extensions soon, I can’t wait to try modal popup windows, the file-upload progress-indicator and the other cool stuff :)

Another example of how well thought out Wicket’s design comes across is that it took only a few lines of code to delegate to the Spring MessageSource instead of using Wicket’s default i18n. So I was able to use my existing resource bundles unchanged.

Integration with Hibernate
I use Spring on top of Hibernate and staying clear of the dreaded LazyInitializationException was as simple as adding the excellent Spring OpenSessionInViewFilter. Regarding GWT, from what I can make out, getting it to work with Hibernate may not be as easy because of the way it works. I would appreciate some comments confirming this, because this could be another key point to consider when you choose an MVC framework.

No Annotations Required
Yep, I’m one of those stubborn types who firmly believes that the only annotation that you should use is @Override. And as mentioned above I did not use the annotations based Spring integration. I bring this point up because from what I have heard – some of the other competing MVC frameworks rely a lot on annotations such as Tapestry, Stripes, RIFE, Seam etc. So if this really matters to you or if your environment is pre-JDK5.0, it could be another differentiating factor. Wicket already is famous for not needing any XML configuration at all. If the Wicket guys are reading this – I really appreciate that you have not forced users to use annotations and I sure hope Wicket stays that way!

WebFlow or Wicket
In the old app, I was using Spring WebFlow and was quite happy with it. So when I started out with Wicket, I was trying to figure out how I could integrate it with WebFlow. But as I understood Wicket more and more and things started to click in my mind, I realized that there is no way you can have them both – you have to choose one or the other.

I found WebFlow great because it allowed me to re-use subflows. So as an example if I had a use-case like “assign task to user” and the user did not exist, I could easily call the “create user” flow and then resume the original calling flow at the point where I branched out, you know – all that continuations stuff. But now my conclusion is that you can easily do all that – and more – with Wicket.

In Spring WebFlow, each view state in a flow is typically a JSP page. Which brings me to now think that it was not really designed to reuse anything more fine-grained than a JSP view – when interacting with a user. I already mentioned that Wicket allows you to reuse sections of HTML and group bunches of components into panels. So when you start trying to build more dynamic pages – I think Wicket wins. Navigating back and forth in Wicket really is child’s play, you just call or instantiate another page at will. You can even do tricks like holding a reference to a previous page, (a page is nothing but a good old Java component) so you can build any kind of complex kind of back-and-forth or wizard kind of navigation easily. I am aware that Wicket has a breadcrumb component and a wizard component but I have not tried them yet.

When it comes to Ajax, I really think Wicket is better than Spring WebFlow. Spring WebFlow is unquestionably a well designed framework, continuations and all, but sometimes I felt that certain things were constraining – for example you have to jump through a few hoops to access flow-scoped variables from outside a web-flow. When you use Ajax, you do need to do that kind of stuff a lot. In addition, in the Ajax world – you are invariably dealing with a section of a page – rather than the page in its entirety – and that is where IMHO the “page centric” nature of Spring WebFlow is a limitation.

A couple of other points, I did not use browser back-button support at all yet, but just from looking at the documentation, Wicket’s back-button support appears to be just as good, if not better. And nit-picking here – I don’t particularly like the huge UUID kind of URLs that SWF generates by default eg: /like?_flowExecutionKey=_c815540C2-03F1-39F8-19E9-D56FC0E377B7_k14D5E331-7B59-EA45-CF06-672C33FA2097
But Wicket is quite the opposite, with a “URL compressor” turned on by default.

End Note
Are there any points I have missed? Please feel free to comment and help me straighten out my thoughts on comparing some of these MVC frameworks. The migration was done on an open source app, so if you want me to pull out some “before and after” code samples, do let me know!

Afterthoughts [update 2007-03-03]
Triggered by the comments and also a few additional things that popped into my mind:

  • Unit Testability: I have not used this yet, but if this means a lot to you – Wicket has that covered. And before you look down on my lack of best practice :p let me hastily add that I use Watij, but not as much as I should have.
  • Custom Session: You can create a typesafe custom Session class and you never need to deal with the HttpSession at all.
  • Refactoring: It is worth repeating that because of no JSPs, no templating (like for e.g. Velocity) and no XML – refactoring of the Java code is simple within your plain old IDE and no special tooling is required. I can vouch for that, I am using NetBeans and have no extra modules (plugins) installed. Debugging, setting break-points and stepping-through plain old Java code is far more easier than trying to do the same thing with e.g. JSPs.
  • Simplified Stack: In my case I replaced [HTML + JS + Prototype + JSP/EL + JSTL + Spring MVC + Spring WebFlow] with [HTML + Wicket]. Also note that whether Acegi needs to be there or not is debatable.
  • Clean separation from Service Layer: This is somewhat specific to Seam and let me elaborate a little. I attended one of Gavin King’s Seam sessions recently and was a little taken aback (so were quite a few others) by the suggestion that the notion of a re-usable middle tier (service layer) is grossly over-rated, i.e. a) you normally never find yourself swapping out a layer, and b) a change in one layer always impacts the other, no matter how loosely coupled they are. Conclusion: so why bother, and you are better off merging all the layers into one. You know the feeling – like wtf, is this back to the monolithic JSP-directly-accessing-DB days!? Anyway – now I can stand up and testify that I was able to cleanly take out Spring MVC and replace with Wicket with only minimal changes to the service interface (mostly feature adds and minor refactoring). This is worth thinking over, and I also feel that a well defined Service Layer is easier to expose as an XML remote API, which I plan to do soon. Just my 2c, do comment!
Follow

Get every new post delivered to your Inbox.

Join 29 other followers