That last item tells me this is an ideal framework for Java developers like you(?) and me. If you’re familiar with other webframeworks like JSF of Spring MVC perhaps, you might have to switch a button in your mind though. Wicket is different in a few ways, you will notice that later.

A simple web application with just Wicket would probably not be sufficient in most cases. Usualy there is the need of a database and preferably we want to have a nice architecture with separated Dao-, Service- and front-end layers, where you can continue to use other frameworks in the backend. And, of course, we want Maven as our build environment.

In this blogpost I’ll show you how to quickly setup a Wicket application using Maven (2), Spring and Hibernate. In this case I use a HsqlDB file-database but other Hibernate configuration are easily Google-able.

I will explain the setup with an example application of which I have created a maven archetype. The application created by the archetype has actually done all the work for you, but keep reading if you want to know how.

Create the application

To create the example application execute the Maven archetype command like this:

The command will create a map with your demo application. Do this inside the map where you want to have it created, for example C:\myWorkspace\. Also you may want to change the last 2 arguments, groupId and artifactId to your own values.

After the archetype created your project you should be able to run it with the following command from within your application’s directory:

Play around with the five different (growing) examples in the *web.examples packages. Be sure to have the corresponding parent in the WicketApplication class as you head to newer examples and uncomment the insertion of the userManager in the applicationContext once you are at the fourth example.

Let’s start

We will start with the maven project. In the pom.xml we see the folowing dependencies:

groupId

artifactId

version

Note

org.apache.wicket

wicket

1.4.15

The core Wicket library

org.apache.wicket

wicket-spring

1.4.15

The integration of a Wicket application in Spring

org.apache.wicket

wicket-extensions

1.4.15

Extentions to the core Wicket with lots of perfect (markup) components out of the box. Not needed in a simple Hello World but comes in handy very quickly

junit

junit

3.8.2

For a simple unit test of our homepage, we might want a newer version here

org.springframework

spring

2.5.6

The core Spring library

org.springframework

spring-test

2.5.6

Spring library used for unit testing using Spring beans

org.hibernate

hibernate

3.2.6ga

Hibernate core library (3.2.6ga is a popular version)

hsqldb

hsqldb

1.8.0.7

The Hsql (file) database library

commons-dbcp

commons-dbcp

1.2.2

Used as the HsqlDB datasource

javax.servlet

servlet-api

2.5

Only needed for a handy lookup in our HsqlDB configuration in this example

log4j

log4j

1.2.14

Used for the logging in our application

org.slf4j

slf4j-log4j12

1.4.2

Used for formatting our logging.

Now, our map structure should look familiar, like this:

src/main/java/ – Containing our Java packages. In the web subpackages where we place our Wicket code we will see the Java files as well as the html files!

The Spring configuration

In the applicationContext.xml we will describe our Spring configuration. It will contain the following beans:

wicketApplication. This is the root of the Wicket application, it is associated with an instance of ‘the’ WicketServlet, handling all requests for Wicket.

dataSource. The source to our data using the (jdbc) driver. (in this case to our Hsql database)

transactionManager. A manager (for the service layer) handling the (database) transactions, implemented by Spring’s HibernateTransactionManager

managerTemplate. A template bean (parent) for our managers (servicelayer). This template is a Spring AOP proxyFactoryBean which we’ll give an interceptor (another Spring bean) for transations using the transactionManager.

sessionFactory. A factoryBean for the Hibernate sessions. This bean, implemented by Spring’s LocalSessionFactoryBean uses the dataSource bean and gets the Hibernate mappingfiles and other Hibernate proberties

Dao- and manager-beans. These backend interfaces can be injected in the wicketApplication bean so we will be able to reach the backend from within our front-end Wicket code.

The Hibernate configuration

The Hibernate configuration is mostly done in the Spring configuration as mentioned before. Look in the applicationContext.xml and the files in src/main/resources/hibernatemappings/ for more details.

As I don’t want to (and can) get into details about Hibernate itself I suggest to Google around for more information.

The Wicket configuration

For a simple Wicket application like this, there is not much to configure. As we saw in the Spring configuration we’ll need a wicketApplication bean. This bean should be an extention of the org.apache.wicket.protocol.http.WebApplication class which is used by the (single) WicketServlet. The only 2 methods we have to implement here are:

getHomePage()Returning the class of the homepage (an implementation of org.apache.wicket.markup.html.WebPage)

init() An initialisation method called during startup. Here it is possible to create bookmarkable pages for example or authorization. You can leave it empty for now.

It is good practice to create a bookmarkable pages. This means giving a logical name to a page (which is allways a class extended from org.apache.wicket.markup.html.WebPage) so you can enter the URL to a page manualy (or add it to some third party menu). You can do this in the WicketApplication class by calling the mountBookmarkablePage(path, classfile). As parameters you’ll give a (web)path to the page, for example “/homepage”, or “/admin/users”, and the class of that page (for example HomePage.class).

Since you have implemented the getHomePage() method, Wicket knows which page to show you when you’ll enter the URL to your application (being the WicketServlet) in your browser.

The web.xml configuration

As mentioned before, there is a single WicketServlet handling all requests for Wicket(pages). In the web.xml you will see that we only need a Wicket filter and corresponding filter-mapping.

You will notice that we use the org.apache.wicket.spring.SpringWebApplicationFactory (from our wicket-spring dependency) as a factory class instead of directly pointing to our WebApplication class. This is where Wicket and Spring come together. the SpringWebApplicationFactory will look for a bean with an implementation of Wicket’s WebApplication and forwards the request to Wicket.

Related

The archetype does not seem to work. I get the following exception :
[ERROR] org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in prol
og.
org.apache.maven.archetype.exception.ArchetypeGenerationFailure: org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in
prolog. Nested exception: Content is not allowed in prolog.
at org.apache.maven.archetype.generator.DefaultFilesetArchetypeGenerator.generateArchetype(DefaultFilesetArchetypeGenerator.java:236)
at org.apache.maven.archetype.generator.DefaultArchetypeGenerator.processFileSetArchetype(DefaultArchetypeGenerator.java:215)
at org.apache.maven.archetype.generator.DefaultArchetypeGenerator.generateArchetype(DefaultArchetypeGenerator.java:130)
at org.apache.maven.archetype.generator.DefaultArchetypeGenerator.generateArchetype(DefaultArchetypeGenerator.java:290)
at org.apache.maven.archetype.DefaultArchetype.generateProjectFromArchetype(DefaultArchetype.java:75)
at org.apache.maven.archetype.mojos.CreateProjectFromArchetypeMojo.execute(CreateProjectFromArchetypeMojo.java:185)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:558)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:512)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:482)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:330)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:227)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in p
rolog.
at org.dom4j.io.SAXReader.read(SAXReader.java:482)
at org.dom4j.io.SAXReader.read(SAXReader.java:365)
at org.apache.maven.archetype.common.DefaultPomManager.addModule(DefaultPomManager.java:88)
at org.apache.maven.archetype.generator.DefaultFilesetArchetypeGenerator.processPomWithParent(DefaultFilesetArchetypeGenerator.java:698)
at org.apache.maven.archetype.generator.DefaultFilesetArchetypeGenerator.processFilesetProject(DefaultFilesetArchetypeGenerator.java:594)
at org.apache.maven.archetype.generator.DefaultFilesetArchetypeGenerator.processFilesetModule(DefaultFilesetArchetypeGenerator.java:515)
at org.apache.maven.archetype.generator.DefaultFilesetArchetypeGenerator.generateArchetype(DefaultFilesetArchetypeGenerator.java:206)
… 23 more
[INFO] ————————————————————————
[ERROR] BUILD FAILURE
[INFO] ————————————————————————
[INFO] : org.apache.maven.archetype.exception.ArchetypeGenerationFailure: org.dom4j.DocumentException: Error on line 1 of document : Content is not a
llowed in prolog. Nested exception: Content is not allowed in prolog.
org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in prolog.

org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in prolog.

I don’t have any problems here on multiple machines. Can you tell me what maven version you use and which OS you are running.
Do you have any specific settings in your settings.xml?
You might want to temporary remove it and try it again (and perhaps clean or move your local repository).

My guide is written for people who already have java experience but sure I would like to help you out a bit. Can you give me specific errors or problems you experience?
Maybe as a newbie it’s better to start reading a java book and perhaps a few chapters of the Wicket in Action book first and have them next to you when working on the examples.
Try to find and understand the differences between the given examples.

Evgenioni

26/07/2011 at 13:58

Thank you for answering. I’ll start reading the java and wicket books. But it’s to difficult for me to find solution or article where could be included some different technologies.
In my application I need to use PostgreSQL database for storing data, AJAX for dynamic information updates on the site.

I’ve started to read Wicket Cookbook, but also will read Wicket in Actoin.

There is a nice Wicket plugin for eclipse out there – qwickie which opens the view and its related controller simultatiously (when either one is clicked). It also has a handy outline view of code. When clicking on id’s the corresponding code will be opened in the other file (view-> controller, controller -> view).
Be sure to check out these and other features of qwikcie from apache:http://code.google.com/p/qwickie

I’m trying to replicate the first example in a clean project and after setting all the configs files and everything ‘the same’ as yours (I’m using wicket + spring + hibernate), it displays this error:

ContextLoaderListener
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1688)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1533)
at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:525)
at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:507)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:124)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4701)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5260)

The only difference that I see is that in your projects deployment assembly you have a persisted container reference, don’t know if this is the reason why the context is not being loaded.

I followed the instructions and kept my project name crystal360. I did mvn jetty:run and it ran successfully. When I try to to access http://localhost:8080/crystal360, I get below error.

Access to the webpage was denied
You are not authorized to access the webpage at http://localhost:8080/crystal360. You may need to sign in.
HTTP Error 403 (Forbidden): The server refused to fulfill the request.