środa, 3 czerwca 2009

Maven2 production profiles- follow up

Quick follow up - simple example of POM with build profiles for different environments. Nothing especial - just to show how to insert profiles and group properties.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>pl.jwach.examples</groupId>
<artifactId>example</artifactId>
<packaging>jar</packaging>
<version>0.1.0</version>

<dependencies>
...
</dependencies>
<build>

<finalName>${project.artifactId}-${build.env}-${project.version}</finalName>

<plugins>
...
</plugins>

<resources>
<!-- FILTERED -->
<resource>
<directory>src/main/resources/default</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/lib/*.jar</exclude>
<exclude>**/*.someFiles</exclude>
</excludes>
</resource>
<!-- NOT FILTERED -->
<resource>
<directory>src/main/resources/external</directory>
<filtering>false</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<!-- DEFAULT FILTERS -->
<filters>
<filter>src/main/filters/default/config.properties</filter>
</filters>
</build>

<!-- Filters do not have to show the src/main -->
<profiles>
<profile>
<id>preprod-env</id>
<properties>
<build.env>preprod-env</build.env>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<filters>
<filter>src/main/filters/preprod-env/config.properties</filter>
</filters>
</build>
</profile>
<profile>
<id>prod-env</id>
<properties>
<build.env>prod-env</build.env>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<filters>
<filter>src/main/filters/prod-env/config.properties</filter>
</filters>
</build>
</profile>
</profiles>
</project>

As you can see, all profiles are disabled by default. This is because common configuration with custom properties for local deployment are collected in default profile, as stated in build section of the POM. When additional profile is activated, properties from new filter will override properties from default. Thanks to such solution we can minimize number of disjoint properties and build development product version without any extra effort.

wtorek, 2 czerwca 2009

Maven2 for production development

As many Java devs, I regard Maven2 as a great build tool. After accepting sacrifices of "convention over configuration" approach and getting used to usage of plugins (goals), Maven2 speeds up building/testing/deploying a lot. Yet, it's far more potent than simply "define dependencies - build - package" flow. Authors proudly declare M2 to be "software management tool" and I think I could support such statement (in some parts at least).

Particularly, this post is about M2 build profiles. Declared in POM (or global settings.xml file) profiles can alter project build cycle. They can be active by default (see "activeByDefault" node) or activated by -P command-line switch. Profiles offer unique opportunity - creating versions for different deployment environments totally painless! To achieve this, one can define in each profile:

  • resources to be included. For example, if each environment has different server count, you can provide different configuration files. Or if servers run different hardware/software, you can for example feed them with different JNI libs.
  • sources to be complied. This is useful in example when distributing different debug versions (instrumented/pure on QA/production)
  • Filters! This is one of the simplest and best features. In my case I have to deal with many pre-production environments. Most of them are configured alike,but with different IPs, ports and external services (JNDI, DB pools, RESTs...). But those are properties that can be tokenized and set during filtering, without any additional efforts.
  • build plugins - but having different build steps for different environments seems a bit crazy :)

I should add one useful note - define custom "build env name" property for each profile and include it in final artifact name, just like:

<finalName>${project.artifactId}-${build.env}-${project.version}</finalName>

This will help you maintain ready artifact for your environments.

niedziela, 31 maja 2009

Automate your GUI for free! With Marathon

Some time ago I was struggling with automation of GUI testing. Problem wasn't typical. Regular flow involved loading our (web) service into external (Java) tool emulating real mobile device, browsing fixed set of pages and taking screenshots. Next those screens were examined for rendering defects.

Obviously, this was great target for automation. This seemed as a hard task, as external testing tool didn't have any API or interface to connect my custom code. As a surprise, I found great (and LGPL) tool - Marathon (http://www.marathontesting.com).

First of all, Marathon supports recording scripts (clicked in app GUI!) that could be saved and replayed. Of course this feature isn't perfect, as Java GUIs tends to use multiple frameworks and custom Swing components. But this can be easily fixed with Jython - main language of Marathon scripts. Integrating Java and Python, it enables user to write custom Java code executed within tested application's Virtual Machine. Wow! This gives developer almost unlimited possibilities. Injecting AWT events, emulating mouse clicks and activating isolated Swing components is easy and straight-forward. Still, without application's sources determining applicable components can be difficult. Thankfully, Marathon offers drop-in console that can be used to freeze application and review it's component tree.

To recap, usage of Marathon helped me reduce time necessary for taking service screenshots by 80%. Also, tool proved to be very potent - from automating GUI to testing Swing applications. As every free tool, it has some issues, but advantages of speeding up tedious tasks are very rewarding.

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!