I have a project made up of several modules.
I'm trying to analyse these with SonarQube.
I've included the Sonar Maven plugin as a dependency in each module:
<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>5.1</version>
</dependency>
Then I'm running Maven using:
mvn clean verify sonar:sonar
Maven completes successfully and I can see the Sonar analysis happening however when I open the Sonar UI, the modules aren't visible in projects.
However...
If I run the Maven command from an individual module directory, it is visible in projects.
Feel I'm missing something very simple, appreciate any help!
Instead of as a dependency, put the sonar-maven-plugin in the <build> section of the root pom.xml, as follows:
<build>
<plugins>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.0.1</version>
</plugin>
</plugins>
</build>
And since it's a multi-module project, you should first perform an install from the root project and then run the sonar:sonar goal as a dedicated step, as follows:
mvn clean install
mvn sonar:sonar
To configure the sonarqube server URL, specify a project property of sonar.host.url in your settings.xml or pom.xml as follows:
<properties>
<!-- Optional URL to server. Default value is http://localhost:9000 -->
<sonar.host.url>http://myserver:9000</sonar.host.url>
</properties>
SonarQube supports multi-module projects just like Maven does. This means that a Maven project containing multiple modules maps to a SonarQube project containing multiple modules/components, not multiple projects.
Take SonarQube code for example (it's a multi-module Maven project): the parent project aggregates all info from sub-modules, then if you check its structure (or its code page) you can see the list of all sub-components (for example: SonarQube::Core)
The bottom line is that you're seeing expected behaviour. Sub-modules of a Maven project are not meant to be analysed as projects, you should always analyse the parent project and SonarQube will handle modules natively.
Related
My project includes the nd4j-native-platform dependency, which includes .jars for windows, linux, and mac. The app is developed on windows/mac machines then deployed to Linux, so I'd like to save space on deployment by excluding these other platform jars that take up > 400 MB when the .war is built. Tl;dr, I want to exclude all the .jars that don't end with linux-x86_64.
Dependency in pom:
<dependency>
<groupId>org.nd4j</groupId>
<artifactId>nd4j-native-platform</artifactId>
<version>1.0.0-beta7</version>
<classifier>linux-x86_64</classifier>
</dependency>
I don't see any way to exclude them by classifier in the dependency tag, it seems you can only exclude by groupId and artifactId. I also tried using packagingExcludes and warSourceExcludes in the .war plugin, but that didn't do anything:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<packagingExcludes>
WEB-INF/lib/nd4j-native-1.0.0-beta7-windows-x86_64.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-android-x86.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-macosx-x86_64.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-android-x86_64.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-linux-ppc64le.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-android-arm64.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-android-arm.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-windows-x86_64.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-linux-armhf.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-windows-x86.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-windows-x86.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-linux-armhf.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-linux-ppc64le.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-linux-arm64.jar
</packagingExcludes>
</configuration>
</plugin>
Using Maven 3.6.3.
The correct way to deal with this for most things that use JavaCPP is to set the javacpp.platform property.
When building with mvn -Djavacpp.platform=linux-x86_64 you will get only that specific platform and nothing else. This will also apply to all other transitive dependencies, e.g. opencv.
You can try running mvn -Djavacpp.platform=linux-x86_64 dependency:tree to see that it works.
I'm creating a common library that will be used accross several Spring application. I've extracted the common classes I want to share between these application into a new Spring application named "Common". I've used mvn install on this application to put it in my local maven repository. On my main project, I've added the maven dependency, with the same version, in the pom.xml.
Now, if I try to launch mvn compile on my main project, I got this error :
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project recruitment: Compilation failure: Compilation failure:
[ERROR] /D:/[...]/application/src/main/java/com/example/application/service/Service.java:[8,37] package com.example.common.exception does not exist
Indicating that my common library is not present and thus my application cannot find package coming from it.
If I try to launch my Spring application from the main (using Spring Boot), it launchs perfectly and behaves like before.
I'm using IntelliJ on Windows, maven is bundled with IntelliJ with the default installation. If I check in my local maven repository I can find the common library jar. IntelliJ does not show any error on my imports, it recognizes my library.
There seem to be some conflict between IntelliJ, which read the pom.xml to find libraries imported for my application, and maven that use the same pom.xml to compile my code.
I used mvn compile -X to have more information and the funny part is that maven is using the common library jar from the local repository :
[INFO] Changes detected - recompiling the module!
[DEBUG] Classpath:
[DEBUG] D:\[...]\application\target\classes
[DEBUG] C:\[...]\.m2\repository\com\example\common\0.0.1\common-0.0.1.jar
Do you have any idea why I can't compile my project with maven while
I can launch it as a Spring application ?
Here is my dependency in my pom.xml :
<dependency>
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<version>0.0.1</version>
<scope>compile</scope>
</dependency>
And the common library definition :
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<version>0.0.1</version>
<name>common</name>
<description>Common project with generic technical modules</description>
Okay, that's embarassing... I just found the solution ! It has been two days looking for a solution to this tricky situation and I just found what was missing, or rather what was too much.
This bad boy :
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
The Spring boot maven plugin is what makes my Spring boot application launchable from maven, and it seems that it affects the way the common jar library is made, or the way it is imported.
I don't really understand why exactly it affects my import, but I deleted the plugin above in my common library pom.xml, I reinstalled in my local repository and I launch mvn install again on my main application... And it now works !
I think that launching via Spring boot used a little bit of Spring boot magic to make it works that the maven way lacks.
If someone understands it better and can explain it, that would be great and the accepted answer I think.
The reason for that is that application classes are packaged in BOOT-INF/classes so that the dependent module cannot load a repackaged jar’s classes
Proper config will look like:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.1.RELEASE</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Taken from
https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/html/#repackage-examples
Let's say I want to install project-local dependencies (jar files) to my local maven repository (~/.m2) prior to compiling the project so I can reference them in my POM just like I would reference any dependency from Maven Central. Currently, I'm using Maven install plugin's install-file goal attached to the 'clean' phase (because my IDE uses it), like so:
<dependencies>
<dependency>
<groupId>group.id</groupId>
<artifactId>artifact.id</artifactId>
<version>artifact.version</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-my-local-dependency</id>
<phase>clean</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>group.id</groupId>
<artifactId>artifact.id</artifactId>
<version>artifact.version</version>
<file>${project.basedir}/lib/local-dep.jar</file>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
When I execute mvn clean (or its equivalent in the IDE), everything runs as I'd expect:
--- maven-clean-plugin:2.5:clean (default-clean) # MyProject ---
--- maven-install-plugin:2.5.2:install-file (install-...) # MyProject ---
Installing ${project.basedir}/lib/local-dep.jar to ~/.m2/repository/group.id/artifact.id/local-dep.jar
But when I execute mvn clean install instead (or its equivalent in the IDE), I get the following error:
Failed to execute goal on project MyProject: Could not resolve dependencies for project com.example.MyProject:jar:1.0: Could not find artifact group.id:artifact.id:jar:artifact.version in central (https://repo.maven.apache.org/maven2) -> [Help 1]
For some reason, Maven install plugin's install-file goal either does not run in this case, or doesn't run soon enough. Why? The other StackOverflow answers I found explain differences between both commands but in my eyes, they do not explain this particular difference as my project has no modules.
Is there a better way of doing the same thing cross-platform, even on build servers (e.g. Jenkins) and with at least one other dependent project?
Should it be any help, I have the following Maven versions:
CLI: 3.6.0
IDE: 3.3.9
Maven first analyses the pom.xml and then calls the goals/phases. The analysis itself is complicated and has different depths, so I guess that calling clean alone will not make Maven analyse the dependencies, but calling clean install does so. Note that the analysis of the POM only happens once, not again for every goal/phase.
Generally, your approach cannot be recommended. Usually, you put project dependencies into remote Maven repositories, so that they can be resolved through them. If you work inside a company, you should set up a Nexus/Artifactory server that handles your artifacts.
If you want people outside your company to build the artifact, you need to find a provider for Maven repositories. I guess that github/gitlab can help you here. Then you need to add those repositories to the POM.
I have a Maven POM Project that includes a number of modules.
One of them is a REST Web Service that some of the other modules use.
This module is a standalone executable.
What I am trying to achieve is to have the web service build and run before all the other modules.
I understand that just by changing the order of the modules in the pom file I can get the module to build before the others, but how do I run it before building the rest of them?
I need to run it so that I can perform a series of tests included in the rest of the modules.
The reason I am trying to achieve this kind of functionality is because what I'm ultimately trying to do is having the project build and test correctly on Jenkins.
I understand that just by changing the order of the modules in the pom file I can get the module to build before the others, but how do I run it before building the rest of them?
Ordering of modules will not necessarily build them in that order. If one module depends on another then you must handle it through <dependency>in the pom of the dependent project.
To answer your question, build the REST service module first and deploy it to your server/container. In multimodule projects running command like mvn somegoal will run somegoal on all the modules. To run different goals on modules, try in two steps
mvn -pl module1 somegoal
mvn -pl module2 someothergoal
In your project they will take the form of
mvn -pl RESTModule deploy followed by usual
mvn command for running test for other modules. Remember the -pl option for these too.
Edit: After looking at the requirements from your comment I tried one more solution. Might work for you as well. Add maven-deploy-plugin to the pom of REST Module and tie it to a phase such that only the RESTModule project deploys the artifacts but not others (since they don't have such plugin in their pom). snippet to be added.
`
<project>
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<executions>
<execution>
<id>MyProjId</id>
<phase>package</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</build>
<distributionManagement>
<repository>
<id>my-repository</id>
<url>http://path/to/your/repo</url>
</repository>
</distributionManagement>
</project>
and run the project using the parent pom in jenkins.
Maven project structure
I have a trivial multi module Maven project:
parent-project
child-project1 (war)
child-project2 (jar)
parent-project's pom.xml references both child projects in its <modules> section. Both child projects reference the parent in their <parent> sections.
child-project1 depends on child-project2 (it references it in the <dependencies> section).
The problem
I am trying to use the License Maven Plugin on the parent-project to generates a file containing a list of all dependencies and their licenses:
mvn license:aggregate-add-third-party
I get an error:
Failed to execute goal on project child-project1: Could not resolve dependencies
for project ... child-project1 ... : Could not find artifact ... child-project2 ...
When I comment out the dependency of child-project1 on child-project2 the plugin works with no problem. So I can use the plugin, but I have to comment out the dependency each time I do it.
What is the problem? Is there a way to fix it?
The problem you are facing is that the maven-license-plugin by default looks in your local repository for the child artifacts.
I suppose, your plugin configuration in the parent pom.xml looks like the following:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<!-- your own config goes here -->
</configuration>
</plugin>
</plugins>
You have to install your multi-module project to your local Maven repository using
mvn install
After that, you run
mvn license:aggregate-add-third-party
again and the build will succeed.
If you configured an <execution> in your plugin, this will fail, since the maven-license-plugin by default binds to the generate-resources phase [1] and this is always executed prior to install [2].
Cheers,
PK