czwartek, 14 sierpnia 2008

Wicket and Spring

Sometime ago I was evaluating Wicket usefulness in development of lightweight, AJAX enabled UIs for web applications. Apache Wicket is modern framework for creating web UIs, well known for its original features as HTML/Java pages implementing separation between page view and logic. Other unique feature is global Application object, usually containing business logic entry points.


Wide range of modern applications requires complex, multi-tier backend (logic and storage, possibly remote, wired together with Web Services) and quite simple frontend (with few user actions available). Server part of the backend, along with WS clients is typically developed with Spring. As far as frontend is concerned, Wicket could be the solution to use.


There are many great Wicket manuals and tutorials, so I won't post any Wicket code here. Those interested can just take a look at Wicket Examples :) Other aspect is Wicket-Spring integration. After some research I decided to go with "central point" solution. This integration type assumes that all logic entry points (usually managers and DAOs) should be injected into Application object. Therefore all Pages have convenient access to the logic. This is compromise between annotations (performing all work under cover, without developer knowledge) and using no dependency injection at all. Because Application object is global (and singleton) it reminds somewhat hated Resource Locator solution, but for the sake of simplicity (remember, be agile..) I can accept it.


Required web.xml configuration is as follows:

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
<filter-name>wicket.wicket-demo</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationFactoryClassName</param-name>
<param-value>
org.apache.wicket.spring.SpringWebApplicationFactory
</param-value>
</init-param>
</filter>

With above entries in webapp config, developer is able to inject logic beans to the Applciation object without problems, as in following example:

<bean id="mrDaoBean"
class="apps.WicketMountains.data.MountainRecordDao">
<property name="sessionFactory">
<ref bean="sessionFactoryBean"/>
</property>
</bean>
<bean id="mrManagerBean"
class="apps.WicketMountains.data.MountainRecordManager">
<property name="mrDao" ref="mrDaoBean"/>
</bean>

<!-- setup wicket application -->
<bean id="wicketApplication"
class="apps.WicketMountains.WicketApplication">
<property name="mrManager" ref="mrManagerBean"/>
</bean>

Wicket components can access logic beans using code similar to call:

((WicketApplication)Application.get()).getMountainRecordManager()

One nice feature of the Wicket framework is bunch of ready to use AJAX components with exhaustive description of use. Beginner in Wicket (as myself) is able to develop first useful, pretty, AJAX enabled webapp in few hours only.

czwartek, 7 sierpnia 2008

HSQL: follow-up

It appears that sometimes one would like to use lightweight HSQL for unit / integration testing of his (hers) Spring-aware application. Nothing simpler ;-)
First thing is preparing Spring bean able to manage lifecycle of an instance of the HSQL database. This could be written by hand, but fortunately convenient class is already available in the Springmodules project. Bean implementation is to be found here.
Second thing is Spring XML configuration of the bean. My sample code is as follows:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="org.hsqldb.jdbcDriver"/>
<property name="url"
value="jdbc:hsqldb:hsql://localhost/test"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
<property name="defaultAutoCommit" value="true"/>
</bean>

<bean id="dataBase"
class="springmodules.HsqlServerBean"
singleton="true" lazy-init="false">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="serverProperties">
<props>
<prop key="server.port">9001</prop>
<prop key="server.database.0">
file:webapps/SampleApp/db/test</prop>
<prop key="server.dbname.0">test</prop>
</props>
</property>
</bean>

Configuration is pretty straight-forward. Note that we're using DataSource referring to the database configuration. This is done because:
a) Spring bean requires DataSource to commence db shutdown when container goes down
b) helps encapsulating database properties in one entity
The latter can be used more when Hibernate is also in the game. SessionFactory can be configured to use the DataSource with such code as:

<bean id="sessionFactoryBean" class=
"org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="classpath:hibernate.cfg.xml"/>
<property name="dataSource" >
<ref bean="dataSource"/>
</property>
</bean>


Have fun!

piątek, 25 kwietnia 2008

Simple & fast DB testing

Yes, you're right. This short post is about HSQL - powerful yet surprisingly simple to use, pure-Java RDBMS.
Developing db-related functionalities in Java has never been easier. Using Hibernate's features as on-the-fly schema generation developer can easily stick to changing requirements. But what about testing? Transferring data to and from DB could take considerable amount of time and usage of one, shared, remote db can change test conditions and therefore make results unpredictable.
Solution is straight forward - configure own, isolated DB for all the testing! In Java world there could be only one answer - Hypersonic SQL (HSQL). In simplest example, one could use embedded HSQL running in-memory database.
Only two things are needed to enjoy separated DB test environment:
  • add HSQL to the test class path - using Maven2 it's as simple as adding dependency to project's POM:

    <dependency>
    <groupid>hsqldb</groupid>
    <artifactid>hsqldb</artifactid>
    <version>1.8.0.7</version>
    <scope>test</scope>
    </dependency>

  • configure and start org.hsqldb.Server class.
The latter can be done by writing simple wrapping class:

public class HsqlBootstrap
extends Thread{

private Server server;

public HsqlBootstrap() {
super();
server = new Server();
server.setNoSystemExit(true);

server.setDatabasePath(0, "mem");
server.setDatabaseName(0, "testDb");
}

public void run() {

server.start();
}

public void stopServer() {
server.stop();
}
}

There is of course need for configuring Hibernate to use our new, freshly created DB. Adequate properties could be found on various Hibernate-related sites and include using jdbc:hsqldb:mem:testDb connection string ;-)