Skip to content

Amazon SWF, aspectj-maven-plugin and JaCoCo

Which could be subtitled as “6+ hours of my life I will never get back”.

I’m leaving this here in case someone else finds it useful. The short story is thus: I’m working on a product using the Amazon Flow SDK, writing in Eclipse under Java 7. We use Maven and JaCoCo, and believe in TDD, high levels of code coverage, and code that doesn’t suck. It turns out that getting all these bits to work together is far more complex than it has any reason to be.

There were several conflicting problems: the AspectJ AOP tool was not successfully dealing with the @Asynchronous annotation on my Workflow implementation, which meant that tests were failing. Various attempts to get that working resulted in the aspectj-maven-plugin failing in various horrible ways, JaCoCo instrumentation failing in various horrible ways, or both.

Here’s an edited version of the pom.xml to show I sorted it in the end (which reminds me that I need a better way of adding code snippets here)

<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/xsd/maven-4.0.0.xsd">
	<modelversion>4.0.0</modelversion>

	<parent>
		<!-- snip: the parent pom contains base definitions for JaCoCo -->
	</parent>

	<artifactid>XXXX</artifactid>
	<version>1.0.0-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>XXX</name>
	<url>https://...</url>

	<description>
	</description>

	<scm>
		<!-- snip -->
	</scm>

	<properties>
		<!-- snip -->
	</properties>

	<dependencies>
		<!-- snip -->
		<dependency>
			<groupid>org.aspectj</groupid>
			<artifactid>aspectjrt</artifactid>
			<version>1.7.3</version>
		</dependency>

		<dependency>
			<groupid>com.amazonaws</groupid>
			<artifactid>aws-java-sdk-flow-build-tools</artifactid>
			<version>1.5.2</version>
		</dependency>

		<dependency>
			<groupid>com.amazonaws</groupid>
			<artifactid>aws-java-sdk</artifactid>
			<version>1.5.2</version>
		</dependency>

		<dependency>
			<groupid>org.freemarker</groupid>
			<artifactid>freemarker</artifactid>
			<version>2.3.20</version>
		</dependency>
	</dependencies>

	<build>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
			</resource>
		</resources>

		<plugins>
			<plugin>
				<groupid>org.codehaus.mojo</groupid>
				<artifactid>aspectj-maven-plugin</artifactid>
				<version>1.4</version>
				<configuration>
					<showweaveinfo>true</showweaveinfo>
					<source>1.7</source
					<target>1.7</target>
					<xlint>ignore</xlint>
					<compliancelevel>1.7</compliancelevel>
					<encoding>UTF-8</encoding>
					<verbose>true</verbose>
					<aspectlibraries>
						<aspectlibrary>
							<groupid>com.amazonaws</groupid>
							<artifactid>aws-java-sdk</artifactid>
						</aspectlibrary>
					</aspectlibraries>
					<sources>
						<basedir>src/main/java</basedir>
						<includes>
							<include>com/xxx/yyy/workflow/*.java</include>
							<include>com/xxx/yyy/workflow/activities/*.java</include>
						</includes>
					</sources>
				</configuration>

				<executions>
					<execution>
						<goals>
							<goal>compile</goal>
							<goal>test-compile</goal>
						</goals>
					</execution>
				</executions>

				<dependencies>
					<dependency>
						<groupid>org.aspectj</groupid>
						<artifactid>aspectjrt</artifactid>
						<version>1.7.3</version>
					</dependency>
					<dependency>
						<groupid>org.aspectj</groupid>
						<artifactid>aspectjtools</artifactid>
						<version>1.7.3</version>
					</dependency>
				</dependencies>
			</plugin>

			<plugin>
				<groupid>org.jacoco</groupid>
				<artifactid>jacoco-maven-plugin</artifactid>
				<executions>
					<execution>
						<id>prepare-agent</id>
						<goals>
							<goal>prepare-agent</goal>
						</goals>
					<configuration>
						<excludes>
							<exclude>**/aspectj/*</exclude>
						</excludes>
					</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

The key bits are using the correct versions of AspectJ and the maven plugin, correctly specifying Java 1.7 everywhere possible, and then telling the JaCoCo plugin which classes to exclude when attempting to instrument. This solution is not perfect, and I don’t expect it to be the final solution, as it results in JaCoCo cheerfully reporting that classes generated by the Flow SDK annotation processor have no coverage, but it’s better than a poke in the eye with a decaying ferret.

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*