Sonar + JaCoCo - Code coverage for both Java and Groovy - java

I'm having some problems to make Sonar display code coverage for tests written in both Java and Groovy. I have a Maven multi-module project where a module can be exemplified like this:
firstServer
src/test/groovy
package1
GroovyTest1.groovy
GroovyTest2.groovy
src/test/java
package2
JavaTest1.java
JavaTest2.java
The pom.xml for firstServer looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<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">
...
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
My Sonar properties are in the parent pom.xml:
<properties>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
</properties>
When I run the command mvn package sonar:sonar and visit SonarQube to see the results, the code coverage only takes java classes into account. I can't see any groovy classes among my unit tests even though I have many of them. I guess that I'm missing something in my POM files but I don't know what. I have read that it is possible to have a mix of Groovy and Java test classes when using Sonar and JaCoCo. My question is simply, what am I missing?
Thanks in advance!

You need to also add the sources and tests configuration:
<sonar.sources>src/main/java,src/main/groovy</sonar.sources>
<sonar.tests>src/test/java,src/test/groovy</sonar.tests>
It seems that the plugin ignores Groovy otherwise.

Install the Groovy plugin in Sonar. Login as admin/admin and go to the administration/system/update-center tab
Add the following property in the pom file
<sonar.tests>src/test/groovy,src/test/java</sonar.tests>

Related

How to deal with dependencies of generated sources in Maven?

For the last few days, I have been trying to get the code for a REST-API client being generated into my project using the openapi-generator-maven-plugin. However, Maven fails in the compile-Phase as soon as it realizes that the third-party dependencies just introduced by the generated code have not been resolved yet. As the code generation itself works, my problem seems to be rather general and related to what's happening after code is being generated.
This is a sample POM, containing the copy-pasted contents of their own README on how to set the plugin up:
<?xml version="1.0" encoding="UTF-8"?>
<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>
<groupId>org.example</groupId>
<artifactId>openapi-generator-maven-plugin-error-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>5.0.0</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v2.0/json/petstore.json</inputSpec>
<generatorName>java</generatorName>
<configOptions>
<sourceFolder>src/gen/java/main</sourceFolder>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Running mvn clean compile should generate the sources, and it does. However, as soon as the maven-compiler-plugin kicks in right after the code is being generated, it sees newly introduced package and symbol references in the generated code and consequently fails.
So I have tried to figure out how to install said dependencies, AFTER generation, but BEFORE compilation, but completely failed to do so. I suspect I need to use the maven-depndencies-plugin, but due to my limited knowledge of Maven and even more limited knowledge of how its plugins work, I am completely lost. I have tried adding the maven-dependency-plugin to my POM, but Maven completely ignores it and does not run it at all. I have tried to bind the resolve goal to the compile phase to no avail.
I would have expected code generation to not be a too uncommon thing to do with Maven, so I am a bit surprised it is actually so hard to pull off. Am I on the right tracks here? What exactly am I missing to have those transitive dependencies introduced in the generated code installed before the compiler is trying to compile them?

Maven Javadoc failed to find my subpackage - 'javadoc: warning - No source files for package'

I have this Maven project. I am trying to have Maven to automatically generate JavaDocs when mvn package is issued. The whole project compiles and packages just fine. It've generated documentation for all of my Java classes that are in the main package just fine but it did not generate documentation for any classes in sub packages. It said that it could not find them.
Exact error message is:
[WARNING] javadoc: warning - No source files for package parser
I've structured my project like this:
pom.xml
src (directory)
main (directory)
java (directory)
parser (directory)
Parser.java
StringParser.java
ByteParser.java
Main.java
Reader.java
The classes Main.java and Reader.java has 'package com.personal.reader;'. The classes in parser directory has 'package com.personal.reader.parser;'. It appears that the error message was saying that it cannot find 'com.personal.reader.parser'.
My pom.xml looks like this: (Deleted some stuff for brevity)
<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>com.personal.reader</groupId>
<artifactId>Reader</artifactId>
<packaging>jar</packaging>
<version>0.1.0</version>
<name>Reader</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<outputDirectory>docs</outputDirectory>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I've tried looking for solutions. Closest thing I've found is this StackOverflow question. There appears to be no clear answer. I've tried compiling the project that was linked in the submitter's answer to see if he had solved it or not. The submitter's project still exhibited same problems as I am having.
I have tried creating the package-info.java file in both src/main/java and src/main/java/parser. That seemed to not work.
I tried messing with maven-javadoc-plugins. I looked into sourceFileIncludes, includeDependencySources, subpackages, and dependencySourceIncludes. None of them seem to work. I might have missed something.
How do I fix this issue of Maven not including the subpackage to generate Javadocs?
It looks like I've found my answer. I'm posting it here so other people who is having the same problem can find it here.
How I did it: I had another go at the sourceFileIncludes tag in the maven-javadoc-plugins. I added this in the plugin in the project pom.xml.
<sourceFileIncludes>
<sourceFileInclude>**/*.java</sourceFileInclude>
</sourceFileIncludes>
The whole plugin in the project pom.xml looks like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<outputDirectory>docs</outputDirectory>
<sourceFileIncludes>
<sourceFileInclude>**/*.java</sourceFileInclude>
</sourceFileIncludes>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
It've successfully generated Javadocs documents off on the classes in the parser directory. I suppose it would also work with other directories or deeper directories. If it doesn't, you can just add another <sourceFileInclude> under the <sourceFileIncludes> group with your own path.
I'm not one hundred percent sure if this is the correct answer but it sure does work fine for me. If someone else have a better solution, please go ahead and post it here.

How to set project version in maven at build time?

I am trying to implement semantic versioning in our project. I tested maven semver plugin but that didn't help me so please don't ask me why. I finally ended up using maven groovy. It works like a charm, however, when I install or deploy the maven project the version in repository is the variable name.
This is despite the fact that all the artefacts and jar files are packaged with correct version.
So please look at my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>
<groupId>com.mytest.test</groupId>
<artifactId>test-tag</artifactId>
<version>${revision}</version>
<description>Test</description>
<properties>
<ChangeType>TO_BE_SET</ChangeType>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<providerSelection>2.0</providerSelection>
<properties>
<script>git describe --abbrev=0 --tags</script>
</properties>
<source>
def tagIt = 'git tag -a vXXXX -m "Auto tagged"'
def changeType = project.properties.ChangeType
def command = project.properties.script
def process = command.execute()
process.waitFor()
def describe = process.in.text.trim()
println "Setting revision to: " + describe
if(!describe.startsWith("v")) {
describe = "1.0.1"
} else {
describe = describe.substring(1)
}
project.properties.setProperty('revision', describe)
</source>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>default-testResources</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
the version is ${revision} a variable name that is being set in groovy script. What groovy code does is getting the last tag from GIT and and then set it to the property 'revision'.
The final jar file has the correct version extracted but when installed into repository, the folder name and jar name are like:
m2\repository\com\mytest\test\test-tag\${revision}\test-tag-${revision}.jar
I tried to default 'revision' to a value using:
<properties>
<revision>1.0.1</revision>
</properties>
but then groovy code setting the value has no effect.
I also tried different phase for the maven groovy plugin, no luck. Have I missed anything? Can anyone please help me on this?
I'd like to mention that as vatbub and StefanHeimberg mentioned I can use versions:set to set the version but this requires me to do an extra commit to GIT which I am trying to avoid, wondering if I can achieve this by writing a maven plugin instead?
With Maven you can set the version at build time with
mvn versions:set -DnewVersion=${bamboo.inject.version}
as #vatbub already commented in your question.
In addition to this i wrote a Shell script that can be used in build pipeline to generate the version according to the maven project version and add the build number from the build server.
https://gist.github.com/StefanHeimberg/c19d7665e8df087845c036fe8b88c4f2
The Script reads the maven project version, add a the build number and writes a text file with all the new numbers that can be used.
The next step is to inject this text file in the Build Pipeline and call the versions plugin as stated above
pom.xml:
something like
<project>
<groupId>ch.stefanheimberg.example</groupId>
<artifactId>your-awesome-app</artifactId>
<version>5.1.2-SNAPSHOT</version>
</project>
or
<project>
<groupId>ch.stefanheimberg.example</groupId>
<artifactId>your-awesome-app</artifactId>
<version>5.1-SNAPSHOT</version>
</project>
Step 1:
./generate_version_txt.sh ${bamboo.buildNumber}
Step 2:
Inject generated version.txt in the build system that all the properties can be used in all tasks / plugins, etc...
In my case Bamboo CI ready the version.txt file and declares the content of the file as environment variables under the bamboo.inject. prefix.
For example ${bamboo.inject.long_version}
Step 3:
Update Maven Project version
mvn versions:set -DnewVersion=${bamboo.inject.version}
Step 4:
Run Maven Build
mvn clean verify
Step 5:
Run Docker build
for example use it also as docker tag version. etc...
docker build --build-arg version=${bamboo.inject.version} --tag your-awesome-app:${bamboo.inject.version} .
Example Dockerfile:
FROM jboss/wildlfy
ARG version
ADD target/your-awesome-app-${version}.war /opt/jboss/wildfly/standalone/deployments/
I know that can be a problem / not possible in your case with the groovy script. but perhaps it is an other view at your problem. and possibly also another solution for it.
(sorry for my english. but i hope it is understandable what i mean)
I ran into a similar problem and ended up using the maven flatten plugin to ensure that all variables are removed from the POMs before being deployed. This remove all references to the string ${revision} and replace by the actual value at build time, without interfering with the original POMs.

Can I force Maven to package a jar despite compilation errors?

So I run maven package to build my dependencies into a jar. However, I need Maven to ignore any compilation errors and package the jar regardless.
How would this be accomplished? My pom.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- Project specific stuff would be here... -->
<build>
<sourceDirectory>wherever</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- etc... -->
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
Searching through SO only showed me how to ignore compilation errors from unit testing. I simply want my package to be compiled despite any errors in the code.
Edit: People seem to be bashing on me. I've been doing Java for 5 years. I know you're not supposed to compile with errors. I know what it entails.
My boss programs with me. He specifically said, "I can compile with errors in Eclipse, so compile with errors in Maven." It's not because I am ignorant, or because I refuse to accept my mistakes. It is because that is what I was specifically ordered to do. I did not ask this question because I am incompetent as many of you would like to assume.
Hate on me all you want, just know that you are doing so unfairly.
Use the exclude option to the compiler plugin to exclude the classes that have compile errors.
Building on Top of #wings Answer
You can use the flag failOnError=false in your pom, too
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<failOnError>false</failOnError>
</configuration>
</plugin>
or via command line
mvn package -Dmaven.compiler.failOnError=false
Maybe this is what you want:
https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#failOnError
Set failOnError=false to ignore compilation errors.
When you run maven package. That means maven will run all phases before "package" phase. Hence maven compile will be triggered for sure. And because of compilation error, maven will stop at "compile" phase.
To package your project even with compilation error. I think you should use "maven assembly plugin" to package your depensencies ONLY and the phase of that plugin should be something before "compile". ex: "process-sources" or "process-resources".
By that way, before maven compiles your project's source code, you will have a bundle which includes all dependencies. Of course, maven will stop at the "compile" phase again. But you already have what you want.
Hope this help.
If it's just about the dependencies there's dependency:copy-dependencies:
Goal that copies the project dependencies from the repository to a defined location.
Use assembly:single with a user-defined descriptor to create the JAR with the dependencies from the location defined above:
Assemble an application bundle or distribution from an assembly descriptor.

Error while compiling when using AspectJ compiler instead of Javac

I have a multi module project. The aspect is currently added to the "core" project. When doing a mvn clean install here it works. However trying to do a mvn clean install on parent project it fails with this error when compiling one of the other projects:
The type org.hibernate.annotations.CacheConcurrencyStrategy cannot be resolved. It is indirectly referenced from required .class files
If I add the Hibernate core dependency in that project too it works, but adding dependencies to projects that shouldn't have the dependency does not make sense - so it is not a solution. When compiling with javac it works fine.
What is the reason? And how can I fix it so I can use the AspectJ compiler without leaking dependencies to projects that shouldn't have that?
I have this configuration in the parent POM:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.5</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<complianceLevel>1.6</complianceLevel>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Update
I just found out. Running mvn clean install fails every time. However, running mvn [clean] install one time fails. Then running mvn install without clean works. I see that the builddef.lst in the target folder is the reason why it works and fails based on whether or not you run clean. So now my question is: How do you automatically generate this file?
Parent POM-file:
<?xml version="1.0" encoding="UTF-8"?>
<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>com.mycompany</groupId>
<artifactId>core-lib</artifactId>
<name>core-lib</name>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.5</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<complianceLevel>1.6</complianceLevel>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
</dependencies>
<modules>
<module>core-xyz</module>
<module>core-xyz2</module>
</modules>
</project>
Enable debug on the maven invocation to dig deeper. You should observe that the aspectj compile is only being invoked during the first maven invocation with the clean. Since the builddef.lst already exists after the first invocation, invoking without clean skips the aspectj compile.
This aspectj compile plugin behavior has been observed previously and was described here:
http://out-println.blogspot.com/2007/08/compile-time-checks-with-aspectj-part-2.html?m=1
You will need to look deeper to address the underlying issue, but as one commenter has already suggested, the aspectj compiler should only be enabled in modules that require it.
Otherwise, the additional dependencies are required for the aspectj compile, as you have already observed. I have incorporated aspectj compile into my own work without issue by restricting it to only the modules that require it.
According to the AspectJ compiler Maven plugin you could set up the argumentFileName to locate an existing builddef.lst.
So you can generate the builddef.lst and copy it to your resources folder, and instruct the AspectJ Maven plugin to use that file.

Categories