Our Blog

Let us find tech solutions together

Mar 10

In the course of building an application, whether it due to shortened timelines, lack of process, or laziness, tests become an afterthought. Tests often are added when problems are found, or to root out bugs that were not found during early phases.

This article, day 2 of our project, will show how to write a solid baseline for your application with tests as the strong foundation. Our first meetings laid down the scope and direction we wanted achieved for this short project. We had a clear sense of the problem we wanted to solve, as well as the basic components we were going to implement.

In testing code there are several cycles commonly used in the enterprise community. We will start our testing tutorial by talking about mocks.

Mocks The Wikipedia page on Mock object describes them simply:

In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways

In Java, utilizing Mock objects generally requires the usage of interfaces. The interfaces are hopefully something that evolved from initial design discussions, and become the basis for the expected functions and behavior.

The tool we use to build the Mocks is EasyMock and JUnit for unit tests. In your search for the ultimate testing tool, I’d strongly encourage you to try out other tools such as TestNG and JMock.

The longest running unit-testing tool in the Java world is definitely JUnit. If you’d like to read up on Test Driven Development and each of the concepts outlined here in more detail, Test Driven Development by Example is a brilliant book written by Kent Beck on the topic. Test Driven Development stands alone in the Agile theory as the most effective value preached, especially when done early, and done comprehensively.

We have a few interfaces now, which came of initial discussion about how we imagine a pastebin functioning, so what is the next step? And how can testing help us?

Here is the primary service interface:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface PasteService {
	List getLatestItems(String clientToken, int count, boolean threaded) throws InvalidClientException;

	PasteItem getItem(String clientToken, long id) throws InvalidClientException;

	PasteItem findPrivateItem(String clientToken, String privateToken) throws InvalidClientException;

	List findItemsByLanguage(String clientToken, LanguageType languageType, int count, boolean threaded) throws InvalidClientException;

	long createItem(String clientToken, PasteItem item) throws InvalidClientException;

	long createReplyItem(String clientToken, PasteItem item, long parentId) throws InvalidClientException, ParentNotFoundException;

	List getItemsForUser(String clientToken, String userToken) throws InvalidClientException;

	PasteStats getStats(String clientToken) throws InvalidClientException;
}

This is the first step in the design, we now have something describing the desired functionality, so we will start by mocking these interfaces.

EasyMock is a handy tool for this, so we simply add the necessary bits and pieces to our pom file and reload the project to get the correct dependencies:

1
2
3
4
5
<dependency>
 <groupId>org.easymock</groupId>
 <artifactId>easymock</artifactId>
 <version>2.4</version>
</dependency>
1
2
3
4
5
<dependency>
 <groupId>org.easymock</groupId>
 <artifactId>easymockclassextension</artifactId>
 <version>2.4</version>
</dependency>

We’ve also made some changes to the initial POM that we created to pull in JUnit version 4.5. Newer versions of JUnit are backwards compatible and add enhancements to your testing such as annotations.

For our first mocks, we start off with extending JUnit’s default TestCase. We add in some convenience methods to help us return a mock Dao and a mock Service.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private PasteItemDao dao;
	private PasteService svc;

	@Test
	public void testMocks() {
		dao = getPasteItemDao();
	 	assertNotNull(getPasteItemDao());
	 	svc = getPasteService();
	 	assertNotNull(getPasteService());
	}

	@Test
	public void testGetLatestItems() throws Exception {
		svc = getPasteService();
		assertNotNull(getPasteService());
		expect(svc.getLatestItems("CLIENT", 10, false)).andReturn(getPastes(10, LanguageType.PASCAL, false));
		replay(svc);
		List returnedList = svc.getLatestItems("CLIENT", 10, false);
		verify(svc);
		assertEquals(10, returnedList.size());
	}

What we are doing here is essentially describing the calls we expect, we replay and call the mocked service and finally we verify and assert that the results are as expected.

While this may seem quite obvious, this will help us in comparing what an implementation will have to return, that the code has coverage and the mocks of these classes actually behave as expected. Once we have full mock coverage we can start implementing the code, and keep looping back to our tests to verify that things work as expected.

Integration and Implementation Tests Once we have a working implementation, covered by our mock tests for expected behavior, the next step to consider are integration tests. Integration tests involve a more complete test involving third party components such as a database or complex services. The focus here is to track down potential errors in our project e.g. configuration files, Dao mapping and entity problems, etc. The tool we consider well thought out and best of breed would help us setup a complete testbed, to include an in-memory database.

Unitils brings together several common tools used separately into a cohesive integration testing framework. It provides the ability to run a Spring context and an in-memory database which we can use to perform full life-cycle tests on all components. These tools let us write tests that will verify our applications behaviour in a real life situation. The value here can be seen later in the project, as it will continue to be referenced throughout the lifecycle of our project. We can use them to hunt down possible bugs, add features without worry of breaking other pieces of our application, or simply maintaining and refactoring the codebase. Yet another benefit is hidden, for it helps new developers on the project understand how everything ties together without the need for a separate, distant, and possibly rarely updated document.

We hunt down our applications Spring configuration file “applicationContext.xml” and make a copy of it and place it in “src/test/resources”. In addition we add a secondary configuration file “applicationContext-test.xml” that overrides the default datasource and supplies a Unitils datasource.

applicationContext-test.xml

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

   <bean id="dataSource" class="org.unitils.database.UnitilsDataSourceFactoryBean"/>

</beans>

We then add a file “unitils.properties” where we define how unitils is supposed to behave.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Properties for the PropertiesDataSourceFactory
database.driverClassName=org.hsqldb.jdbcDriver

database.url=jdbc:hsqldb:mem:mysticpaste-test
database.userName=sa
database.password=

# This property specifies the underlying DBMS implementation. Supported values are 'oracle', 'db2', 'mysql', 'hsqldb' and 'postgresql'.
# The value of this property defines which vendor specific implementations of DbSupport and ConstraintsDisabler are chosen.
database.dialect=hsqldb

## This property specifies the database schema that is used. This schema name is used to qualify all tables when (amongst
# others) clearing / dropping tables / inserting test data.
# NOTE: schema name is case sensitive
database.schemaName=mysticpaste
dbMaintainer.generateDTD.enabled=TRUE
# DbUnit database DTD file path
dtdGenerator.dtd.filename=src/resources/test.dtd

This file will now allow us to move on to an implementation we start with an AbstractBaseTest where we extend a Unitils class called UnitilsJUnit4.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class AbstractIntegrationTest extends UnitilsJUnit4 {

&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp; @SpringApplicationContext({"applicationContext.xml", "applicationContext-test.xml"})
&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp; private ApplicationContext applicationContext;

&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp; /**
&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp; * Method testDoNothing ...
&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp; */
&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp; //This is to keep maven surefire quiet.
&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp; @Test
&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp; public void testDoNothing() {
&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp; //Nothing
&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp;&Acirc;&nbsp; }

}

If you run the test, you will see in the logging output a complete invocation of the spring context, database setup and verification of mapped entities, pretty nifty for an empty test!

We can now move on to testing the actual implementations provided with a full cycle environment.

As we are using Unitils and its Spring utilities we also have handy annotations for injecting our real daos and their implementations into our tests.

Our final test-class that will completely test our environment looks as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class PasteServiceIntegrationTest extends AbstractIntegrationTest {
    @SpringBeanByType
    private PasteService svc;
    @SpringBeanByType
    private PasteItemDao dao;
    // We start with verifying that the DB is correctly setup.
    @Test
    public void testMapping() {
        HibernateUnitils.assertMappingWithDatabaseConsistent();
    }
    @Test
    public void testGetCurrentCount() {
        PasteItem paste = new PasteItem();
        paste.setContent("TEST-DATA");
        paste.setUserToken("USER");
        paste.setClientToken("CLIENT");
        try {
            svc.createItem("CLIENT", paste);
            assertTrue(svc.getItemsForUser("CLIENT", "USER").size() == 1);
        } catch (InvalidClientException e) {
            e.printStackTrace();  //TODO
        }
    }
    @Test
    public void testCreateAndRetrieve() throws InvalidClientException {
        PasteItem paste = new PasteItem();
        paste.setContent("TEST-DATA");
        paste.setUserToken("USER");
        paste.setClientToken("CLIENT");
        Long id = svc.createItem("CLIENT", paste);
        System.out.println(id);
        PasteItem item2 = svc.getItem("CLIENT", id);
        assertEquals(item2.getClientToken(), paste.getClientToken());
    }
}

Voila! We have a complete life cycle test.  These tests of course run somewhat slower than mocks. As tools and aids to rapid development they are quite valuable and will help find elusive bugs and problematic issues.

Read more
Mar 09

Wicket is a Java web application framework which allows “Designers” (people good with Dreamweaver) and “Developers” (people good with Java and Databases) to collaborate on a project with minimal chances of stepping on each other’s toes or wearing each other’s hats.

The beauty of Wicket is that it uses plain xhtml pages as it’s templating markup.  This means that html pages can be loaded into Dreamweaver (or whatever tool the Designer is comfortable with) and they will look very close to the same as they would when rendered on the deployment web server.

Workflow

The basic workflow involved in creating and maintaining html rendered by Wicket is as follows:

wicket-sequence-diagram

  1. The Designer creates the html for the website and fleshes it out with “mock” sections.  For instance in the application we intend to create during our Five Days of Wicket will be a pastebin application called "Mystic Paste". In our application we'll have an “Add Code to Mystic Paste” page, mock data might include some user created content in the textarea of the page.  All css/images, etc... are setup such that if they were to be put on a webserver, everything would work.
  2. The Developer needs to flesh out the dynamic areas of the webpage, that is, he needs to instruct Wicket where it will need to show information from the server.  The developer does this by decorating the designer's html page with special Wicket tags and attributes.  Because these tags and attributes are just considered part of another namespace separate from xhtml's, editors like Dreamweaver and browsers will simply ignore them - It is important to note: The developer will still keep the “mocked” sections of the page intact, this is so the page renders and looks fleshed out on its own.  The mocked sections will be replaced by real data when rendered by Wicket.
  3. The Developer hands the file back to the Designer.  The Designer is free to make further edits, so long as he/she does not remove or manipulate the Wicket tags and attributes present in the file.  If the Designer does need to remove any Wicket tags or attributes, they need to consult the Developer as such an action will “break” the webpage when Wicket renders it.

Example Wicket Page

Here is an example of a Wicket page.  This example was taken from Manning Publishing’s book “Wicket in Action”:



   Cheesr - Making cheese taste beta





<div wicket:id="cheeses" class="cheese"> <h3 wicket:id="name">Gouda</h3> <p wicket:id="description">Gouda is a Dutch... <span wicket:id="price">$1.99</span> <a wicket:id="add" href="#">add to cart</a>
</strong>

Emmental

Emmental is a Swiss che... $2.99 add to cart
</wicket:remove> </div>
...
</div> </div> </body> </html></pre> This looks almost 100% like a normal webpage would look, the only difference is the addition of the “wicket:XXX” attributes and tags sprinkled through the document.  The parts of the document using the special Wicket namespace modifiers will be replaced/removed in the final markup when Wicket renders the page to the user's browser.  Notice the "" element?  This is where your designer can put a "mocked" version of what that area of the page should look like.  You as a developer can take that mocked html and divide it out into a template that is dynamically driven from the backend. Here is how the final page looks if you were to simply load the page into a web browser (or Dreamweaver) from your hard drive: cheesr-wicket

Preparing for Setup

Deviating a bit from the Standard Wicket Convention

One of the first things a developer notices when starting out with Wicket is the convention where Wicket likes having its html template files live at the same level and in the same packages as it's Java source files.  Sure you can jump through hoops to get Wicket to load the html template files from elsewhere but a nice compromise is to simply keep your html template files within the same package directory structure but in a source folder separate from the Java classes.  Why?  Well quite simply to keep your designers (Dreamweaver folks!) from having to grab Java source files along with the html files they are working on.  It will just confuse them and clutter their directories. You can of course stick with the typical "Java source files along side html" convention if you wish, but I find it much cleaner to separate them during design time, and have Maven combine them only at build time into the target war (which it will gladly do automagically).

Project Folder Structure

.
|-- pom.xml
|-- src
|   `-- main
|       |-- filters
|       |-- java
|       |   `-- com
|       |       `-- mysticcoders
|       |           `-- mysticpaste
|       |               |-- model
|       |               |-- persistence
|       |               |   |-- exception
|       |               |   |-- hibernate
|       |               |-- services
|       |               `-- web
|       |                   |-- ajax
|       |                   |-- pages
|       |                   |-- panels
|       |                   `-- servlet
|       |-- resources
|       |   |-- com
|       |   |   `-- mysticcoders
|       |   |       `-- mysticpaste
|       |   |           |-- spring
|       |   |           `-- web
|       |   |               |-- ajax
|       |   |               |-- pages
|       |   |               `-- panels
|       |   `-- log4j.properties
|       |-- sql
|       `-- webapp
|           |-- WEB-INF
|           |-- images
|           |-- js
|           `-- css
  • src/main: maven builds source and resources from this directory to the main deployable target (i.e. our war file)
    • filters: we keep a set of "filters" files that maven can use to interpolate variables at build time. What does this mean? It means that inside your configuration files, the files you use to setup database connections or file paths, you can insert variable place holders like ${db.host}. When maven does a build, it looks up the correct filter file to use and looks for the key=value part corresponding to "db.host" and inserts it into the configuration file for you. This ensures that you are able to configure your application per environment you deploy to (i.e. DEV, QA, PROD, etc...) by having different filter files with the same keys but different values. For more information see Maven's documentation on filtering resource.
    • java/*: this folder will contain all of the application's source code. Everything from the database access code, wicket code and services code for the mysticpaste application (see below).
      • model: all "domain" classes, that is, classes that represent the objects in the application.  For mysticpaste you'll see classes like "PasteItem" which represents an item pasted to the mysticpaste.
      • persistence: at this level of the persistence package a list of interfaces will be kept. The interfaces comprise the basic access layer the services layer will use to save, retrieve and update items to/from the paste bin.
        • exception: the peristence layer needs to tell the services layer when things have gone wrong.  It does this via delcaring and throwing exceptions.
        • hibernate: such is our case, our persistence interfaces will be implemented via the ORM known as Hibernate.  This package will store all of the custom hibernate implementations and hibernate specific classes
      • services: The services layer will be stored here.  Both the generic interfaces and their implementation classes.  The persistence layer will be injected via spring.
      • web: this folder is where our Wicket classes will reside and it's split into several category packages which are as follows:
        • ajax: mysticpaste uses Ajax to render portions of its UI.  The wicket classes which render the xml/html to be injected dynamically into the page are stored here.
        • pages: standard Wicket page classes which are used throughout the application are stored here
        • panels: reusable panel classes are stored here.  Panels may be included within Wicket pages for sake of templating
        • servlet: any run of the mill servlet code we need is stored here.  A good example might be an ImageUploadServlet
    • resources/*: the resources folder will hold our non-java based files.  Noteably html files and spring confguration files
      • spring: Holds any spring configuration files needed to wire the services and persistence layer
      • web: this folder and all subfolders mirror the packages under src/main/java/.../web and hold the .html files that the Wicket page/panel classes use as their templates.  As described above, a "standard" wicket application simply stores the .html files along side their Wicket classes under src/main/java/.../web, however we want to keep these files separate from the Java source so as to keep the directory our designers checkout from version control contianing only the files they need to work on.
    • sql: any sql scripts we need to keep handy for building the mysticpaste database.
    • webapp: this folder will keep the files which live at the base directory of our war file
      • WEB-INF: where you keep your web.xml file
      • images: any image resource, .gif/.png/.jpg files your webapp will reference
      • js: javascript files your webapp will reference
      • css: style sheets your webapp uses
  • src/test/*: All files which reside under this folder are test classes and resources needed to support the tests.  Maven will build everything under src/main/java and add it to the class path of the JUnit or TestNG classes you create.
    • java: JUnit or TestNG test classes which will be run during a build
    • resources: resource files which are needed to support the tests

Getting Started

Since we are using Maven as our build tool we can take advantage of the fact that the fine folks at the Wicket project have created a specialized "archetype"  which creates a skeleton web application complete with a folder structure which mimics roughly what we have outlined above and Maven pom.xml file used to build a war.  The Wicket contributors have even gone one step further and have created a little web page which will, based off a few drop down options, generate the maven command you need to execute in order to create the boiler plate Wicket project.  You can find this web page over on the Apache Wicket site under the "Quick Start" link. [caption id="attachment_190" align="alignnone" width="642" caption="Copying the above Maven command creates a Skeleton Wicket Project"]wicket-archetype1[/caption] To be precise, the command I used was:
mvn archetype:create \
-DarchetypeGroupId=org.apache.wicket \
-DarchetypeArtifactId=wicket-archetype-quickstart \
-DarchetypeVersion=1.3.5 \
-DgroupId=com.mysticcoders \
-DartifactId=mysticpaste
And I ended up with the following folder structure:
.
`-- mysticpaste
    |-- pom.xml
    `-- src
        |-- main
        |   |-- java
        |   |   `-- com
        |   |       `-- mysticcoders
        |   |           |-- HomePage.html
        |   |           |-- HomePage.java
        |   |           `-- WicketApplication.java
        |   |-- resources
        |   |   `-- log4j.properties
        |   `-- webapp
        |       `-- WEB-INF
        |           `-- web.xml
        `-- test
            `-- java
                `-- com
                    `-- mysticcoders
                        |-- Start.java
                        `-- TestHomePage.java
Now obviously we'll have to rearrange a few things, for instance I want my base package to be com.mysticcoders.mysticpaste, but that's easy enough to do once we are in an IDE.  For now, let's test this example webapp out and see if it works.  To do that switch into the mysticpaste directory (the directory that has pom.xml in it) and type the following:
mvn jetty:run
This will start up a Jetty webapp container running on port 8080 (if you have something running there already, use the -Djetty.port= option).  Startup a webbrowser and navigate to http://localhost:8080/mysticpaste/  You should see: jetty-quickstart

Your IDE

Sooner or later you're going to want to crack open your IDE and start hacking away.  Maven makes this extremely easy by allowing you to create IDE specific project files based off of the Maven pom.xml file. Eclipse mvn eclipse:eclipse For eclipse you'll also have to set the M2_REPO classpath variable for the workspace your project resides under.  Do this by entering the following command:
mvn -Declipse.workspace= eclipse:add-maven-repo</pre>
IntelliJ IDEA
mvn idea:idea -OR- in IDEA 7+ simply open the pom.xml file

Netbeans
Netbeans supports maven out of the box, just "Open Project" and choose the mysticpaste directory that contains the pom.xml file

When generating the project files through Maven, the project is setup such that classpath entries point to your local Maven repository (i.e. ~/.m2/repository, or C:Documents and Settingsyourusername.M2repository on Windows).  It also sets up src/main/java, src/main/resources as "source folders".  You may add other folders to the source folder list as per your IDE if needed, the only thing you have to remember is if you ever use mvn eclipse:clean followed by mvn eclipse:eclipse again, those other source folders will have to be readded through your IDE.  Instead, you should add the source/resource folders directly to your pom.xml, this way they will be maintained.

Spring

The Mystic Paste application will use Spring, and really you should too.  Unless you have been hiding under a rock or work in a corporate environment so lame as to which technologies newer than 2002 are forbidden you should learn to accept Spring as a defacto standard.  Dependency injection for the win! We add the following to our pom.xml:

 
    org.apache.wicket
    wicket-spring-annot

 
    org.springframework
    spring

 
    org.springframework
    spring-test

 
    org.springframework
    spring-tx
  1. wicket-spring-annot: allows us to wire our Wicket application via handy dependency injection annotations (i.e. @SpringBean, see Wicket documentation for more detail)
  2. spring: is just the core spring libraries
  3. spring-test: is a set of Spring integration classes for Unit testing
  4. spring-tx: is the Spring Transaction Management api for declarative transactions

web.xml additions for Spring

In order for Spring to manage our Wicket application we need to setup the Wicket filter with a Spring-aware application factory.  This allows us to wire our Wicket Application class in our applicationContext.xml file, which is really handy if you have a services and configuration settings you want to inject into the Wicket Application object so the rest of your application can access them.  To do this, we change the original Wicket filter like so:
    
        wicket.mysticpaste
        org.apache.wicket.protocol.http.WicketFilter
        
            

applicationFactoryClassName

org.apache.wicket.spring.SpringWebApplicationFactory
        
    
As well, we want our Spring context to be available to our webapp if ever there is a need for one of our pages to access the Spring managed beans directly:
    

contextConfigLocation

classpath:com/mysticcoders/mysticpaste/spring/applicationContext.xml
    



          org.springframework.web.context.ContextLoaderListener
        
    

Hibernate

Hibernate is our ORM of choice, it will allow us to persist and retrieve our model objects to and from the underlying database, whatever that database may be. We add the following to our pom.xml:

 
    org.hibernate
    hibernate-annotations

 
    c3p0
    c3p0

 
    commons-dbcp
    commons-dbcp

 
    javax.transaction
    jta
    1.0.1B
  1. hibernate-annotations: used so we can annotate our model classes with mapping information, instead of having to create a separate mysticpaste.hbm.xml file.
  2. c3p0: provides a connection pooling library Hibernate can use
  3. commons-dbcp: another connection pooling library, we'll add it as well and decide whether to use it or c3p0 later
  4. jta: this is the Java Transaction API which is needed by Hibernate (Hibernate provides an implementation of the API)

web.xml additions for Hibernate

To have a Hibernate Session open and ready for our webapplication during a Request Cycle we need to setup a Hibernate filter like so (otherwise, good luck getting lazy loading working!):
    
       open.hibernate.session.in.view
        org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    

    
    
       open.hibernate.session.in.view
       /*
    
As the comment states above, make sure this filter-mapping exists *before* your wicket.mysticpaste filter or else it just plain won't work.

Database

For the Mystic Paste we decided to use the freely available PostgreSQL.  Adding support for PostgreSQL is very easy, unlike with some of the commercial DBMSes where you have to download and install their JDBC driver into your repository.  To add support for Postgres, we simply add the following to our pom.xml:


    postgresql
    postgresql

Servlets

Regardless of which webapplication framework you choose there are just some times when a plain jane Servlet comes in really handy.  If you have a need for Servlets and the Servlet must have access to the Wicket session add the following to your web.xml:
    
        wicket.session
        org.apache.wicket.protocol.http.servlet.WicketSessionFilter
        

filterName

wicket.mysticpaste
        
    
And then, after your other filter-mappings add the following (assuming you mount your servlet-mappings under /servlet/):
    
        wicket.session
        /servlet/*
    

Maven Filters and Profiles

In order to build our Mystic Paste project for various environments (DEV/QA/PROD) we need to implement both Maven profiles and filters.

Filters

Filters allow you to place variables inside your configuration files and have those variables filled in durring build time.  This is very handy for setting environment specific things such as database connection information. Enabling filters is quite easy, we open up the pom.xml file and find the section for and set the value for the element to true as follows:

    
        true
        src/main/resources
    
.
.
.
But for filtering to work, we need to specify a filters file.  It's not enough to specify only one filter file because we need to specify different filters per environment and we'll do that by using Maven Profiles.

Profiles

To setup a profile, create a new set of elements following the section in your pom.xml file. Like so:


    DEV




        DEV


            DEV
        
    


        QA


            QA
        
    


        PROD


            PROD
        
    
and just above your tag underneith your tag you would add the following elements:

    mysticpaste
    
        src/main/filters/filters-${env}.properties
    
    
        
            true
            src/main/resources
        
    
src/main/filters will contain the following files.
|-- pom.xml
|-- src
|   `-- main
|       |-- filters
|       |   `-- filters-DEV.properties
|       |   `-- filters-QA.properties
|       |   `-- filters-PROD.properties
filters-DEV.properties
jdbc.url=jdbc:postgresql://localhost:5432/mysticpaste
jdbc.user=mysticpaste
jdbc.password=password
image.upload.path=/tmp/pasetbin/userimages
image.upload.size.limit=4096K
filters-PROD.properties
jdbc.url=jdbc:postgresql://192.168.2.10:5432/mysticpaste
jdbc.user=mysticpaste
jdbc.password=CrYp71c
image.upload.path=/mysticpaste/userimages
image.upload.size.limit=4096K
Now within any file under src/main/resources that has variables of the form ${variable.name} will have those variables replaced with the values specified in the proper filters file located under src/main/filters.  For instance here is an example of a Spring applicationContext.xml file which will be interpolated with proper variables values at build time: applicationContext.xml
    




    
    
        


    
To determine which filters file will be used depends on the profile chosen when building. For example, to build to production using the filters-PROD.properties we would execute the following:
mvn clean deploy -P PROD
The profile you use with the -P switch must match one of the values of the element for a profile.

Conclusion

Although it's quite easy to get started with the Maven QuickStart project it is sometimes a bit frustrating putting some of the additonal pieces together.  Building to several environments, setting up depenencies not included in the QuickStart project and strucuturing your project in an effort to make life easy for yourself as a developer and for your designer. I hope our Day 1 tutorial leaves you with a good sense of how a Wicket project is setup, now we can move onto coding the app! Article Index...
Read more
Mar 09

5 Days of Wicket!

By kinabalu | Comments

At Mystic, we love our technology, and we love to evangelize the best of the best. We’ve been brewing a cauldron of new ideas, and the latest, is a series of articles surrounding building actual applications with the technology we love, and sharing how it was all done with you.

Our first feature: 5 days of Wicket!

Each day this week will feature a new blog article with an in-depth look at the creation process behind setting up a Java project and implementing the frontend with Apache Wicket. Enjoy.

Read more