In a typical web framework, you write a template that's more-or-less HTML, but with special code to make it dynamic. For example, here's how to print "Hello World" in php:
NOTE: I am NOT saying that PHP is better than Wicket. I'm just EXPLAINING how Wicket works compared to other frameworks and using PHP as an example of another framework.
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php echo '<p>Hello World</p>'; ?>
</body>
</html>
In the <?php ?> tag, you specify what HTML will be generated. Wicket works in a different way. You mark the dynamic parts of your HTML with a special attribute and specify what it does in Java code. Here's the same example in Wicket:
<html>
<head>
<title>Wicket Test</title>
</head>
<body>
<p wicket:id="message">This is replaced</p>
</body>
</html>
And then in a Java class:
public class HelloWorldPage extends WebPage {
public HelloWorldPage() {
Label component = new Label("message", "Hello World!");
add(component);
}
}
By comparison the html template is simplified: You define the parts that are dynamic but you don't say what the dynamic parts will do. That's done entirely in the Java code. If you learn more about Wicket, you'll see that your Java code ends up looking similar to Swing code (Swing is Java's GUI API).
Before I go on to explain the top 8 reasons to NOT use Wicket, I want to say that there is one situation where I would still use it: If a large part of my webapp functioned like a wizard. Wicket makes it easy to keep track of state from page to page without persisting at each step. With a traditional framework, you have to manipulate the session or use hidden fields to accomplish this.
1. Documentation, documentation... documentation?
By far my biggest complaint about Wicket stems from problems with its documentation. Imagine this: You get stuck on an issue and have no idea why. First you search the official wiki. You try your hardest to find a section to answer your question but it doesn't seem to be there. On the other hand, it's so badly organized you may have just missed it. You guess it's not there and move on to the examples.
The examples can be useful, but there's a lot to be desired. Exercise: Visit http://www.wicketstuff.org/wicket13/ and try to find an example that shows you how to redirect to a different page after you submit a form. I had to ask in the IRC channel to figure out how to do that. It also doesn't help that there are two example pages. One is on the main site, and another (much more useful, I might add) that's on wicketstuff.org (but good luck finding these examples on the wicketstuff.org home page).
Lets say the examples didn't help so you move on to the Javadocs. No help there: The class in question and its methods are barely documented. Take a look at this gem: http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/SharedResources.html At least this time it's obvious the answer isn't there.
Time to move on to the mailing list archives. You discover that Wicket's mailing list is extremely active and is often the only source for answers. Here's the downside to that: 1) A mailing list is not the right environment to learn a framework. A mailing list is for situations where you more-or-less "get" the technology, but are unsure of a few things. 2) It's hard to find mailing list answers by Googling. Think about it, how often do people link to a mailing list threads? Almost never. That leads to poor page ranking and that means the answer to your question, even if it's there, is hard to find.
2. High learning curve
Even if the documentation was well written and complete, Wicket would still be harder to learn than most frameworks. Lets look at how to solve some basic problems using the example above:
How do hide a dynamic tag? component.setVisible(false). How do I dynamically add a class attribute to the tag? component.add(new SimpleAttributeModifier(“class”, “classValue”)); How do I dynamically add a CSS file to my template? webpage.add(HeaderContributor.forCss("/path/to/my.css"); Do you see the problem? It's subtle.
Knowing the answer to one of these does not help you in answering the others and each one of these questions requires you to deal with part 1. On the other hand, as soon as you learn how to write a conditional in PHP/JSP/ROR, you immediately know the answer to all of these questions and many more in the future.
Let's try an example together: How would you make a page's title dynamic in Wicket? Is it webPage.setTitle(String)? Nope, that doesn't exist. In fact, the word title isn't even mentioned in the javadoc. Ok, dead end #1. Perhaps it's webPage.add(new Title(...)); or something like that. Nope, there's no such thing as a Title class. In fact, the word Title isn't even part of any class in the javadoc. Dead end #2. That also rules out something like webPage.add(TitleContributor...); Dead end #3.
So, how the heck do you actually do this in wicket? The only answer I can find is webPage.add(new Label("wicketId", "dynamicTitle");. You add a Label to your page that attaches to your <title> tag and overwrites the text. Duh!
3. Different... not better, but different
In my 5 months with wicket, there was no indication that it was a time saver. Wicket seems more about making a webapp in a different way than in a productive way. Compared to a framework like Struts or Ruby on Rails, Wicket probably decreased my template code by 4x but increased my Java code by 4x. I ended up doing the same amount of work, just in a different place.
If you consider writing template code to be traumatic experience, perhaps you'll see this as a huge improvement. But, if you're like me, you'll think that a webframework should help you write less code. Writing less code has a lot of benefits. There's less to understand, less to maintain, less work to add a feature, etc.
Perhaps these time saving features exist and I overlooked them. Unfortunately, Wicket doesn't have an official list of, "Cool features that will save you tons of time" anywhere, so you'll likely have the same experience as me. But, I did read most of "Wicket In Action" (great book for learning Wicket, BTW), and it didn't change my impression.
4. Lacking 3rd party library support
Getting 3rd party libraries to work in Wicket is more annoying than other frameworks. By 3rd party libraries, I mean external tools that add content to your website that may or may not care about the programming language you use. Things like ReCaptcha to add a captcha to your site, the Facebook API for making a Facebook app, or Rome to add a RSS feed to your site. Fortunately, there are Wicket extensions for these examples (I made the first two), but unless you make your entire webapp from scratch, you're bound to run into others that aren't. With Wicket, getting these libs to work can be painful and confusing.
Lets look at ReCaptcha to see why. With ReCaptcha, you add a <script> tag to your webpage that refers to an external javascript file. When it loads, the script generates a captcha and an input field for you. When the user submits the page, you take the input and ask the ReCaptcha server, "User typed this, is that what was displayed?".
With most frameworks, this is an easy way to add a captcha to a website. With Wicket, it's a challenge. Since you didn't include this input in your template (remember, Wicket needs a wicket:id attribute on input fields too) and you didn't put add(new TextField("recaptchInput")); in your Java code, Wicket is unaware of the input. As a consequence, you can't leverage any framework features. This includes essentials like retrieving the value so you can pass it to the ReCaptcha server.
For those wondering "Why doesn't he just put it in his template and add the Java code?", that won't work: The ReCaptcha script would just generate another input field for you and cause the same problem.
What's the solution? You need to reach into the HttpServletRequest and extract the value by hand. Most frameworks, including Wicket, consider this a primitive way to get data from a user response. Yet, as far as I can tell, it's what you have to resort to.
5. Generate HTML or generate pain
Sometimes you want the server to generate something other than HTML. For example, you may want to generate Javascript or CSS. EG: var message = "dynamicString"; To make the string dynamic, the template would have to say var message = <span wicket:id="dynamicString">localized alert</span>; You have to do similar things in your CSS files to make them dynamic: .highlight { <span wicket:id="highlight">highlight style</span> }
Unless your editor speaks Wicket, this will drive it nuts. Not only will the dynamic bits be more verbose than a typical framework, they'll look more out of place. "Why is this HTML embedded in this CSS file?".
6. Easier to maintain?
One of Wicket's selling points is that it's far easier to maintain than other frameworks because you write most of your code in Java. I think that's debatable. Is 4x more Java code more maintainable (see part 3)? The code you write ends up looking like Swing code so unless you're very disciplined, you end up writing anonymous and inner classes all over the place that share instance variables with the parent class. Once that happens, it's a real chore to refactor them to outer classes.
If you put in the effort to avoid these pitfalls, your code may be more maintainable. But a framework is supposed to facilitate discipline, not put the burden on the developer. With Wicket I found myself thinking, "OK, how can I add that feature without it turning into a mess later?". I'd prefer to just focus on the feature itself. If I wanted to focus on proper discipline, I would've stuck with JSPs and Servlets in the first place. This goes back to the question, "What is this framework doing to make my life easier?"
7. The "Great for web designers" myth
Wicket is supposed to be nice for web designers because it doesn't use template code. You just put a wicket:id="something" on the HTML you want to be dynamic and replace it in your Java code. The end result is your HTML is perfectly understandable by a web designer who doesn't know the first thing about Java. While Wicket may be better than other frameworks in this respect, it still has problems.
For instance, Wicket has non-HTML tags for special functionality with names like <wicket:panel>, <wicket:child> and <wicket:extend>. These won't render correctly in a browser. If you research the last one, you'll see you must violate the "Don't Repeat Yourself" principle to get your pages to render outside the browser in a way that looks similar to its production code.
In general, Wicket is better than most frameworks in this respect. But, when you consider part 5, it can sometimes be worse than most.
8. Search Engine De-optimization
By default, the URLs Wicket uses look like this: http://www.startfound.com/?wicket:interface=:3:::: For a search engine, this is a problem for two reasons:
- This URL provides no semantic information
- This URL is only valid for that user's session.
There are Wicket classes that won't work with bookmarkable URLs. For example, if you want to use the Wicket "paginator" (think the bottom of Google search results), your URLs have to look ugly. So if you want pagination on your site with pretty URLs, you're going to have to write it yourself. And that goes for a lot of its other APIs.
Conclusion
There was a point while working on my hobby website that I was pulling my hair out dealing with these issues on a daily basis. Finally, I had enough and came to the conclusion that it was smarter to rewrite the whole thing from scratch in another framework.
I chose what I'd consider to be the exact opposite of Wicket: The Stripes Framework. During and since the rewrite, I couldn't be happier with my choice. When it comes to ease of use, quality documentation, simplicity and productivity, I've never worked with a better web framework. Let me state that I'm not affiliated with the Stripes framework, I'm just a huge fan. I have experience with Struts, Ruby on Rails, plain old JSPs and Servlets and, of course, Wicket, and the Stripes framework is by far the best web framework I've ever worked with.
One last note on Wicket: Of all those projects I created while learning it, there was one where I feel Wicket was the right choice (the whole thing was basically a Wizard). So in the end, I consider Wicket to be a hammer in my tool belt. Unfortunately, most jobs I come across require a screwdriver.
You can see my follow up blog post that compares Wicket and Stripes in depth here: http://www.assertinteresting.com/2009/03/why-i-prefer-stripes-over-wicket/