Maven - differences between dependencies inside plugin and outside? - maven

I've come across some sample code which specifies dependencies inside the plugin tag like this :
<build>
<plugins>
<plugin>
<dependencies>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.2.8</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
It look strange to me because mostly I see people put the dependencies tag outside the build tag.

When you add <dependency> to project it is available to that project depending on its scope (compile, test, runtime, etc)
But when you add <dependency> inside plugin's execution you are making that artifact available to that plugin in classpath at runtime
For example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>check my sources</id>
<goals>
<goal>check</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>checkstyle</groupId>
<artifactId>checkstyle</artifactId>
<version>4.4</version>
</dependency>
</dependencies>
</plugin>
in this snippet checkstyle:checkstyle:4.4 is being available to maven-checkstyle-plugin at runtime
Read More
How to override a plugin's dependency in Maven

Related

Maven plugin- exclude log4j1 transitive dependency

I have created sample application which has only one plugin 'aspectj-maven-plugin'.
When I build application, log4j1.2.12 is getting downloaded by this plugin.
Is there any way to avoid downloading log4j1 from maven plugin ?
I tried different options, like- exclude from dependency, increase plugin version, exclude from maven plugin, etc., but no luck.
My pom.xml -
<properties>
<aspectj.version>1.8.10</aspectj.version>
</properties>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I have observed same with my another multi-module application. I have different maven plugin in different module- 'maven-war-plugin', 'maven bundle-plugin', etc.
One or another plugin is downloading log4j1.
If I increase version of one plugin then dependency is getting downloaded with another plugin.
I tried many options but no luck.
Log4j1 is not getting bundled in my war but what I need is log4j1 should not be downloaded.
Please let me know if there is any option to exclude lo4j1 from maven plugin.
Thanks.

Using Provided Artifact As Maven Plugin Dependency

This seems like it should be a simple question, but I can't seem to find any information about it. When a maven plugin has a required dependency, is it possible to tell it to use an artifact defined elsewhere in the section of the pom?
As an example, I'm trying to add the 'maven-processor-plugin' to my build. That plugin has a dependency on 'hibernate-jpamodelgen'. I'm working with wildfly, so I already have that jar as a dependency of the project. I want to ensure I am using the same version for both. Is what I'm trying to do even possible?
Some code snippets:
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-ejb3</artifactId>
<version>${version.server.bom}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArguments>
<processor>-proc:none</processor>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>4.5</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<outputDirectory>${project.build.directory}/generated-sources/java/jpametamodel</outputDirectory>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
<overwrite>true</overwrite>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<!-- How do I handle this without hard coding the version? -->
<!-- <version>???</version> -->
</dependency>
</dependencies>
</plugin>
</build>
Define a property like <hibernate-jpamodelgen.version> in the <properties> section of the POM.
Then use that property for the version like ${hibernate-jpamodelgen.version}.

Maven - how to verify that dependencies compiled with specific Java level (1.7 for example)?

For example, Java Maven project have ben compiled with maven-compiler-plugin with target level 1.7 have number of dependencies.
How to verify that those dependencies compiled with some specific Java target level as well (1.7 for example)?
As suggested in the comments, i have used Extra Enforcer Rules as additional dependency to Maven enforcer plugin that provides extra rules, as a solution.
The usage of this functionality described here, and specifically in my code it looks like that:
<properties>
<extra-enforcer-rules>1.0-beta-4</extra-enforcer-rules>
</properties>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>${extra-enforcer-rules}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>enforce-bytecode-version</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<enforceBytecodeVersion>
<maxJdkVersion>1.7</maxJdkVersion>
</enforceBytecodeVersion>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>${extra-enforcer-rules}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
</build>

Preventing overriding dependency version in Maven child pom

I have a dependencyManagement section in parent pom like
<dependencyManagement>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
</dependency>
</dependencyManagement>
and a child pom, having it
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0</version>
</dependency>
</dependencies>
I've tried to prevent this kind of overriding in child poms using enforcer plugin, allowing these only to be set in parent, but haven't been able to. I'd like this to fail the build. Is that possible, with that plugin or some other way?
There is DependencyCovergence, which forces all versions to be the same, but that's too restrictive as I don't want to control all transitive dependencies - just the ones defined explicitly.
I'd be happy if I could just prevent introducing any new dependencies at all in child poms - everything defined should really be defined in the parent pom, and then just mentioned, if needed, in the child.
You could add a dependency:analyze-dep-mgt execution in your parent pom and configure it to fail on version mismatches:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>analyze</id>
<phase>package</phase>
<goals>
<goal>analyze-dep-mgt</goal>
</goals>
<configuration>
<failBuild>true</failBuild>
<ignoreDirect>false</ignoreDirect>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Simplistic using Groovy in Maven

In some maven project I'll try to figure out how can be used Groovy language. For instance, I try to create a directory in validation phase, by using something like that
<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">
...
<dependencies>
...
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.5.5</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<id>Project</id>
<phase>validate</phase>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
<configuration>
<source>
final FileTreeBuilder treeBuilder = new FileTreeBuilder(new File('tree'))
def folder = new File( 'sample_dir' )
if(!folder.exists()){
treeBuilder.dir('sample_dir')
}
</source>
</configuration>
</plugin>
...
</plugins>
</build>
But if it using the command mvn compile will be present error
[ERROR] script1.groovy: 3: unable to resolve class FileTreeBuilder
What have I missed and what should be added to make this plugin functional?
https://groovy.github.io/gmaven/groovy-maven-plugin/
Customizing Groovy Version
To customize the version of Groovy the plugin will use, override the org.codehaus.groovy:groovy-all dependency on the plugin definition in the project.
For example to use Groovy 2.0.6 instead of the default:
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.0.6</version>
</dependency>
</dependencies>
</plugin>

Resources