sonarqube + lombok = false positives - sonarqube

import lombok.Data;
#Data
public class Filter {
private Operator operator;
private Object value;
private String property;
private PropertyType propertyType;
}
For code above there are 4 squid:S1068 reports about unused private fields. (even they are used by lombok generated getters). I've seen that some fixes related to support of "lombok.Data" annotation have been pushed, but still having these annoying false positives.
Versions:
SonarQube 6.4.0.25310
SonarJava 4.13.0.11627
SonarQube scanner for Jenkins (2.6.1)

This case should be perfectly handled by SonarJava. Lombok annotations are taken into account at least since version 3.14 (SONARJAVA-1642). The issues you are getting are resulting from a misconfiguration of your Java project. No need to write any custom rules to handle this, this is natively supported by the analyzer.
SonarJava reads bytecode to know which annotation are used. Consequently, if you are not providing bytecode from your dependencies, on top of bytecode from your own code, the analyzer will behave erratically.
In particular, setting property sonar.java.libraries should solve your issue. Note that this property is normally automatically set when using SonarQube maven or gradle scanners.
Please have a look at documentation in order to correctly configure your project: https://docs.sonarqube.org/display/PLUG/Java+Plugin+and+Bytecode

I added following property to Sonar analysis properties file. And it works for me.
sonar.java.libraries=${env.HOME}/.m2/repository/org/projectlombok/lombok/**/*.jar
lombok v1.16.20 is lombok version on my project.

I'm using sonar-maven-plugin 3.4.0.905, lombok 1.16.18, with SonarQube CE Server v8.3.1.
I resolved the issue by adding
<sonar.java.libraries>target/classes</sonar.java.libraries> to the POM properties.

The answer suggested by Wohops and Barış Özdemir worked for me. Posting this answer because in my scenario, it took some time to figure out how to implement it because my CI builds are running in Travis and we don't know the path where the lombok-x.x.x.jar file will be downloaded because there is no much control we have on travis environment where the build runs.
I used my build tool (Gradle) to implement it. Following configuration in build.gradle ensured that as part of building of the project, all the jar dependencies get copied to ${buildDir}/output/libs
task copyToLib(type: Copy) {
into "${buildDir}/output/libs"
from configurations.runtime
}
build.dependsOn(copyToLib)
And then as mentioned in the previous answers, I configured the property in the sonar-project.properties file to this libs directory.
sonar.java.libraries=/home/travis/build/xxxxxx/build/output/libs/lombok-1.16.20.jar
Hope this helps.
Cheers.

You can configure the ignore issue rules:
sonar.issue.ignore.multicriteria=e1
sonar.issue.ignore.multicriteria.e1.ruleKey=java:S1068

Related

Primitive Axon App run as Fat JAR Doesn't Autoconfigure Axon Beans

PROBLEM:
RESEARCH: At https://gitlab.com/ZonZonZon/simple-axon.git I've made up a simple Axon-app to show that JAR-artifact built with Gradle-plugin com.github.johnrengelman.shadow doesn't autoconfigure Axon beans when (when run as JAR). Though it runs fine under Intellij.
From project root in terminal:
run gradle clean build shadowJar;
java -jar build/simpleaxon.jar;
Stacktrace is enclosed here. I expect that Axon Autocongiguration provides beans like CommandBus, Snapshotter and other by default.
QUESTION: How to autoconfigure default axon beans in a fat jar?
So, this took my some investigation to get a hunch what is going wrong, but I know what the problem is.
Quick notice, it's not an Axon specific thing, rather the plugin you are using.
I ran your sample project and indeed ended up with the same result; no Axon beans were being wired, ever. That led me to investigate the process of creating fat JAR's step by step. First Maven, then Spring Boot with Maven, then Gradle with Spring Boot and finally with the Shadow plugin you are referring too.
This endeavour landed me on this issue, which states as much as "projects which require the use of META-INF files need to add this to the shadow plugin, and this should be documented".
The portion referenced through this is the following:
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
// Left out all other specifics from your 'build.gradle' file
shadowJar {
// Required for Spring
mergeServiceFiles()
append 'META-INF/spring.handlers'
append 'META-INF/spring.schemas'
append 'META-INF/spring.tooling'
transform(PropertiesFileTransformer) {
paths = ['META-INF/spring.factories' ]
mergeStrategy = "append"
}
setArchiveFileName("simpleaxon.jar")
getDestinationDirectory().set(new File(projectDir, "./build"))
}
After adding that piece of logic to your build.gradle file, I could run your sample project as expected.
I've hit a similar issue when using Axon in a multimodule Gradle project. The app would not work when packaged and worked fine in IDE. The exact error I was getting was
org.axonframework.messaging.annotation.UnsupportedHandlerException: Unable to resolve parameter 0 in handler
The reason for this was because ParameterResolverFactories were not loaded due to the META-INF/services resources not being resolved correctly in the shadow jar plugin as #Steven hinted.
I've managed to fix it with simply (using Kotlin DSL in Gradle):
tasks.shadowJar {
mergeServiceFiles()
}
#Steven 's solution was the only one working for me, after searching for a long time for other solutions.
The Gradle Kotlin Version looks like this https://github.com/spring-projects/spring-boot/issues/1828#issuecomment-607352468:
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
plugins {
id("com.github.johnrengelman.shadow") version "7.1.2"
}
...
tasks.shadowJar {
// Required for Spring.
// The shadowJar plugin should merge the services correctly, but it doesn't!
mergeServiceFiles()
append("META-INF/spring.handlers")
append("META-INF/spring.schemas")
append("META-INF/spring.tooling")
transform(
PropertiesFileTransformer().apply {
paths = mutableListOf("META-INF/spring.factories")
mergeStrategy = "append"
})
}

Gradle Kotlin DSL: get sourceSet of another project

Currently, we're trying to migrate our existing build.gradle scripts to the new Kotlin DSL. Right now, we are struggling with the jar task configuration.
Our project is a simple multi-project. Let's say we've Core and Plugin and Plugin uses classes from Core. Now, when building Plugin, the target jar should include any used classes from Core.
This is how it looked like before:
jar {
from sourceSets.main.output
from project(':Core').sourceSets.main.output
}
And this is the current solution we've with Kotlin DSL:
val jar: Jar by tasks
jar.apply {
from(java.sourceSets["main"].allSource)
from(project(":Core").the<SourceSetContainer>()["main"].allSource)
}
However, the above example just gives me an Extension of type 'SourceSetContainer' does not exist. Currently registered extension types: [ExtraPropertiesExtension] error. I've also tried other code snippets I've found, but none of them have been working so far.
I have also tried this (like suggested in the first answer):
val jar: Jar by tasks
jar.apply {
from(java.sourceSets["main"].allSource)
from(project(":Core").sourceSets.getByName("main").allSource)
}
But then the IDE (and also the jar task) argues that sourceSets is not available: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public val KotlinJvmProjectExtension.sourceSets: NamedDomainObjectContainer<DefaultKotlinSourceSet> defined in org.gradle.kotlin.dsl.
I hope that someone can help us, because it is very frustrating to spend hours in configuration instead of writing any usefull code.
Thank you very much in advance.
You can access the SourceSetContainer by
project(":Core").extensions.getByType(SourceSetContainer::class)
it seems <T : Any> Project.the(extensionType: KClass<T>): T looks in the convention of the project, while val Project.sourceSets: SourceSetContainer get() looks in the extensions ExtensionContaier instead. This is somewhat odd, as the documentation for the says "Returns the plugin convention or extension of the specified type."
Note that you may need to do your sourceSet manipulation in gradle.projectsEvaluated, because otherwise the sourceSet in question may not be configured yet if the corresponding project is not yet evaluated.
If you get access to the project, then everything should looks like your actual groovy gradle script:
project(":Core").sourceSets.getByName("main").allSource
So regarding your actual code:
val jar: Jar by tasks
jar.apply {
from(java.sourceSets["main"].allSource)
from(project(":Core").sourceSets.getByName("main").allSource)
}

Honoring #SuppressWarnings with the sonar checkstyle plugin

Is there any possibility to configure SonarQube 5.1 with Checkstyle plugin to honor the #SuppressWarnings("deprecation") annotation. I do not want to turn off 'Avoid use of deprecated methods' rule, I just want to SonarQube honor the #SuppressWarnings annotation.
I have a Java code in which I need to use deprecated createValidator() method as following:
#SuppressWarnings("deprecation")
#Override
public javax.xml.bind.Validator createValidator() throws JAXBException {
return contextDelegate.createValidator();
}
Java compiler does not warning when compiling code, but unfortunately SonarQube with CheckStyle plugin rise a issue:
squid:CallToDeprecatedMethod
Avoid use of deprecated methods
Squid is a different kind of beast. As suggested in the SonarQube docs, you'll have to use a slightly different syntax, e.g.:
#SuppressWarnings("squid:CallToDeprecatedMethod")
The string squid:CallToDeprecatedMethod is the SonarQube rule key.
Unfortunately, this means adding two annotations to effectively suppress the deprecation warning. But afaik, it's the only way short of disabling the rule.
Squid is a name or number of Sonar Rule, no relationship to checkstyle, all checkstyle rules are described at http://checkstyle.sourceforge.net/checks.html

Spring Tool Suite 3.7.0 not reading #ConfigurationProperties for content assist in YML

Hi I have move on to spring tool suite 3.7.0 with the highly anticipated feature of YAML editor as described here https://spring.io/blog/2015/06/30/spring-tool-suite-3-7-0-released specially the content assist that it provides .
The issue I am having is that my properties class as below
#ConfigurationProperties(prefix="datasource.ucp")
#Data
public Class DumbProperties{
private String url;
private String user;
...
}
does work but when I open my application.yml I still have to provide these manually the content assist doesnt work .ALso STS givem me a warning that the property doesnt exists .Screen shot below
ALso the maven entry for the same to find #ConfigurationProperties are added as below
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
anything I am missing here!!
Two things have to be in place for the configuration properties in your own source-code to work.
The "spring-boot-configuration-processor" must be on the classpath
The project must be confgure properly so that Eclipse JDT Annotation Processing is enabled to run the spring-boot-configuration-processor as part of an eclipse workspace build.
It sounds like you have 1. so probably its number 2. that's missing.
Normally, 2. should be configured automatically by STS, but it does this as part of m2e project configuration. If you just added the configuration-processor by pasting the xml into your pom, then its likely the project-configurator has not yet been executed. So try forcing it by selecting "Update Project" from the "Maven" context menu (accessed by right click on your project).
If that doesn't help, we'll have to troubleshoot a bit more as I don't know what's missing from your project's setup.

MavenProject: Get the available classes for use on my plugin

I'm loading a Maven project as described here. I'm trying to figure out how I can retrieve the source roots so I can figure out the Java classes I have so my Mojo can use them.
I tried a couple of the methods in there, like getResources or getScriptSources without luck. Any idea?
Thanks in advance!
Edit:
I was asked to elaborate a little bit in what I'm attempting to do, so here it is:
The plugin I'm developing will take the sources in the project and create test cases from those. Unless configured, I want to generate tests for all the classes, and for that, I need to somehow figure out where are my sources so I can configure properly.
Hope that helps.
Here's the repository. I planned on publishing it later but I provided source as requested.
Have you read the plugin developers documentation?
That page will link to Plugins Cookbook which links to Mojo Developer Cookbook which has The maven project, or the effective pom. and gives you access to org.apache.maven.project.MavenProject object via
/** #parameter default-value="${project}" */
private org.apache.maven.project.MavenProject mavenProject;
Alternatively via Java 5 annotations
#Component
MavenProject project;
You can call getCompileSourceRoots() to get a list of the directories that will be used for compilation.
You will also need to do more reading about how to setup inclusion/exclusions. You can use other plugins as examples of how to do this, e.g. maven-compiler-plugin
If you want to use annotations, it is very important to make sure your pom is configured as per using annotations and that you use annotations at the class level as well. Mixing javadoc annotations might not work.
I think the simplest solution would be to define a mojo parameter:
/**
* #parameter default-value="${project.build.sourceDirectory}"
* #required
*/
private File sourceDirectory;
or with new annotation based definition:
#Parameter(required = true, defaultValue="${project.build.sourceDirectory}"}
private File sourceDirectory;
which should give your wished result.

Resources