Does maven dependecyManagement impact pluginManagement transitive dependencies? - maven

I understand that <dependencyManagement> config impacts to <dependencies> and transitive dependencies there. But also affects plugins under <pluginManagement> or <plugins>?
I have a case where is not happening, but just want to confirm if is a general behavior or something is wrong in my config.
Let's say that I need to use the-plugin, that has as dependency dep-a:1.0.
But I need to make that the-plugin uses dep-a:1.1 instead.
Is the following pom correctly configured to achieve this?
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>dep-a</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>group-plugin</groupId>
<artifactId>the-plugin</artifactId>
<version>1.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
I tested the above pom but is not working, I had to do the following to make it work as I need. Is this the correct configuration?
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>dep-a</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>group-plugin</groupId>
<artifactId>the-plugin</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>dep-a</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
</build>

The dependencyManagement is intended for dependencies of your project and NOT for dependencies of plugins. These are two different things.
In other words the given dependencyManagement can not influence the dependency of a plugin.
If a plugin needs a different version there are the following options:
You have to give the dependency explicit as already shown.
You have to upgrade the plugin version which contains the needed (newer?) version
The plugin will handle that automatically and uses the version which is given via the dependencies of the project (which has a number of impacts).

Related

Why can Maven plugin dependencies only be specified within <build> and not <reporting>?

Why can <dependencies> for a <plugin> only be defined within the <build> section, and not the <reporting> section of the pom?
Why does the maven pom.xml syntax disallow <dependencies> in <reporting>?
What if a user wanted to configure a plugin only for <reporting> and set the dependency version too?
How/why does <build> dependency information get used by the plugin in the <reporting> section?
The documentation I have found, I explain below why it didn't answer the question (the confusion from the docs is actually why I'm asking this question here!).
From what I've read, observed, and tried, here is my current understanding:
Plugins in the <build> section of the script can override default dependency information, and that will affect the dependencies of the plugin in the <reporting> section. Therefore, plugin dependency information does not need to be in the <reporting> section, only the <build> section.
Is this correct? Is there a spot in the docs which clarifies this? What details am I missing in order to correctly understand the relationship between <build> and <reporting> plugin configuration for <dependencies>?
From the Maven Documentation
It says on the Maven documentation Using the Reporting vs the Build Tag:
Using the <reporting> Tag VS <build> Tag
Configuring a reporting plugin in the <reporting> or <build> elements in the pom does NOT have the same behavior!
mvn site
It uses only the parameters defined in the <configuration> element of each reporting Plugin specified in the <reporting> element, i.e. site always ignores the parameters defined in the <configuration> element of each plugin specified in <build>.
The documentation explicitly says <configuration> is not shared between <build> and <reporting>, but
my question is about <dependencies> and how/why they only get declared in <build> and never <reporting>.
It seems as if dependencies specified in <build> do carry over to <reporting> plugins. But this is a point I'd like confirmation/explanation for.
Minimal Example
I encountered this question upgrading the dependencies for the CheckStyle plugin at runtime for use with mvn site, so this minimal example POM is demonstrating the issue with the Checkstyle plugin as the example.
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>mylib</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.0.0</version>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>8.15</version> <!-- Update from default 6.18 to 8.15 -->
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.0.0</version>
<!-- Uncommenting will cause syntax error, Dependencies can't be declared in reporting -->
<!-- <dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>8.15</version>
</dependency>
</dependencies> -->
</plugin>
</plugins>
</reporting>
</project>
I would say the situation is not so simple here - because <dependencies> are possible in the <reporting> section!
I think the point is the plugin itself (so it might be different for each plugin).
But at first whats the difference between <build> and <reporting>:
<build> is used during compiling, testing - i.e. during generating/analyzing/running code - like with mvn clean install
<reporting> is used during generating documentation with mvn site
So the question is does the checkstyle plugin require your dependency during the documentation generation - I guess not - so checkstyle refuses all dependencies in <reporting>.
So to prove that dependencies within reporting are possible please have a look at spotbugs (another famous analyzer):
<build>
<plugins>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>3.1.12.1</version>
<configuration>
<xmlOutput>true</xmlOutput>
<spotbugsXmlWithMessages>true</spotbugsXmlWithMessages>
<spotbugsXmlOutputDirectory>target/site</spotbugsXmlOutputDirectory>
<failOnError>false</failOnError>
<includeTests>true</includeTests>
<dependencies>
<dependency>
<groupId>com.mebigfatguy.fb-contrib</groupId>
<artifactId>fb-contrib</artifactId>
<version>7.4.3.sb</version>
</dependency>
<plugin>
<groupId>com.h3xstream.findsecbugs</groupId>
<artifactId>findsecbugs-plugin</artifactId>
<version>LATEST</version>
</plugin>
</dependencies>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>3.1.12.1</version>
<configuration>
<xmlOutput>true</xmlOutput>
<spotbugsXmlWithMessages>true</spotbugsXmlWithMessages>
<spotbugsXmlOutputDirectory>target/site</spotbugsXmlOutputDirectory>
<failOnError>false</failOnError>
<includeTests>true</includeTests>
<dependencies>
<dependency>
<groupId>com.mebigfatguy.fb-contrib</groupId>
<artifactId>fb-contrib</artifactId>
<version>7.4.3.sb</version>
</dependency>
<plugin>
<groupId>com.h3xstream.findsecbugs</groupId>
<artifactId>findsecbugs-plugin</artifactId>
<version>LATEST</version>
</plugin>
</dependencies>
</configuration>
</plugin>
</plugins>
</reporting>
Please have an eye on this example - because here the <dependencies> are part of the <configuration>. So it is always wise to read the documentation of each plugin carefully.
For a complete maven pom.xml please have a look at my small OpenSource TemplateEngine which includes a lot of best practices not only for maven.

Assemble a Karaf container with my dependencies

I was able to assemble a karaf container with standard and webconsole features in a new module:
<dependencies>
<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>framework</artifactId>
<type>kar</type>
</dependency>
<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>standard</artifactId>
<classifier>features</classifier>
<type>xml</type>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<version>${org.apache.karaf.features.framework.version}</version>
<extensions>true</extensions>
<configuration>
<bootFeatures>
<feature>standard</feature>
<feature>webconsole</feature>
</bootFeatures>
</configuration>
</plugin>
</plugins>
</build>
Now, I want to do some more, I want to add my other modules/code to this container to start it together and test my code, my REST calls and so on...
One of my modules is something like this:
<artifactId>config-testutils</artifactId>
<properties>
<bundle.symbolicName>${project.groupId}.${project.artifactId}</bundle.symbolicName>
<bundle.namespace>${project.groupId}.${project.artifactId}</bundle.namespace>
</properties>
<name>${project.groupId}.${project.artifactId}</name>
<packaging>jar</packaging>
How can I add those modules to see if they are working fine in this Karaf I'm assembling? There is a way besides putting manually on deploy folder?
You should create a feature that contains your own bundles and add it in <bootFeatures>

Maven compile error [package org.testng.asserts does not exist]

When I try to build project via console by [mvn clean install -DskipTests] I get error. I use in my tests testNG SoftAssert and in a test class I just added an import import org.testng.asserts.SoftAssert but looks like maven does not see that package.
Error from console:
package org.testng.asserts does not exist
My pom.xml looks like
<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.atlassian</groupId>
<artifactId>tests</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>confluence</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.48.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
Such errors occur when corresponding dependency version do not have the classes you are trying to use. In this case the TestNG version 6.1.1 you are using, does not have package org.testng.asserts. Try using below version,
Also, it will not give error for SoftAsserts import, if you have asked IDE to include TestNG library. This TestNG library surely is of higher version than the one you are referring from pom.xml. Try to keep same versions both in pom.xml & your IDE's testNG plugin to avoid such varying behavior.
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.8</version>
</dependency>
Above version is surely working. Give it a try.
I found out that removing scope inside testng dependency worked. I tried running with scope added to the same dependency but failed. Strange but it just worked by removing testng scope dependency.
Tried different versions, but it did not help. Removing a scope from dependency indeed solved the issue.

Using "provided" classpath in tomcat7-maven-plugin goals

I have some dependencies in my webapp that I've marked as provided because I expect them to be provided by an appserver (maybe a production environment provides these dependencies at the specified versions). How do I simulate that when I'm running tests or in development on my localhost using for example the tomcat7-maven-plugin goals like run?
I can't see any way to do it without manually copying jars around. I can see how to use the test classpath - is there something wrong with what I'm trying to do?
OK, I've found a way of getting this to work - it's reasonable but there's a duplication of dependency information and a magic profile... I feel that the tomcat7-maven-plugin should provide a means of making provided dependencies available in the container when running.
Add a profile that is activated when the tomcat plugin runs, and add the dependencies that have provided scope with compile scope to that profile, eg.
... in project pom ...
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>my-provided-artifact</artifactId>
<version>1.2.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
...
<profiles>
<profile>
<!-- profile activated as cli param when tomcat7 plugin runs -->
<id>tomcat</id>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>my-provided-artifact</artifactId>
<version>1.2.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</profile>
</profiles>
I use, for example, this:
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<path>/myApp</path>
</configuration>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
</dependencies>
</plugin>
and then also include the dependency again later with provided.

How to include a provided denpendency when debug webapp using maven tomcat plugin?

I have webapp which has a jdbc driver dependency. And this is dependency's scope is provided. So when I use maven tomcat plugin to run it, it is not include in my local. So how can I include this provided plugin when I debug it using maven tomcat plugin ?
Thanks
One way to do this would be to use a profile for debugging using tomcat. In this you can specify the required dependency with the needed scope. Something like this...
<profile>
<id>tomcat</id>
<dependencies>
<dependency>
<groupId>myGroup</groupId>
<artifactId>myArtifact</artifactId>
<version>a.b.c</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
</plugin>
</plugins>
</build>
</profile>
Instead of using a profile I prefer specifying the dependencies for the plugin directly:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<dependencies>
<!-- add here your JDBC drivers which appear
in the global dependencies with state provided -->
</dependencies>
</plugin>

Resources