General Questions Why "Wicket"?

The name "wicket" was at first selected simply because it was unique, memorable and easy to say... and yet not used by a serious software project (the owner of the "dodgy IRC bot" called "wicket" which shows up in a Google search was kind enough to give his blessings to me via email to use the name). It is surprisingly hard to find any short word that is not already used as the name of some software project or other!

Although the name was selected for no particular reason, there are a couple of interesting coincidences. For one thing, web frameworks have been somewhat of a "sticky wicket". For another, "wicket" sounds a bit like "wiki" which is Hawaiian for "quick" (you could even think of the name as "wik" "it" ;-)). And finally, the original meaning of wicket was that of a small door. But, especially a small door within a larger door. I like this image quite a lot. It's modular ;-) and doors represent freedom (from the big J2EE door?). A picture of a small door within another door might make a nice cover for the User's Guide when it's done. Either that or a cute little squirrel staring back at the reader through a croquet wicket!

Design Philosophy Why are so many classes and methods in Wicket final?

Classes and methods in Wicket are generally declared as final until the need for extensibility is well understood. While this defensive approach may seem obsessive to some, the major benefit is that classes and methods which haven't been designed for extension cannot be extended until the problem(s) at hand are examined by the Wicket development team. This helps to ensure that the best approach is taken. Sometimes, straightforward extension is not the best approach. Sometimes, features of the API have been misapplied or misunderstood. It's best to catch this early.

While this does provoke more discussion and sometimes a bit of annoyance, the discussion generally improves Wicket and will help ensure greater backwards compatibility in the future. It's really a matter of how the development team manages API commitments. By making fewer commitments in the API in terms of extension points, we are more likely to be able to support those extension points that we do allow in the future. We are also more likely to catch anti-pattern use cases and provide features appropriate to the problems you are trying to solve.

Honestly, we aren't trying to annoy anyone and we do aim to respond quickly to any extension needs that arise which make sense. If you really don't agree with all this, remember that Wicket is open source. You can always check out the source code, remove the final keyword that offends you and rebuild the project.

What design decisions were made regarding state management?

One of the primary objectives was to make state management a Java thing that is abstracted away from implementation details like HttpSession. In Wicket, state is stored in components that are nested in Pages which are all contained in a map in the user's session. All of this is very well defined and occurs "behind the scenes".

Such a style of coding may be unfamiliar to people with experience using existing frameworks. Typically Wicket code involves good OO design, use of nested and anonymous classes and an overall awareness of components and their models as being the repositories of all state. It will take time to adapt to this and for people to set aside old functional models of programming where they accomplish everything with query parameters, session state or their equivalent.

How does Wicket handle stale data and the back button?

Because Wicket has a first class component object model where the state for every page and nested component is available in the user's session, it can trace through all that state when model information changes looking for pages containing components with models that have changed in ways that invalidate earlier renderings of those components and pages.

This provides automatic handling for the back button, which has to do with stale markup, and can generally be divorced from the typical problems of stale data in a multi-user environment, which should be handled with the usual (optimistic) locking techniques in the persistence layer.

A good example of stale markup is this: If a table on a page is rendered when there are 20 rows in the table's model, a subsequent deletion of a row will invalidate the rendering of the table that is still cached in the user's browser. When the user accesses the 20th row in the cached page by using their back button, the link will not be backed correctly. What's more, a deletion of the first row means that all 19 rows are off by one in terms of the model they reference.

In Wicket, stale markup caused by deleting a row in a table is automatically handled by using the well-controlled server side state which exists in the user's session. If you look at the Cell class you will see this implementation (roughly) of the removeLink method (which returns a Link that will remove any given cell from its containing table).

Notice that once the remove link changes its table's model by removing the cell's model from the table list, it calls table.invalidateModel(). This method is implemented by Table, which inherits most of the functionality from Component. If you look at the implementation of invalidateModel in Component, you will find that it looks through every component on every page in the user's session. Any page containing a component using the same model is a stale markup rendering and is made stale with a call to setStale. When a user uses their back button to access the stale page at a later time, they will receive an appropriate warning.

Building your own Applications How can I set a session property?

The best and safest way to set a property for a session is to create a subclass of Session (for web applications, a subclass of WebSession) which has the properties you desire. Then override the getSessionFactory() method of Application and provide code which instantiates instances of your session subclass. For example:

Then you can provide access to session properties in a typesafe manner that requires only a single downcast in your whole project:

How can I get Wicket to automatically reload changed markup files?

By default, Wicket will not reload changed markup files. This default is a conscious decision because performance can be affected by Wicket's change detection code, which has to poll the modification dates of all your markup files at a regular interval.

If you call the ApplicationSettings method setResourcePollFrequency(Duration), you can specify how frequently Wicket should poll for file changes. A Duration value of null will turn the feature back off again. For example:

will cause Wicket to scan your source files for changes as often as every second.

Note that this does NOT affect where Wicket finds resources. If you want Wicket to find markup files directly in your source tree while you are developing, you can call setSourcePath(Path) like this:

This is a highly productive way to work if your resource poll frequency is fairly quick. After you change a markup source file, you can simply hit refresh in your brower and immediately see the effect. With your source path set like this, it is not necessary to restart the application server or redeploy any files.

Finally, it is interesting to note that since ApplicationSettings methods return their this pointer for invocation chaining, you can put this all together into one statement: