niedziela, 28 czerwca 2009

Groovy!

Most of java devs have already heard about (not-so-new) JDK based dynamic language - Groovy. It's first announcement didn't make an impression on me, as it seemed to me as "one among many". I became interested in it only after presentation on GeeCON (site).
Especially I asked myself - maybe it can prove useful for testing ? Many agilers know that one of biggest obstacles in implementing TDD in company is that no one really wants to write tests - as it takes precious time. Groovy posses some interesting features which can make testing simpler - and faster! In my opinion, following ones are noteworthy:

  • closures - passing block of logic code to always-required try catch finally (try-catch) block in IO operations is quite convenient (of course closures are far more potent); also "it" keyword for first argument to shorten closure declaration is one neat trick
  • "spread dot" operator - no more for-each loops only to obtain one property value from a collection!
  • safe navigation operator "?." (aka Elvis :) ), shortening few access lines into one
  • additional helper methods, as findAll(), every(), any(), collect()

What I really like in Groovy testing idea is that it shortens TDD development time without sacrificing quality of the final product. Typically, overusing Groovy's shortening syntax in production code would be like shooting self in foot, as it would make code more error-prone and less maintainable. But this can't be applied to test code, as it serves different purpose and in fact could be, let's say, lesser quality that production one.
For those interested I really recommend short presentation about Groovy from GeeCON by Vaclav Pech. You can find it here

ś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.