What happens if you do not specify the version of the maven plugin? - maven

What will happen if spring boot 2 in pom.xml does not indicate the version of the plugin. Will it automatically use the latest version? For example maven-surefire-plugin.
<build>
<!--Закомментировать если сборка с Java-->
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<!---->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>

From maven 3.x documentation
When a plugin was invoked without an explicit version given in the POM
or on the command line, Maven 2.x used to pick the latest version
available where the latest version could either be a release or a
snapshot. For the sake of stability, Maven 3.x prefers the latest
release version over the latest snapshot version.
Given the threat of non-reproducible builds imposed by automatic
plugin version resolution, this feature is scheduled for removal as
far as plugin declarations in the POM are concerned. Users of Maven
3.x will find it output a warning when missing plugin versions are detected to encourage the addition of plugin versions to the POM or
one of its parent POMs. The Enforcer rule requirePluginVersions can be
used additionally check for missing plugin versions in the POM.

It really depends what your parent is. Spring Boot's parent has pluginManagement for a number of plugins (including surefire) so it will use that version. This is a fixed version and it depends on the Spring Boot version you're using.
There is no guarantee that it will be the latest, even if you use the latest Spring Boot version as we try to be consistent with our upgrade policy. You can figure this out yourself via mvn help:effective-pom.

Related

Old version of checkstyle detected. Consider updating to >= v8.30

Small question regarding a SonarQube + Checkstyle warning please.
Currently, in my app, in my pom, I use the following Checkstyle plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<outputFile>.out/reports/checkstyle/checkstyle-result.xml</outputFile>
<outputDirectory>target/reports/checkstyle</outputDirectory>
<outputFileFormat>xml</outputFileFormat>
</configuration>
</plugin>
This plugin is doing its job, no worries there.
When I run SonarQube though, I get this warning
Old version of checkstyle detected. Consider updating to >= v8.30
For more information see: https://maven.apache.org/plugins/maven-checkstyle-plugin/examples/upgrading-checkstyle.html
I obviously went to read the website, but I am still having hard time understanding.
The Checkstyle plugin I have is the latest known, version 3.1.2, checked on Maven central etc.
In SonarQube, I am running on the latest version, 8.9 LTS, with the latest version of Checkstyle plugin as well.
What am I missing please? Am I using some kind of wrong plugin?
It is a SonarQube plugin named sonar-checkstyle which needs to be installed or upgraded at the SonarQube server instance. The current version is 8.40.
Note: Refer to
https://docs.sonarqube.org/latest/setup/install-plugin/
https://docs.sonarqube.org/latest/instance-administration/plugin-version-matrix/
https://github.com/checkstyle/sonar-checkstyle
https://github.com/checkstyle/sonar-checkstyle/releases
Edit 1
Step 1
Firstly, there is a cache directory at <user_home>/.sonar/cache (for me on the Windows 10 is C:\Users\<myuser>\.sonar\cache), please delete all sub directories under this cache directory with purpose to let the org.sonarsource.scanner.maven:sonar-maven-plugin latest version download it from our SonarQube server instance and ensure that all related plugins are new and fresh after upgrading/installing at the SonarQube server instance. (Do not forget to restart it after finishing upgrading/installing to ensure all new are re-loaded)
Step 2
Secondly, make sure that we do not specify the org.sonarsource.scanner.maven:sonar-maven-plugin in our project pom.xml neither at the parent nor anywhere else with purpose to ensure that during executing, it will be a latest version which matches to our SonarQube server instance version.
Anyhow the formal document (https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-maven/) also mentions about How to Fix Version of Maven Plugin as the following: -
How to Fix Version of Maven Plugin
It is recommended to lock down versions of Maven plugins:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>
<!--Version that matched with our Sonar server instance version -->
</version>
</plugin>
</plugins>
</pluginManagement>
</build>
The latest version is able to be browsed at https://search.maven.org/artifact/org.codehaus.mojo/sonar-maven-plugin or https://search.maven.org/artifact/org.sonarsource.scanner.maven/sonar-maven-plugin The latest is version 3.9.0.2155 (Note: the version ?.y.z is matched with our Sonar server instance version)
Step 3
Last but not least, if our project is a multi-module projects there is a mentioned at the formal document (https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-maven/) as the following: -
In some situations you may want to run the sonar:sonar goal as a
dedicated step. Be sure to use install as first step for multi-module
projects
mvn clean install
mvn sonar:sonar ...
Then there will be 2 steps here, mvn clean install first so that it is completed and then mvn sonar:sonar ... later on.
Edit 2
The maven-checkstyle-plugin is also able to specify the checkstyle version as mentioned at https://maven.apache.org/plugins/maven-checkstyle-plugin/examples/upgrading-checkstyle.html with the significant sentence as
Maven Checkstyle plugin comes with a default Checkstyle version: for
maven-checkstyle-plugin 3.1.2, Checkstyle 8.29 is used by default.
Then the configuration for the maven-checkstyle-plugin will be like the following: -
<project>
...
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.2</version>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>...choose your version...</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
<build>
...
</project>
The latest version is able to be browsed at https://search.maven.org/artifact/com.puppycrawl.tools/checkstyle The latest is version 8.42.

Java 11 Eclipse finds automatic module, Maven does not

I'm attempting to upgrade a 15 year old Maven multimodule project to Java 11, and the module system that was introduced in Java 9. Since the project is built using Maven, all dependencies are pretty clear. First I want to do this using the automatic module names, in order not to also introduce upgraded artifacts (if not absolutely required).
Eclipse is pretty helpful in this process, autocompleting the automatic module names in the module-info.java. For example:
requires dom4j;
But if I compile with Maven, I get errors about that it cannot find the modules Eclipse just autocompleted in there.
module-info.java:[29,18] module not found: dom4j
I am using Maven's compiler plugin 3.7.0 (3.8.0 gives a NullPointerException as per https://jira.apache.org/jira/browse/MCOMPILER-355) I suspect Maven is setting the jars up on the classpath instead of on the modulepath, but the compiler's plugin debug output does not log that.
How can I make Maven correctly handle those modules?
I was running into the same issue. Adding
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
</plugins>
</build>
to my pom solved the problem for me...
Maven version 3.9.0 seems to be buggy and will not find the module although the dependency is using an Automatic-Module-Name. Downgrading to version 3.8.1 helps.

Maven versions plugin update to next snapshot

I'm trying to use the maven versions plugin to update my pom to the next snapshot version. eg. 0.0.1 should change to 0.0.2-SNAPSHOT.
From my reading of http://www.mojohaus.org/versions-maven-plugin/set-mojo.html I would expect mvn versions:set -DnextSnapshot=true to do this, but in reality it just prompts me for a new version with a default of the current version (0.0.1). Am I missing something here? I want to do this update as a part of a script so don't want any manual intervention.
I'm using v2.5 of the versions plugins. That link above says that nextSnapshot is available from 2.10 but 2.5 seems to be the latest I can find.
I also faced this issue. I got to know that my Maven project was picking up older version (2.3) of Versions Plugin. This no longer seems to be a problem in latest version (2.7) of the plugin.
I added following in pom.xml of my project to force my project use 2.7 version of Maven Versions plugin.
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.7</version>
</plugin>
</plugins>
</pluginManagement>
Otherwise, you can mention latest version of Versions plugin to choose in command line :- mvn org.codehaus.mojo:versions-maven-plugin:2.7:set -DnextSnapshot=true

TypeNotPresentExceptionProxy error at integration-test with maven-failsafe-plugin spring-boot 1.4

I'm getting ArrayStoreException: TypeNotPresentExceptionProxy when running integration-test with maven-failsafe-plugin and spring-boot 1.4.
You can see this error if you run joinfaces-example with
mvn -Pattach-integration-test clean install
I realized that the error does not occur if I change spring-boot-maven-plugin to run at pre-integration-test phase instead of package one.
More, this error started when I upgraded spring boot to 1.4. No error occurs if I change jsf-spring-boot-parent version to 2.0.0 which uses spring boot 1.3 version.
I actually found the answer in Spring Boot 1.4 release notes, short answer is that maven-failsafe-plugin is not compatible with Spring Boot 1.4's new executable layout. Full explanation below :
As of Failsafe 2.19, target/classes is no longer on the classpath and
the project’s built jar is used instead. The plugin won’t be able to
find your classes due to the change in the executable jar layout.
There are two ways to work around this issue:
Downgrade to 2.18.1 so that you use target/classes instead
Configure the spring-boot-maven-plugin to use a classifier for the
repackage goal. That way, the original jar will be available and used
by the plugin. For example :
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
An alternative is documented here: https://github.com/spring-projects/spring-boot/issues/6254
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<!--
Make failsafe and spring-boot repackage play nice together,
see https://github.com/spring-projects/spring-boot/issues/6254
-->
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
</configuration>
</plugin>
This worked better for me, because when I used the "exec" solution, Spring failed to find my configuration files when starting the container. Which could probably be fixed by adding some further configuration parameters, I suppose, but this solution works "out of the box" for me.

Is my project using older versions of dependencies than what I need?

The place where I work uses Maven and we have lots of internal libraries. We try to make changes in a backward-compatible manner, but sometimes one of our libraries requires a newer version of another library. That can cause problems if an end product doesn't end up pulling in the newer library version.
For each end product, we have a dependencyManagement section that declares which versions of transitive dependencies should be used for the project. We do this instead of letting Maven figure out which version to use because we want control of which versions of libraries are being used.
Even if we let maven figure out which versions of libraries should be used, it's possible that the older library may be used, which could cause ClassNotFoundExceptions, etc...
Is there a Maven plugin or way to determine if my project is using an older version of a dependency, when one of the project's dependencies requires a newer version?
There is mvn dependency:tree but we have lots of dependencies, and I don't want to have to look through the giant list by hand.
Thanks!
EDIT
Since we have lots of libraries, if the end product uses libraries A, B, and C, and both A and B use a different version of C, the latest version of C is not always used. From Introduction to the Dependency Mechanism:
Dependency mediation - this determines what version of a dependency
will be used when multiple versions of an artifact are encountered.
Currently, Maven 2.0 only supports using the "nearest definition"
which means that it will use the version of the closest dependency to
your project in the tree of dependencies. You can always guarantee a
version by declaring it explicitly in your project's POM. Note that if
two dependency versions are at the same depth in the dependency tree,
until Maven 2.0.8 it was not defined which one would win, but since
Maven 2.0.9 it's the order in the declaration that counts: the first
declaration wins.
Since we almost always make changes in a backward-compatible manner, it looks like the best solution for us is to ensure that the latest versions of dependencies are used. The Maven Enforcer plugin with the "Require Upper Bound Dependencies" feature accomplishes this.
From http://maven.apache.org/enforcer/enforcer-rules/requireUpperBoundDeps.html:
This rule requires that the version for each dependency resolved
during a build, is equal to or higher than all transitive dependency
declarations. The version of each dependency resolved during the build
will normally be the version specified in the POM or the version with
the least transitive steps (the "nearest" definition). For more
information about Maven dependency resolution, see the Maven site.
Here is a concrete example. This will cause a build to fail:
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.9</version>
<!-- Depends on org.slf4j:slf4j-api:1.5.0 -->
</dependency>
</dependencies>
Because the project will run logback-classic 0.9.9 with slf4j-api
1.4.0 and slf4j-api 1.4.0 is probably not forwards compatible with slf4j-api 1.5.0.
This is the log message:
Failed while enforcing RequireUpperBoundDeps. The error(s) are [
RequireUpperBoundDeps error for org.slf4j:slf4j-api:1.4.0 paths to dependency are:
+-test:TestParent:1.0-SNAPSHOT
+-org.slf4j:slf4j-api:1.4.0
and
+-test:TestParent:1.0-SNAPSHOT
+-ch.qos.logback:logback-classic:0.9.9
+-org.slf4j:slf4j-api:1.5.0
]
We're probably going to set up this plugin in a profile which we can turn on or off.
I'm not sure there's a plugin that will do as you ask. In general, a newer version will be the one you'll settle on, but that's not always a hard rule - sometimes you'll have a newer version pulled in but an older version is actually what you require.
In my experience, you have to treat each dependency problem in isolation.
The way we handle this is by combination of using the <dependencyManagement/> section as you suggest, along with the Maven Enforcer plugin with the <DependencyConvergence/> rule.
The dependencyConvergence rule:
...requires that dependency version numbers converge. If a project has
two dependencies, A and B, both depending on the same artifact, C,
this rule will fail the build if A depends on a different version of C
then the version of C depended on by B.
Basically, if you've got 2 different versions of the same lib in your dependency tree, then the validate phase fails.
So:
The way I do it is - we usually have multi module Maven projects and I try to define common dependency versions in the <dependencyManagement/> section at the parent level - EG Spring, Jersey etc. Then at the child module levels, define specialist <dependencyManagement/> section as needed.
In all our poms we define the Maven Enforcer plugin configured with the <dependencyConvergence/> rule as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
<configuration>
<rules>
<DependencyConvergence/>
</rules>
<fail>true</fail>
</configuration>
</plugin>
Then on every Maven build, if someone's added a new dependency (or there's a new transitive dependency) that clashes with another, your build will fail, and you'll get a (slightly repetitive) log of the dependency issues for you to deal with.
As an end point, I don't see the Maven Enforcer plugin used much, but it's got a load of really useful rules as well as the ability to make custom rules.
If it really was the newest version of a dependency you always wanted, I'm sure you could write a simple rule to do it.
Hope this helps,
Will

Resources