Cobertura excludes not working in multi-module Maven 3 project - java

I have a multi-module Maven 3 project. We are using Cobertura as our code coverage tool, but the excludes tag is not working. We have some bad tests from a package we inherited from another team, but need to consume.
The structure is as follows:
<module1>
.../com/aaaa/...
<module2>
.../com/aaaa/...
<module3>
.../com/aaaa/...
...
<moduleN>
packages with .../com/xx/... WE WANT TO EXCLUDE
pacakges with .../com/aaaa/... WE WANT TO STILL INCLUDE
parent-pom.xml
Our parent POM is configured as such:
<build>
...
<plugins>
<other plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.6</version>
<configuration>
<aggregate>true</aggregate>
<outputDirectory>coverageReports</outputDirectory>
<instrumentation>
<excludes>
<exclude>**/com/xx/**/*</exclude>
</excludes>
</instrumentation>
/configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.6</version>
<configuration>
<aggregate>true</aggregate>
<outputDirectory>coverageReports</outputDirectory>
</configuration>
</plugin>
</plugins>
</reporting>
I've tried a lot of various configurations, including:
Excluding the test/com/xx files as well
Adding the exclusion pattern to ignore
Setting exclude in the reporting AND build section
Multiple permutations of the exclude file pattern, including being more implicit
Any thoughts? I've had some other build engineers look at my various POM configurations and it always seems valid, but we never get accurate reports.

Put the exclude configuration into the pom.xml file of moduleN that you want to do the exclusions from:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.6</version>
<configuration>
<instrumentation>
<excludes>
<exclude>com/aaa/**/*.class</exclude>
<exclude>com/xxx/**/*.class</exclude>
</excludes>
</instrumentation>
</configuration>
</plugin>

Related

Maven deploy:deploy-file publishes all files instead of one

I am building my Java application using Maven and the Maven Assembly Plugin to create an executable jar.
As a result, the target folder contains multiple jars and other files. However, I only want to deploy the executable jar file built via the Assembly Plugin.
To do this, I have tried to use mvn deploy:deploy-file and provided it with the following properties:
file
repositoryId
url
artifactId
groupId
version
However, when I execute the command, Maven deploys all files instead of only the executable jar.
I also tried disabling the default build step:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<executions>
<!-- disable standard deploy -->
<execution>
<id>default-deploy</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
The build part of my pom.xml looks like this:
<build>
<!--suppress UnresolvedMavenProperty -->
<finalName>${project.artifactId}-${BUILD_DATE}</finalName>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>main.PAtrackMain</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<!--suppress UnresolvedMavenProperty -->
<Implementation-Build>${BUILD_DATE}</Implementation-Build>
</manifestEntries>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>true</appendAssemblyId>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<executions>
<!-- disable standard deploy -->
<execution>
<id>default-deploy</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
How can I deploy only the executable jar without the other files?
That is much simpler than you might think.
There are two kinds of artifacts, produced by maven project:
main: ${artifactId}-${version}.${packaging} - this one you would like to not publish
supplemental: everything else produced by plugins (javadoc, sources, assembly, etc)
If project/module packaging is pom, that means following:
project/module may not have main artifact, only supplemental ones
some plugins are not enabled by default (https://maven.apache.org/ref/3.8.6/maven-core/default-bindings.html - compare default bindings for pom and jar packaging)
Thus, all what you need is:
switch module packaging from jar to pom
enable missing plugins: maven-compiler-plugin, maven-resources-plugin, maven-jar-plugin, etc
extra configuration of maven-deploy-plugin is not required

Generating filtered resources from the maven sources:jar execution

I would like to generate a sources jar file for my project, so I have included the maven-source-plugin. However, I am also using the resource filtering plugin to set a version number in a property file for my project. When I generate a final jar file, the property file has been filtered and the version is set. However in the sources jar, is still has the unfiltered property. I would like for the sources plugin to also invoke the resource filtering. How can I do this?
Here is (part) of my pom.xml
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
and here is the property file that I want filtered in
version = ${project.version}
EDIT
For clarification, the root of my issue is that I have another project that is a GWT project built using this library. Part of the requirements of a GWT project is that the source code has to also be made available for anything that is going to be compiled to client side javascript. Therefore, this project contains both the compiled jar and the sources jar in the classpath.
So there are now two properties files with the same package path and name, one exists in the compiled jar and one in the sources jar.
When I attempt to read this file, it seems to pick the properties file out of the sources jar, which has not been filtered.
Normally, you'd use the maven-source-plugin for this. However, I see in its documentation that you cannot remove src/main/resources from its processing, while simultaneously adding target/classes to its processing cycle (which is what you would need to do in order to accomplish your task)
Therefore, I think your best bet is through a maven-assembly-plugin configuration.

Maven - Import Plugins configuration from one project to another using maven-tiles

In order to use the same configuration of a maven plugin in many projects, I am trying to define this configuration in one core project, and then import it to the other projects.
Basing my solution on this discussion, I used Maven Tile Plugin, and I followed the steps that were explained in the documentation.
Definition of the configuration in the core project:
1) pom.xml:
<build>
<plugins>
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.8</version>
<extensions>true</extensions>
<configuration>
<filtering>true</filtering>
</configuration>
</plugin>
</plugins>
</build>
2) tile.xml:
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<!-- .... -->
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<!-- .... -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
3) Build the core project
Import of the configuration in the targeted project:
In the parent POM:
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.8</version>
<configuration>
<buildSmells>pluginmanagement</buildSmells>
<tiles>
<tile>groupId:coreProjectId:1.1.0</tile>
</tiles>
</configuration>
</plugin>
From what I understand, the import of the core project using the tile plugin must allow the use of the configuration that was defined for the maven failsafe plugin. The problem is that the verify goal of the failsafe plugin isn't working that way (No integration Test is run with 'mvn verify')
Any suggestion to well define the maven tile plugin, or to use any other method to reuse the core configuration would be helpful.
Thank you for your help.
The buildSmells tag should be defined in the core project instead of the target project.
This is how the pom.xml should configured in the core project:
<build>
<plugins>
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>${plugin.tiles.version}</version>
<extensions>true</extensions>
<configuration>
<buildSmells>pluginmanagement</buildSmells>
<filtering>true</filtering>
</configuration>
</plugin>
</plugins>
</build>

How to specify pluginList as maven dependencies for findbugs-maven-plugin

I would like to know if there is a way to specify findbugs attribute for plugins, pluginList as maven dependencies instead as a file path.
I mean, if I use this configuration:
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.3</version>
<configuration>
<xmlOutput>true</xmlOutput>
<xmlOutputDirectory>target/site</xmlOutputDirectory>
<pluginList>/my/path/fb-contrib-6.2.3.jar</pluginList>
</configuration>
</plugin>
</plugins>
</reporting>
Findbugs load the plugins jar and analyze the code as I want. But as you can see, jar location is a fixed path. I would like to use something like this:
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.3</version>
<configuration>
<xmlOutput>true</xmlOutput>
<xmlOutputDirectory>target/site</xmlOutputDirectory>
<pluginList>
<dependency>
<groupId>com.mebigfatguy.fb-contrib</groupId>
<artifactId>fb-contrib</artifactId>
<version>6.2.3</version>
</dependency>
</pluginList>
</configuration>
</plugin>
</plugins>
</reporting>
Obviously, the last configuration does not work, but it is more convenient from a Maven point of view.
Yes you can do it with the <plugins> parameter, and not <pluginList>.
Quoting the documentation:
The pluginList option specifies a comma-separated list of optional BugDetector Jar files to add.
...
The plugins option defines a collection of PluginArtifact to work on.
A sample configuration would be:
<configuration>
<plugins>
<plugin>
<groupId>com.mebigfatguy.fb-contrib</groupId>
<artifactId>fb-contrib</artifactId>
<version>6.2.3</version>
</plugin>
</plugins>
</configuration>

cobertura-maven-plugin excludes configuration

I have a Maven project with a test case DefaultViewTypeToFragmentMapperTest.java in the directory /src/test/java/test/com/mycompany/myproduct/android/viewtype2fragmentmapper/.
I want this test case to be excluded from unit test coverage calculation. In order to achieve this result, I configured the plugin like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<formats>
<format>html</format>
<format>xml</format>
</formats>
<instrumentation>
<excludes>
<exclude>test/co/**/*.class</exclude>
</excludes>
</instrumentation>
</configuration>
</plugin>
But I still see the aforementioned class in the coverage report.
How can I fix it such that the test case does not appear in the report and its coverage (0 % according to the report) is not taken into account?
After a lot try and fail I got it working.
Edit the pom.
mvn clean test-compile
mvn cobertura:cobertura
Reopen the page from Firefox. (make sure the page is not cached)
I got it working with:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.6</version>
<configuration>
<instrumentation>
<excludes>
<exclude>aaa/**/*.class</exclude>
<exclude>com/test/bbb/**/*.class</exclude>
</excludes>
</instrumentation>
</configuration>
</plugin>
Change 'aaa' with the beginning of the package name to be excluded.
Change 'bbb' with your package name that you want to exclude from the report.
I hope it helps,
Marc Andreu
You should use the <ignore> tag.
<configuration>
<instrumentation>
<ignores>
<ignore>com.example.boringcode.*</ignore>
</ignores>
</instrumentation>
</configuration>
<exclude> used within <instrumentation> simply excludes the package from what your instrumenting. Which in this case, is nothing because you're not doing anything.
Please see the Mojo Maven Cobertura Plugin docs here.
Is it a typo?
<exclude>test/co/**/*.class</exclude>.
The co should be com.
BTW, <ignores> instructs Cobertura to ignore any calls to any method that matches the ignore regular expression. It will NOT skip over these classes during instrumention. To exclude classes from being instrumented, <excludes> should be used.
You should not append the .class as the following example
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<formats>
<format>html</format>
<format>xml</format>
</formats>
<instrumentation>
<excludes>
<exclude>test/co/**/*</exclude>
</excludes>
</instrumentation>
</configuration>
</plugin>
I hope this may help.
I just lost two hours of my life getting an exclusion for Cobertura to be excluded, but finally succeeded.
The solution I found is that the plugin configuration with instrumentation & exclusion for the cobertura-maven-plugin MUST be in the build/plugins or build/pluginManagement chapter of the pom, while there also must be a reference to the cobertura-maven-plugin in the reporting chapter.
The pitfall here is that you initially start with defining the plugin at the reporting chapter, otherwise no report is generated. But the instrumentation itself doesn't pick up any configuration from that part of the pom. You need to define that within the build chapter.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.7</version>
<configuration>
<instrumentation>
<excludes>
<exclude>my/exclusion/package/**</exclude>
</excludes>
</instrumentation>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
</plugin>
</plugins>
</reporting>
In addition to BertKoor's answer, I'd like to point out that if you're executing mvn cobertura:cobertura or mvn cobertura:cobertura-integration-test directly, your report will still include coverage on all instrumented classes found in your target directory, as reported here!
If this is the case, make sure you do mvn **clean** cobertura:cobertura in order to clean up the target dir from a previous build first, and then instrument and run your tests.

Categories

Resources