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:

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:


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


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 “” 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 “” file with a single line on it. Something like this:


From the command prompt, change to the “myproject” root directory (which should contain build.xml and 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 “”. After clicking on this file to select it within the NetBeans project explorer window – go to the Run –> Run File –> Test “” 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 “” 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:


Then re-run the command to generate 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 “” 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 “” 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 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.

Migrating to Apache Wicket – GIDS presentation slides

The ‘Migrating to Apache Wicket’ presentation I made at the Great Indian Developer Summit last week went off well. It was great to see the interest in Wicket, the room was full and there were quite a few questions even during the course of the session before I got to the end.

Here are the slides for your viewing pleasure. Apologies if some of the slides look cluttered because the animations I used to talk through some of the slides have been lost after converting to PDF.

Here below is one of the images I used to illustrate how a project that starts out using an action-oriented MVC framework with JSP can end up with a ‘Franken-stack’ over time. It starts innocently enough, you decide to use something extra say to enforce a common layout, then you realize you need some third party tag-libs, then security, and of course Ajax and before you know it…

What if a framework exists that can do all of this in Just Java and Just HTML? Find out more.

Hope you find the slides useful. I look forward to your feedback and suggestions on how the content can be improved. Please do comment!

How to record RTMP flash video streams using Red5

Update 2009-04-04: I’ve released an open source project that you can use to download RTMP video streams in a much simpler way. You can find it here:

Red5 is an open source Flash server written in Java. It does not include a standalone client yet but I was able to write a Java program that uses Red5 to connect to an RTMP video stream and record / save it to a file. Code is provided below and also some tips on how to get the details required to download flash videos that you come across on the internet.

Here’s the code of “”, you are free to use and modify this in any way you want.


import org.apache.mina.common.ByteBuffer;
import org.red5.server.api.event.IEvent;
import org.red5.server.api.event.IEventDispatcher;
import org.red5.server.api.service.IPendingServiceCall;
import org.red5.server.api.service.IPendingServiceCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyRtmpClient extends RTMPClient {

	private static final Logger logger = LoggerFactory.getLogger(MyRtmpClient.class);

	private String saveAsFileName = "test.flv";

	public static void main(String[] args) {

		String host = "localhost";
		String app = "oflaDemo";
		final String name = "IronMan.flv";
		int port = 1935;
		final int duration = 10000; // milliseconds, -2 means until end of stream

		final MyRtmpClient client = new MyRtmpClient();
		logger.debug("connecting, host: " + host + ", app: " + app + ", port: " + port);
		IPendingServiceCallback callback = new IPendingServiceCallback() {							
			public void resultReceived(IPendingServiceCall call) {
				logger.debug("service call result: " + call);
				if ("connect".equals(call.getServiceMethodName())) {					
				} else if ("createStream".equals(call.getServiceMethodName())) {													
					Integer streamId = (Integer) call.getResult();
					logger.debug("createStream result stream id: " + streamId);
					logger.debug("playing video by name: " + name);		, name, 0, duration);
		client.connect(host, port, app, callback);


	private RTMPConnection conn;	
	private ITagWriter writer;

	private int videoTs;
	private int audioTs;

	public void connectionOpened(RTMPConnection conn, RTMP state) {
		logger.debug("connection opened");
		super.connectionOpened(conn, state);
		this.conn = conn;

	public void connectionClosed(RTMPConnection conn, RTMP state) {
		logger.debug("connection closed");
		super.connectionClosed(conn, state);
		if (writer != null) {
			writer = null;

	public void createStream(IPendingServiceCallback callback) {
		logger.debug("create stream");
		IPendingServiceCallback wrapper = new CreateStreamCallBack(callback);
		invoke("createStream", null, wrapper);

	protected void onInvoke(RTMPConnection conn, Channel channel, Header header, Notify notify, RTMP rtmp) {
		super.onInvoke(conn, channel, header, notify, rtmp);		
		ObjectMap<String, String> map = (ObjectMap) notify.getCall().getArguments()[0];
		String code = map.get("code");
		if (StatusCodes.NS_PLAY_STOP.equals(code)) {
			logger.debug("onInvoke, code == NetStream.Play.Stop, disconnecting");

	private void init() {
		File file = new File(saveAsFileName);
		FLVService flvService = new FLVService();
		try {
			IStreamableFile flv = flvService.getStreamableFile(file);
			writer = flv.getWriter();
		} catch (Exception e) {
			throw new RuntimeException(e);

	private class CreateStreamCallBack implements IPendingServiceCallback {

		private IPendingServiceCallback wrapped;

		public CreateStreamCallBack(IPendingServiceCallback wrapped) {
			this.wrapped = wrapped;

		public void resultReceived(IPendingServiceCall call) {
			Integer streamIdInt = (Integer) call.getResult();
			if (conn != null && streamIdInt != null) {
				MyNetStream stream = new MyNetStream();


	private class MyNetStream extends AbstractClientStream implements IEventDispatcher {

		public void close() { }

		public void start() { }

		public void stop() { }

		public void dispatchEvent(IEvent event) {
			if (!(event instanceof IRTMPEvent)) {
				logger.debug("skipping non rtmp event: " + event);
			IRTMPEvent rtmpEvent = (IRTMPEvent) event;
			if (logger.isDebugEnabled()) {
				logger.debug("rtmp event: " + rtmpEvent.getHeader() + ", "
						+ rtmpEvent.getClass().getSimpleName());
			if (!(rtmpEvent instanceof IStreamData)) {
				logger.debug("skipping non stream data");
			if (rtmpEvent.getHeader().getSize() == 0) {
				logger.debug("skipping event where size == 0");
			ITag tag = new Tag();
			if (rtmpEvent instanceof VideoData) {				
				videoTs += rtmpEvent.getTimestamp();
			} else if (rtmpEvent instanceof AudioData) {
				audioTs += rtmpEvent.getTimestamp();
			ByteBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
			try {
			} catch (Exception e) {
				throw new RuntimeException(e);


To compile and run the code you need the following libraries:


We need the latest Red5 JAR built from version control (not the latest official release) and I have uploaded these files here: red5-rtmp-client-libszip.pdf – just rename the file to end with “.zip” after downloading.

The code shown is hard-coded to connect to “localhost”, app name “oflaDemo” and stream name “IronMan.flv” which can be tested on the official Red5 server distribution which you can download and run. When it comes to downloading flash streams from the internet, WireShark can be used to sniff out the values you need.

Let’s take this site for example: Start a WireShark capture session before clicking on a video on the site to play it. Let WireShark grab all the information exchanged between your PC and the remote flash server and you can stop the capture once the video begins to play, we are only interested in what goes on during the connection handshake. I will use this video as an example: [update Jun-2008: looks like they changed this particular video to Windows media instead of Flash, so try other videos or other sites]

In WireShark you can filter for protocol “rtmpt” and the first few entries would be handshake or “invoke” operations. Examining the “Handshake part 3” we can easily get the value of the required “app” property. Below we can see it is “video/2006/other/ff06/chomsky_noam”:

For the host name, the IP address should do fine for most sites, but we can easily figure out the host name of the stream server from what appears after “rtmp://”. Note that WireShark allows you to search the text contents of captured packets. Here below we can see that the host name is “”:

And finally when the “play” command is issued – we need the value of the stream name. Below we see it is “chomsky_noam_01”:

So with the right values of hostname, app and stream name set – you can run the program and download the stream to your local drive for offline viewing. To download the whole stream – just change the duration to ‘-2’ as hinted in the source code comment. There are many free Flash players available you can use to play downloaded content such as FLV Player.

Do let me know if this works for you and if you find any additional parameters that need to be passed for other sites.

Never install NetBeans again! (just use the ZIP)

Okay that title was just to grab your attention :) What I mean is that I’m going to show you how to use the NetBeans ZIP distribution on Windows so that you never need to use the installer executable again. If you are like me and would like total control over the folders that NetBeans uses, or if you hate installing things onto Windows because of all that stuff that gets added to the programs menu and your user profile folders and maybe your registry – you will probably like this approach. Now that NetBeans 6.1 release candidate
is out, this is a good way for you to try it out in an un-intrusive manner especially if you have an older version of NetBeans already installed.

Although most people use the platform specific installers, NetBeans can also be downloaded as a platform-independent ZIP file. You can get the various flavors here for 6.1 RC:

I am going to use the “javase” version which is just 50MB. I can’t help mentioning that two years back, one of the main reasons I switched to NetBeans was because I felt that Eclipse was getting too bloated for comfort. Never regretted it, and especially now that Apache Wicket is my web-framework of choice – the NetBeans “javase” version is just perfect because Wicket only needs HTML and Java editing support.

After downloading the file, in this case called “” extract it to any folder of your choice. Create a batch file (you can call it “netbeans.bat”) and place it in the top level “netbeans” folder itself with the following contents:


set JAVA_HOME=C:\peter\app\jdk1.6.0_02
set NETBEANS_USER_DIR=C:\peter\workspaces\netbeans

start /b %NETBEANS_HOME%\bin\netbeans.exe --jdkhome %JAVA_HOME% --userdir %NETBEANS_USER_DIR%

The first two lines are DOS hacks to obtain the path of the current directory (without a trailing slash) where you un-zipped NetBeans. You should point the JAVA_HOME to the JDK you wish to use. And finally, you can customize the folder where NetBeans saves your settings (which by default goes somewhere into your “Documents and Settings” folder). The “start /b” part is a way to make the console window “disappear” after NetBeans launches otherwise you may terminate it later and kill NetBeans by mistake.

That’s it! Now just double-click on the batch file and NetBeans will start and even create the “userdir” if it does not exist. I actually use NetBeans like this on a daily basis. It should be easy to evaluate NetBeans this way – you don’t have to go through any un-install step (in the unlikely event that you don’t like NetBeans :)

This is a nice way to control which JDK NetBeans uses, which is useful in case you have multiple JDKs installed. I use this approach for conducting training workshops where I provide a ZIP that includes NetBeans, a custom bundled JDK and a sample project – the batch file uses relative paths, just unzip and you are good to go.

If you have a NetBeans tip to share – enter the NetBeans blogging contest here:

Fibonacci spiral fun with Java3D

Recently I became fascinated with the Fibonacci series and the Golden Ratio, especially with how they turn up in nature. I had been meaning to explore the Java3D API for a while, so I thought it would be a good idea to try and generate some Fibonacci spirals and get to know Java3D that way. Here is one example of what I could come up with.


I was able to tweak the code to highlight interesting patterns. I actually thought for a moment that I had “discovered” a few things like for instance how if you number the “dots” by the order in which they are introduced into the simulation, the spirals that visually strike you are formed by joining the dots where the number difference is a fibonacci number.

Of course all this is common knowledge in the mathematics community. But I think I was able to create much prettier visualizations :) Here is a snapshot showing how the two most obvious spirals are where the dot-number difference is equal to 13 and 21 (successive Fibonacci numbers). Dot number 1 is on the far right.


And here is this interesting effect when the dots are numbered in reverse order, the dots corresponding to the Fibonacci sequence (1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144) line up along the x-axis.


Well, this is animation after all – so here is my first ever YouTube video :) If you are interested, here is the source code (not much documentation I’m afraid).

I found the fantastic sunflower photo on Flickr. The photo description has a good explanation of why the fibonacci spirals happen and the maths behind it. If you want to explore more, have a look at this Science News Online article.

Update 2008-12-13: Found this link to some nice mathematical analysis of number spirals (not Fibonacci):

Japanese anime song and dance stuck in my head

Thanks to Boing Boing for introducing me to this kind of stuff. It all started with this Haruhi Suzumiya dance, I watched the YouTube clips and sure enough, that was enjoyable. Exactly as predicted by the BB poster, the song stuck in my head for a week.

Then just recently there was this: “Software creates songs, vocals from text“. Woah, cool. You gotta hand it to the Japs!

So I followed the links, listened to the demos, and I was thrilled. Will this “Vocaloid” ever be available in English? I’ll buy it!

Something about the “anime song generator” stuff got to me, I feverishly searched for more demos. Soon, I landed on this YouTube video – a song called “Go My Way”. Yes, the vocals are computer generated!

[update: looks like the YouTube video was taken down because of some effing “terms of use” violation. I was able to find a version minus the video of the cute dance here:]

This was getting better! Although the video quality is terrible, the choreography, the cute anime characters and the CGI camera moves really got my attention. My, what a catchy tune! Little did I know that this song and dance was going to turn me into a crazed file-downloading j-pop-tune-humming maniac over the next two days or so.

Digging around for the source of the video, I came to learn about this Japanese arcade game called “iDOL@MASTER“. The game is about building the career of a cute anime “Japanese Idol” contestant you get to choose at the start. This Wired blog post has details on the gameplay.

So apparently in the game, once you are done with the mini-games and the sim gameplay, you sit back and watch as your precious teen idols take the stage and perform. I’ll probably never have the patience to play the whole game, but the computer generated performances and one particular song and its choreography is what I am currently obsessing about.

The in-game songs are voiced by humans and the YouTube clip above is just a Vocaloid demo. I watched all the YouTube clips of the iDOL@MASTER stage performance routines I could get and this “Go My Way” song was by far the catchiest. And those dance moves! The glorious cel-shaded animation! The smooth, sweeping camera moves and changes! The super-cute anime girls! The hair and costumes! The stage, lighting effects and sets! Wow. Very soon I had found hi-res versions of “Go My Way” and a couple other iDOL@MASTER songs on the net. Awesome.

So have I gone stark raving mad? In my defense, here is a YouTube clip I found of a grown man showing off his mastery over the “Go My Way” dance moves in sync with the video. Heh.

My cousin will be proud of me, he was trying to introduce me to the wonderful world of Japanese anime a while back and I still have those “Naruto” episodes on my hard disk. Maybe I’ll go back and finish watching them all. So much to do, so little time. *sigh*

Now coming full circle, I explored more about Haruhi Suzumiya – intriguing stuff, maybe will watch someday. But allow me to rave about this one particular video clip from the TV series where the main character and her friends play a rock-song live in a high-school event.

Considering that this is animation, the visual accuracy of how the characters are depicted playing the instruments in sync with the music – is to be seen to be believed. I wonder if the animators did something like rotoscoping, but the video captures the mood of a live band and the pent-up emotion of the lead singer amazingly well. The song is called “God Knows”, you can search for hi-res versions on the net.

In time, I’ll probably look back at this blog post and say to myself “what was I thinking?” but this stuff has so gotten under my skin that I simply have to post about it! “Go My Way” is well and truly stuck in my head and is not showing any signs of going away, I suspect because of the additional visual appeal of the dance moves. Oh help.

“Go My Way” is the best pop song EVAR!

I hope to be back to posting on Java soon. Heh.

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.

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.


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.

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

  • 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
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
Even without using Tomahawk etc., MyFaces requires far more dependencies than Wicket i.e. 10 vs 4 JAR files

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.

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
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

  • 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
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


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 “” 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