Trifork Blog

Wicket do’s and don’ts

September 16th, 2009 by
|

In the past 2 years I worked in, and visited many development teams to help them implement divers Wicket applications. Some applications were mostly for visualizing stuff, some were full of forms, and some were full of Ajax tricks. This article contains some of the lessons I had to teach, or had to learn myself. I’ll present them as do’s and dont’s. They are:

  • Do use models
  • Don’t use an Ajax library without intimate knowledge of the library
  • Do make sure you understand the repeaters for high performance sites
  • Don’t overuse inheritance
  • Do keep markup in sync with the component code
  • Don’t try to do authorization from a servlet filter
  • Do take your time to override key Wicket features

Do use models

Number 1 on the list of smelly Wicket code is like this:

public IncomePanel(String id, Person person) {
  super(id);
  add(new Label("salary", person.getSalary()); // no model!
}

There is not much wrong with this code, except for one little thing. Suppose that IncomePanel also contains some logic to increase this person’s salary (e.g. a button). Unfortunately, you will never see the new salary as the label got a fixed value during its construction; the label will not look for a new value during a second rendering.

We can correct the situation by passing a model to the label. In addition, it is good practice to use models for your own components (like IncomePanel). With this in mind the code becomes something like this:

public IncomePanel(String id, IModel<Person> personModel) {
  super(id);
  add(new Label("salary", new PropertyModel(personModel, "salary"));
}

Or even this:

public IncomePanel(String id, IModel<Person> personModel) {
  super(id, new CompoundPropertyModel(personModel);
  add(new Label("salary");
}

Don’t use an Ajax library without intimate knowledge of the library

You should never start using Hibernate if you do not know about tables, inner vs. outer joins, indexes, resolution of the datetime type you’re using etc, etc. Every sufficiently complex technology (such as Hibernate) is affected by something called leaky abstractions.

The problem of leaky abstraction can also occur when you use Wicket components that abstract away javascript libraries. In general you know you have leaky abstractions when you suddenly have to worry about implementation details. For example because the component does not work in certain circumstances.

I had such unpleasant experiences with the wicketstuff-yui library. The library has many nice capabilities, but is not very well maintained. Without YUI knowledge it is almost impossible to find the subtle bugs that can prevent all your AJAX components from working completely. We had a similar problem with the wicketstuff-tinymce library.

Do make sure you understand the repeaters for high performance sites

Repeaters are a family of components that allow you to display some HTML multiple times on a page. As you can guess, every web application has repeaters. Using repeaters wrongly can lead to unnecessary memory and CPU usage. Mostly this is not a big problem. For sites that require optimal performance, understanding the different repeaters is essential.

Wicket by default provides the following repeater: Loop, ListView, RepeatingView, RefreshingView, DataTable. This list is not even exhaustive; there are some more variations. Every repeater constructs a transient component for each iteration: the loop item. Every loop item has a Wicket model to look up the item’s data.

Here are some points to consider to choose the most optimal repeater:

  • Moment of data retrieval. Is it during construction only, or for each render again? During a re-render, is all data retrieved at once or one by one?
  • Moment the loop-item’s model is created. First time only, or again for each render, or does it retain existing models and only add/remove models as the underlying data changes (ItemReusePolicy)? Can you control the model creation?
  • Is pagination/sorting needed?

Answering these questions for each of these components is an article in itself. However, if you need every bit of performance, make sure you have someone on the team with this knowledge.

Don’t overuse inheritance

Wicket has a nifty feature which allows you to do markup inheritance. When a component extends a super component you have the option to embed its markup in the markup of the super component. Markup inheritance is extremely useful to provide a common page layout.

Unfortunately I have also seen serious misuse of markup inheritance. Signs you’re in trouble are:

  • common layout turned out to be slightly different on every page,
  • components are created by abstract methods (constructors should not call these),
  • there are getters to your components (breaks data hiding),
  • the constructor of the sub-class replaces a component that was created by the super-class (wasteful and unmaintainable) or
  • you add components while the wicket:id is not in the markup file of the current class (maintenance nightmare).

The remedy is to split of parts of the screen to separate components (e.g. Panels) and manage the complexity there.

Inheritance is probably the most overrated feature of object oriented languages. Most OO power comes from composition and data hiding. Even though Wicket makes extensive use of inheritance (and rightly so), this applies as much to Wicket code as to regular Java code.

Do keep markup in sync with the component code

Nothing is more frustrating then having trouble finding the html element that is associated with a given component or vice versa. Make sure you keep code and markup in sync or you will have maintenance nightmares.

Don’t try to do authorization from a servlet filter

It just won’t work. Wicket is full of generated URLs (yes, even if you mount every page) so authorization based on the URL is a fruitless exercise. You are better off by writing an IAuthorizationStrategy and configuring this in your Wicket application. Study the code of wicket-auth-roles to see how this can work. In addition you’ll get component based authorization, not just page based! (By the way, you’ll have no problems with filter based authentication.)

Do take your time to override key Wicket features

Wicket can be tweaked in all kinds of expected and unexpected ways. For example you can substitute your own resource messages provider, filter and change the markup as it is read from disk or completely override the request cycle handling. However, some of these extension points are not for the faint hearted and not likely to be right immediately. Make sure you have a number of iterations before it needs to be rock solid production ready.

Summary

Although Wicket is easy to work with, you can find yourself in situations that are not optimal, either because you did not find the best solution, or because you are working against the framework. In addition, please be careful when you take Wicket to the extreme.

Further reading:

14 Responses

  1. September 16, 2009 at 15:25 by Wille

    I would add to the “do’s” something that makes sense in OO:
    Do use composition.

    When I started using Wicket a few years ago, I definitely overused inheritance because I did not quite get how Wicket worked, though after a while I realized I could get the same effect, but better with composition.

    These days most Wicket pages I create are in fact just the same base page composed in different ways, with different components.

  2. September 17, 2009 at 15:24 by Frank Silbermann

    Goede Dag, Erik!

    I don’t understand your objection to components created by abstract methods, saying “constructors should not call these.”

    Let’s say I have a set of pages each with four quadrants (UpperLeft, UpperRight, LowerLeft, and LowerRight), and let’s say that the UpperRight and LowerLeft are pretty constant across many pages of my application, but the UpperLeft and LowerRight panels vary independently page by page. I would like to create a base page that deals with the two common panels once and for all.

    So I create an HTML template with wicket IDs for the four panels in their place. My abstract base page creates and adds all four panels. However, for the UpperLeft and LowerRight panels (which vary across the sub-pages), the base page’s constructor calls:

    abstract Panel createUpperLeftPanel(String wicketID);

    and

    abstract Panel createLowerRightPanel(String wicketID);

    in each case passing the actual wicket ID defined in the base page’s HTML.

    When developing the individual pages that inherit from my base page, I need no HTML file for the sub-pages — they use the base page’s HTML file. In the sub-page definitions I can ignore the very existence of the UpperRight and LowerLeft boilerplate panels — how is that for information hiding? The only new HTML needed for the sub-pages is the HTML for the individual panels I instantiate when implementing the abstract methods.

    When creating the page-specific panels, the sub-page definition doesn’t even need to know the wicket IDs used by the base page — the abstract method provides it. (If I change the wicket ID on the base page, as long as it passes the new ID to the abstract method, the sub-page does not break.)

    So what’s wrong with this pattern?

  3. September 18, 2009 at 02:18 by Dave Bolton

    Great write up. Coming from an arduous JSF project, we’re looking at potentially using Wicket in the future, and it is this accumulated expert knowledge that gives real insight into a framework in use, rather than reading “getting started” guides which always gloss over this sort of thing.

    Look forward to more posts like it.

    Cheers,
    D

  4. September 18, 2009 at 18:00 by martin-g

    Nice write-up Erik !

    @Frank: check http://www.javapractices.com/topic/TopicAction.do?Id=215
    I think this is what Erik meant

  5. September 24, 2009 at 17:31 by Nick

    Nice post.
    Just started using wicket for a project and I’ll take note of your suggestions, especially the part about repeaters.

  6. September 25, 2009 at 13:16 by LeChe

    Frank,

    I think the issue that Erik is referring to has to do with the general problem of calling abstract methods in any class’ constructor. Basically, you are leaking the reference to a incomplete object by doing that and any implementing class (that you might not be the author of) might incorrectly assume that object construction is finished!

    The book “Practical Java” is a very good source for this (and similar) kinds of gotchas…

    Regards,
    Che

  7. September 30, 2009 at 12:21 by Erik van Oosten

    Wille: indeed. Your ‘do’ would be a nice addition. I try to do the same as well. I still use markup inheritence for the most basic page layout though.

    Frank: Martin and LeChe gave the correct answer.

    Dave, Nick: Thanks!

  8. October 20, 2009 at 16:42 by Frank Silbermann

    I see your point about constructors calling overridable methods. It only works if the overriding method does not depend on anything that the subclass adds to the construction process. (That’s how I’ve gotten away with this for so long.) One might consider it a weakness in Java that nothing can be done in the subclass until the base class’ constructor has executed, but Java is what it is.

    It seems to me therefore to be a flaw in Wicket’s requirement that the page hierarchy of components be completely built during the page’s construction. The parent page is only going to know about the components that are common to all the sub-pages.

    Markup inheritance is not a good solution IMAO, as it allows sub-pages to develop only a single part of the parent page. Also, it wastefully forces the sub-page to have its own HTML file when all you’re trying to do is to insert into predetermined places a few panels that already contain their own HTML.

    One alternative is to have the subclass replace dummy components that the parent page built — but you condemn that, too, as wasteful and unmaintainable.

    My motivation for using the abstract methods was:

    (1) To ensure that no one tries to instantiate the base page (as its component hierarchy is incomplete),
    (2) So that writers of the sub-pages would know what components they needed to add, and
    (3) So that writers of the sub-pages would not have to look at the base page’s HTML file to discover those components’ wicket-IDs, nor would they have to examine the base-page’s code to determine the container components to which the specialized sub-page components are to be added.

    What would be a better solution?

    Would you suggest putting into each base page an uncalled “CompleteThePage()” method — which calls the abstract component-creation methods and adds the components to the component hierarchy in the proper places?

    With this latter approach, we would then merely depend on the sub-page authors to to know that “CompleteThePage()” must be called at the end of their constructors (the compiler would still ensure that they instantiated the abstract methods it calls).

    Of course, in a page hierarchy, the intermediate page constructor would have to call “parent-page.CompleteThePage()” — to distinguish it from its own “CompleteThePage()” method that its children call in their constructors.

    It really surprises me that the Wicket community has not discussed this issue already, and that Wicket developers would be satisfied with the weak and ugly “mark-up inheritance.”

  9. October 20, 2009 at 21:24 by Frank Silbermann

    A follow-up to my previous question. Is there any hook I could override in the base page that is called after the constructor returns but before the page’s component hierarchy is matched to the HTML hierarchy of wicket-id tags?

    I’m thinking that if my base class overrode that method to call the “CompleteThePage()” method, then subclasses wouldn’t have to worry about adding “parent.CompleteThePage()” to the end of their constructors.

  10. October 21, 2009 at 08:43 by Erik van Oosten

    Hi Frank,

    > Markup inheritance is not a good solution IMAO, as it allows sub-pages to develop only a single part of the parent page.

    Wicket is no silver bullet 🙂 I agree, you have to live with this limitation. But no despair, composition with panels is another technique that works very well.
    One more note: Wicket 1.5 will allow multiple extension points for sub-pages.

    > Also, it wastefully forces the sub-page to have its own HTML file when all you’re trying to do is to insert into predetermined places a few panels that already contain their own HTML.

    Well actually, I was saying it is wasteful to /replace/ components that were already added by the parent page. It is acceptable (within limits) to add components from sub-pages while the associated HTML is in the parent page. The wicket id to use can be given by a constant in the parent page. With Wicket 1.5 this kludge will no longer be necessary.

    > My motivation for using the abstract methods was:…

    These are very good considerations. However, the underlying mechanism in flawed because you are using java 😉 Btw, I went through the same steps before I came to this conclusion.

    > What would be a better solution?

    The solution is to step away from markup inheritance and only use it for the most basic HTML layout of the page. Instead you can use panel composition. (Note this is what I recommended in the article.)

    > It seems to me therefore to be a flaw in Wicket’s requirement that the page hierarchy of components be completely built during the page’s construction.

    Strictly spoken, this is not the case. The component hierarchy must be complete before the render phase starts. Therefore you can also add components in an overridden Component#onBeforeRender. You’ll need a flag to keep track if you already did this, or clear the currently present components. Also, you might want to override callOnBeforeRenderWhenInvisible. Don’t use this technique before you have tried to use panel composition.

  11. October 21, 2009 at 15:28 by Frank Silbermann

    Erik responded: “Don’t use this technique before you have tried to use panel composition.”

    Well, I _am_ composing panels; the issue is the kind of glue I should use for attaching the panels within the page (in lieu of calling abstract methods from my constructor). What method of assembling panels do you have in mind when you refer to “panel composition”?

    I suppose one way is to assemble the panels in each page independently; the common panels are reused, but if 50 pages all use the same panel in the same place, I’d be repeating that

    “add( new Panel…);”

    command in 50 pages. And, I’d have to repeat the HTML containing the panel’s wicket-id 50 times. Not good.

    Another approach we’ve discussed is to have the base page assemble the common panels along with dummy panels, and to have the sub-page replace the panels that vary. The sub-page programmer has to look at the base page documentation or code to learn the panels that should be replaced and the variables containing each respective wicket-id. Is this what you mean by “panel composition”?

    Suppose I move the base page’s component tree construction out of the constructor into the method:

    private void assembleComponents() { …

    and add the property:

    private boolean componentsAssembled = false;

    Then I could add:

    @Override
    void onBeforeRender() {
    if ( !componentsAssembled ) {
    assembleComponents();
    componentsAssembled = true;
    }
    super.onBeforeRender(); // Or whatever else I might have put into this method
    }

    Then component construction would wait until the properties in both the parent and the subclass had been set, and I’d no longer have a problem with calling abstract methods from the constructor. Abstract methods would still tell the subclass what it needed to implement, and each abstract method would provide the proper wicket-id.

    Do you see any disadvantages to this approach? I don’t think additional boolean test in “onBeforeRender()” is computationally significant, and it would not prevent me from adding any additional on-before-render tasks.

    If it is a good approach, I wonder why the Wicket designers did not create an overrideable called-once-after-object-construction method in the Component class, and tell developers that this is where the component tree should be created.

  12. November 8, 2010 at 22:23 by Wicket – useful links « Tomasz Dziurko

    […] Wicket dos and don’ts, article showing what to do and what not to do when we use Wicket framework in our project […]

  13. September 20, 2011 at 08:08 by Chrisco

    LeChe said “Basically, you are leaking the reference to a incomplete object by doing that and any implementing class (that you might not be the author of) might incorrectly assume that object construction is finished!”

    I agree, calling from constructors is very dangerous and pre Wicket 1.5 this was sometimes unavoidable (but a juggling act) because onInitialize was not implemented properly like it is in 1.5.

    In 1.5 you are guaranteed that onInitialize() is called AFTER the component/page constructor has completed so onInitialize is always dealing with a completely constructed object. So in 1.5 is makes sense to do that bulk of your intiialization code in onInitialize() rather than in the constructor.

    This subtle but long awaited (by me at least 🙂 ) change means that Wicket acts more like traditional UI frameworks (MFC, OWL, Swing) etc., where a method like ‘SetupWindow’ is used to initialize child components etc., rather than the constructor.

  14. September 26, 2011 at 08:25 by Erik van Oosten

    Hi Chrisco, right you are.

    BTW, onInitialize was already added around version 1.4.10.