Ant's replaceregexp task in a maven pom file

Since it can be tricky, here’s how Ant’s regexp task can be used in a maven pom file:

<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<tasks>
<echo>Online uncomment of ${basedir}/src/main/resources/beanRefContext.xml</echo>
<copy>
file="${basedir}/src/main/resources/beanRefContext.xml"
todir="${basedir}/target/classes" /&gt;
<replaceregexp>
file="${basedir}/target/classes/beanRefContext.xml"
match="&lt;!--s*(&lt;[^-{2}]+)--&gt;" replace="1"
byline="true" /&gt;
</replaceregexp>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-apache-regexp</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<artifactId>jakarta-regexp</artifactId>
<groupId>jakarta-regexp</groupId>
<version>1.4</version>
</dependency>
</dependencies>
</plugin>

A groovy use case

I recently discovered Spring’s ability to declare beans that are script-based. This feature can be used to mock business interfaces with Groovy implementations. In a JavaEE container where startup and redeployment can take a while, it can be very useful, in pre-integration tests, to change the behaviour of your business services especially without redeploying the whole EAR or restarting the server.Here’s an example declaration:

<bean id="MockServiceImpl" class="org.springframework.scripting.groovy.GroovyScriptFactory">
<constructor-arg value="${mocks.path}/MockServiceImpl.groovy"></constructor-arg>
</bean>
<bean class="org.springframework.scripting.support.ScriptFactoryPostProcessor">
<property name="defaultRefreshCheckDelay" value="2"></property>
</bean>

The “defaultRefreshCheckDelay” parameter sets the delay in seconds between checks for modifications of the script. and the groovy script:

public class MockServiceImpl implements Service {
ProductsReturn returnCase1 = new ProductsReturn(fetchDate:Calendar.getInstance(),products:[new Product(id:1,name:"good")])
ProductsReturn emptyReturn = new ProductsReturn(fetchDate:Calendar.getInstance(),products:[])
ReturnObject listProductsForUser(String userId) {
return returnCase1
}

I see many benefits in this solution:

  • hot-swapping implementations without redeployment.
  • returned objects can be dynamically generated. For instance if you want to return objects depending only one a given parameter it can be done easily.
  • more concise than XML (see xmlstubs a XML based mocking solution).

On a side note, groovy requires ASM 2.2.2 library so if you use hibernate use the cglib with no dependency library which includes asm classes in renamed packages. Also use Spring 2.0.3+ if you use AspectJ pointcut declarations or you can expect errors.With maven profiles it ‘s easy to build a mock and non-mocked service layer of an EAR.Note that you can still inject the real implementations if you want to delegate work to it.

<bean id="MockServiceImpl" class="org.springframework.scripting.groovy.GroovyScriptFactory">
<constructor-arg value="${mocks.path}/MockServiceImpl.groovy"/>
<constructor-arg value="ServiceImpl"/>
</bean>

On an other side note, I like both Groovy and JRuby but now tend to prefer Groovy because it leverages my knowledge of Java API. With Ruby i spend too much time finding the reference web site how to achieve things that i do almost naturally in Java. OTH, Ruby has its core API use closures. Closures are tightly integrated and tend to favor loose coupling.