How to Run SonarQube Findbugs Analysis for a project with multiple source directories - maven

I have one multimodule maven project where there are source directories apart from 'src' where java file resides.
This is the folder structure
folder1
-pom.xml
pom.xml Contains modules defined like this:
<modules>
<module>module1</module>
<module>module2</module>
<module>module3</module>
<module>module4</module>
<module>module5</module>
<module>module6</module>
<module>module7</module>
<module>module8</module>
<module>module9</module>
<module>module10</module>
</modules>
Different modules are organized like this:
module1
-src
-gen
module2
-src
module3
-gen
module4
module5
-src
-gen
So, as you see, there are modules/projects which have either src or gen or both or doesn't have any of it.
When I run findbugs analysis, it picked only java classes from 'src' and skipped 'gen' (Natural as Maven model forces the analyzer to pick from only src)
So, in the Jenkins job configuration, I defined sources explicitly like this:
-Dsonar.sources=src,gen
-Dsonar.exclusions=src/test/java/**
When I run with this configuration, analysis fails for modules which doesn't have both src and gen. (module2, module3, module4)
So, how do I run the analysis to pick either src or gen or skip that module if either of them is not found ?
Thanks,
Ron

When using the SonarQube scanner for Maven, you can't specific properties that only apply to some of the modules using the command line.
In the modules where you want to modify the sources, add in the pom.xml a property. For example, in module5/pom.xml add:
<properties>
<sonar.sources>src,gen</sonar.sources>
</properties>

Related

Build multi maven modules then copy JARs inside a docker image

I have a multi-modules project configured with maven.
/myProject
/module1
/target
pom.xml
/module2
/target
pom.xml
pom.xml
The pom parent is building the submodules.
Using the com.spotify.dockerfile-maven-plugin I want to build all the modules, build a docker image and copy all the JARs inside that image.
The pom parent
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>myTest</artifactId>
<name>test</name>
<version>0.0.1</version>
<packaging>pom</packaging>
<modules>
<module>module1</module>
<module>module2</module>
</modules>
</project>
If I put a Dockerfile at the root of /myProject, the plugin complains there is no Dockerfile for module1
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} /home/xyz/jars
maven plugin:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<configuration>
<repository>mytest</repository>
<buildArgs>
<JAR_FILE>target/${project.artifactId}-${project.version}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
This works fine with one module if I put the Dockerfile inside that module but how to do with multiple modules and only 1 Dockerfile?
Can I build the submodules and then the docker image with a single mvn clean install on the parent pom?
Maybe by creating a submodule only with a pom and the Dockerfile?
If the jars are dependencies for one executable then yes, you could just build that one executable with its dependencies declared in its pom.xml file. Maven should figure out which order to build the submodules in, so long as you don't create a cycle. As you suggest, you want to make it a submodule and not the root pom as the root pom is parent configuration that is inherited by other modules. Just put the plugin on that one submodule (in its pom.xml) and only give it the Dockerfile.
(If you think of this as a problem about having one executable depending on libraries in the same maven project then it's not really related to docker. You could ask the same question about a spring boot app using libraries in the same multi-module project. In a sense it just is that problem as the jar will get built together with its dependencies and copied into the docker image.)
Or if you mean that each jar for each submodule is an executable in itself (and I don't think you do) then you could create multiple docker images, each from its own Dockerfile, and then you can bundle and start them together if you want to with a docker-compose file.

Setting subproject pom.xml to be ignored by parent install

My parent pom modules list looks something like this:
<modules>
<module>jarProject1</module>
<module>jarProject2</module>
<module>jarProject2</module>
<module>warProject1</module>
<module>warProject2</module>
</modules>
I would like warProject1 and warProject2 to be ignored when I run mvn clean install on the parent pom. I want install to only build jars and put them in the maven repo but not the war producing projects. Currently I do it using profiles but I have some problems related to that. I would like the parent pom to keep a comprehensive list of modules in its default modules tag and not under profiles. Is there a way to do it and how?

Maven says it cannot find something in the "reactor"

I have a maven project and I'm using this --projects command from the root of the project to run several pom files.
mvn clean install --projects proj1, then-proj2
The proj1 and then proj2 are the artifact ids of the projects I want to run. That is, I go to the pom.xml for each project and use the "artifact id" there.
Both proj1 & then-proj2 are themeslves sub modules of projects in the main pom file.
Say proj1 is in A, and then-proj2 is in B, and both A & B are in the main pom file.
When I run this, maven tells me: "could not find the selected project in the reactor: proj1".
This is really frustrating - why not tell me what all the projects in the reactor are? Anyway, what am I doing wrong?
If you only use the artifactId's of the given project you have to define that correctly on command line:
help output of Maven (mvn --help)
Comma-delimited list of specified reactor projects to build of all
projects. A project can be specified by [groupId]:artifactId or by its
relative path
This means in your case you have to define:
mvn clean install --projects :proj1,:then-proj2
Try this:
mvn clean install -pl A/proj1, B/then-proj2
check this out: https://stackoverflow.com/a/23076358/1680793
Another thing is to make sure that you have listed your child projects inside the
<modules>
<module>
sections of the corresponding parent multimodule projects.
For example in the below project structure:
main
A
proj1
proj1A
B
then-proj2
Let's say you are trying to build proj1A. When you try
mvn package -pl A/proj1/proj1A
from the main's pom directory you will still have this same reactor error if you don't have:
"A" as a module in "main", or
"proj1" as a module in "A", or
"proj1A" as a module in "proj1"
If your modules are distinguished based on profiles then make sure to consider profiles too. Eg:
mvn -P profile1 -pl relative/path/to/project1 clean install
For this kind of setting, the pom would be:
<profiles>
<profile>
<id>profile1</id>
<modules>
<module>project1</module>
</modules>
</profile>
<profile>
<id>profile2</id>
<modules>
<module>project2</module>
</modules>
</profile>
</profiles>
Not mentioning profile would also give the Not Found in reactor.
A solution that worked for me, run the below command from the root directory.
mvn clean install --projects :projA, :projB -am
assuming that projB is dependent on projA
-am
If project list is specified, also
build projects required by the
list
The command used by you :
mvn clean install --projects 'submodule1','submodule2`
works on the sub-modules submodule1 and submodule2 specified in the pom.xml of the module where you're executing this command.
The guide to Working with Multiple modules shall help you understand the reactor and its sorting order. A general structure of the module for such use case would look like:
<groupId>stackoverflow</groupId>
<artifactId>mainmodule</artifactId>
<packaging>pom</packaging>
<version>1.2.3</version>
<modules>
<module>submodule1</module>
<module>submodule2</module>
... others
</modules>
... other tags

build multiple modules multiple times in parent pom

There are several applications that need to be built and packaged from a number of modules.
In parent pom, i'm using the profile to invoke builds for different apps.
root
parent/
pom.xml
moduleA/
pom.xml
moduleB/
pom.xml
moduleC/
pom.xml
For example, app "profile-1" would need a subset of existing modules to be built and put together as a tar ball.
The tar would contain several jars and different config files pulled from the target/ of the sub modules.
I'm using a shell script invoked using exec-maven-plugin to put together the tar.
The problem I'm facing is that, in one application, i need to build the same module multiple times but with different maven parameters.
What is the best way to do this?
<profiles>
<profile>
<id>profile-1</id>
<modules>
<module>../moduleA</module>
<module>../moduleB</module>
<!-- <module>../moduleC</module> -->
</modules>
<properties>
<global.version>0.0.1-SNAPSHOT</global.version>
</properties>
<build>
<!-- use maven exec plugin to run a shell script which generates the tar ball picking jars and config files from different modules target dirs -->
<plugins>
</plugins>
</build>
<profile>
</profiles>
A sample sub module pom
<groupId>com.test</groupId>
<artifactId>moduleC</artifactId>
<packaging>bundle</packaging>
<version>${global.version}</version>
<name>test :: ${project.artifactId} :: ${name} </name>
<parent>
<groupId>com.test</groupId>
<artifactId>parent</artifactId>
<version>${global.version}</version>
<relativePath>../parent</relativePath>
</parent>
Things i tried:
1) Can i separate into multiple profiles and invoke them as -Pprofile-1,profile-2?
It did not work for me but i would be doing something wrong.
2) Have another shell script that has mvn command line to build the moduleC in different ways.
- Even though i pass in the "-Dglobal_version", the moduleC run from mvn command line does not seem to find the parent in the repository.
I tried doing a "-N" build to put the parent pom in the repository before building the application but did not help.
Best way is:
mvn clean install --projects moduleA, moduleB
mvn clean install --projects moduleB, moduleC
You can't run multiple builds with maven (see this stackoverflow question)

Execute JAR of dependent artifact in Maven

I'm working on a multi-module Maven project which looks like this:
Parent-project (pom)
+- Module1 (executable-jar)
+- Module2 (executable-jar)
+- Module3 (jar)
+- ...
+- Distribution (pom)
The Distribution module lists dependencies on Module1, Module2, and Module3. I want the Distribution module to test the project and package it up. I'm using this module for testing since the distribution already contains all the necessary configuration files. If I were to start the tests manually from the command line it would look something like this:
$ # Pre-integration-test:
$ java -Djava.rmi.server.codebase=file:module3.jar -jar module1.jar
$ java -Djava.rmi.codebase=file:module3.jar -jar module2.jar
I've looked at the exec-maven-plugin for binding these calls to the pre-integration-test phase, but the plugin only includes the JARs on the classpath instead of the directory holding the JAR itself. I think I would benefit most from a plugin which can easliy execute jars produced by a project's dependencies. That way, I can do something like this in the Distribution POM:
...
<plugin>
<artifactId>some-magic-plugin</artifactId>
<executions><execution>
<phase>pre-integration-test</phase>
<goals><goal>exec-dependency</goal></goals>
<configuration>
<artifactId>module1</artifactId>
<vmArguments>...</vmArguments>
<arguments>...</arguments>
</configuration>
</execution></executions>
</plugin>
Is there already a plugin for this? Ideally, it would be able to:
Execute a JAR artifact given its Maven-coordinates
Put directories containing the artifacts' JARs on the path (so I can include the JARs with command line arguments)
I've laso looked at dependency:copy goal to try and copy all JARs to a common path first, but it seems unnecessary since the jars are already built as part of the project. (I'm also not sure which directory would make the best copy-destination).

Resources