cobertura on maven multi module project

As of version 2.6, there is an aggregate option that can be set to true in the parent pom:

<reporting>
<plugins>
  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>cobertura-maven-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <outputDirectory>./target/tmpCobertura</outputDirectory>
        <formats>
            <format>html</format>
        </formats>
        <aggregate>true</aggregate>
    </configuration>
  </plugin>
</plugins>
</reporting>

We don't have sonar here and right now, we cant install it. So i had to find a workaround and got one. This solution works with a simple mvn clean install -DrunCobertura=true in a multi module project. You only need to add this profile to your super pom.xml of your project, define the working.dir property and it should work.

<profile>
    <id>runCobertura</id>
    <activation>
        <property>
            <name>runCobertura</name>
            <value>true</value>
        </property>
    </activation>
    <properties>
        <cobertura.format>html</cobertura.format>
        <cobertura.working.dir>${working.dir}/${project.version}/cobertura</cobertura.working.dir>
        <cobertura.complete.ser.file>${cobertura.working.dir}/complete.ser</cobertura.complete.ser.file>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>2.4.1</version>
                <inherited>false</inherited>
                <configuration>
                    <filesets>
                        <fileset>
                            <directory>.</directory>
                            <includes>
                                <include>cobertura.ser</include>
                            </includes>
                        </fileset>
                        <fileset>
                                <directory>${cobertura.working.dir}</directory>
                            </fileset>
                    </filesets>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.7</version>
                <executions>
                    <execution>
                        <id>cobertura-Instrument</id>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <taskdef resource="tasks.properties"/>
                                <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
                                <if>
                                    <available file="${project.build.outputDirectory}"/>
                                    <then>
                                        <cobertura-instrument>
                                            <fileset dir="${project.build.outputDirectory}">
                                                <include name="**/*.class"/>
                                            </fileset>
                                        </cobertura-instrument>
                                    </then>
                                </if>
                            </target>
                        </configuration>
                    </execution>
                    <execution>
                        <id>cobertura-createCombinedSerFile</id>
                        <phase>generate-test-sources</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <taskdef resource="tasks.properties"/>
                                <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
                                <if>
                                    <available file="${cobertura.complete.ser.file}"/>
                                    <then>
                                        <cobertura-merge datafile="${basedir}/tmp.ser">
                                            <fileset file="${cobertura.complete.ser.file}"/>
                                            <fileset file="${basedir}/cobertura.ser"/>
                                        </cobertura-merge>
                                        <move file="${basedir}/tmp.ser" tofile="${basedir}/cobertura.ser"/>
                                    </then>
                                </if>
                            </target>
                        </configuration>
                    </execution>
                    <execution>
                        <id>cobertura-copyResultSerFileAndSources</id>
                        <phase>test</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <taskdef resource="tasks.properties"/>
                                <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
                                <if>
                                    <available file="${basedir}/cobertura.ser"/>
                                    <then>
                                        <move file="${basedir}/cobertura.ser" tofile="${cobertura.complete.ser.file}"/>
                                        <mkdir dir="${cobertura.working.dir}/source"/>
                                        <if>
                                            <available file="${basedir}/src/main/java"/>
                                            <then>
                                                <copy todir="${cobertura.working.dir}/source">
                                                    <fileset dir="src/main/java">
                                                        <include name="**/*.java"/>
                                                    </fileset>
                                                </copy>
                                            </then>
                                        </if>
                                        <cobertura-report datafile="${cobertura.complete.ser.file}" format="${cobertura.format}" destdir="${cobertura.working.dir}/report">
                                            <fileset dir="${cobertura.working.dir}/source"/>
                                        </cobertura-report>
                                    </then>
                                </if>
                            </target>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>net.sourceforge.cobertura</groupId>
                        <artifactId>cobertura</artifactId>
                        <version>1.9.4.1</version>
                    </dependency>
                    <dependency>
                        <groupId>ant-contrib</groupId>
                        <artifactId>ant-contrib</artifactId>
                        <version>20020829</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>net.sourceforge.cobertura</groupId>
            <artifactId>cobertura</artifactId>
            <version>1.9.4.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</profile>

What does it do:

1. @process-classes-Instrument the compiled classes of the module.

2. @generate-test-sources-Merges the .ser file from previous modules with the created one of this module to get the complete code coverage.

3. @test-Creates the code coverage report. Should be called in the last module, but due to the fact that the last module can change, i call it always and the previous reports will be overwritten. If you use the report in xml format (for Jenkins) it's fast, so it doesn't matter.