Maven: Force the exclusion of dependencies

In large Maven-based projects consisting of several high-level frameworks sooner or later there will come the time, when there are two versions of the same dependency in the classpath. For example: two versions of the same logging framework.

One approach to solve such ambiguity is to choose one of the versions (which is hopefully compatible) and to use it as an explicit dependency. Nevertheless other dependencies may still introduce other version as transitive dependencies. This may be caused by different groupIds, which will result in two similar named jar.

Once you got a candidate you can start finding all the possible sources of the dependency.

mvn dependency:tree -Dverbose -Dincludes=log4j:log4j

will show you the dependency-tree, but only the relevant excerpt. Using this information you can now add your exclusions to the affected pom.xml files.
Exclusions are configured via the exclusion-tag [1], which excludes specific transitive dependencies. For example:

<dependency>
	<groupId>sample.ProjectB</groupId>
	<artifactId>Project-B</artifactId>
	<version>1.0-SNAPSHOT</version>
	<exclusions>
		<exclusion>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
		</exclusion>
	</exclusions>
</dependency>

By the way: Java IDEs can help you doing this.

After that you can make sure the faulty dependency versions will never ever be included again. This can be done using the maven-enforcer-plugin [2]

      
<build>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-enforcer-plugin</artifactId>
			<version>1.3.1</version>
			<executions>
				<execution>
					<id>enforce-version</id>
					<goals>
						<goal>enforce</goal>
					</goals>
					<configuration>
						<rules>
							<bannedDependencies>
								<excludes>
									<!-- exclude all versions lower than 1.2.17-->									
									<exclude>log4j:log4j:[0.0,1.2.17)</exclude>
								</excludes>
							</bannedDependencies>
						</rules>
					</configuration>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

[1] http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
[2] http://maven.apache.org/enforcer/maven-enforcer-plugin/

[Quicktip] Importing a “dependencyManagement”-section from an external artefact

Situation: You have a parent pom with defined dependencies in the “dependency management”-section. This way you do not have to provide versions for your dependencies. Standard-Maven-Stuff.

New situation: BUT for some reason you have to switch to another totally different parent pom with totally different “dependency management”-section. Your previously declared dependencies have no version, so there will be errors when invoking maven on this pom.

One solution: A cool thing you can do since Maven 2.0.9 is the import of the “dependency management”. So still no versions required for your previously declared dependencies…

This is accomplished by declaring a pom artifact as a dependency with a scope of “import”.

The offical documentation can be found here

Status code 401 on mvn site:deploy?

Are you faced to a 401 status code when invoking mvn site:deploy?

Like this one?
Embedded error: Failed to transfer file: http://server:port/dir/projectname//./changes-report.html. Return code is: 401

Then

  1. check your pom.xml if the site-id in the distribution-section of the pom.xml matches any server-id setting in your settings.xml.
  2. check if the password is still valid!

For example the following pom.xml and settings.xml DO NOT match. Note the difference between BARNAME and FOONAME! This cannot work.

pom.xml:

   <distributionManagement>
     <site>
       <!-- does not match FOONAME -->
       <id>BARNAME</id>
       <url>${site-base-url}/projectname/</url>
     </site>
   </distributionManagement>

.m2/settings.xml:

<?xml version="1.0" encoding="UTF-8"?>
<settings 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/settings-1.0.0.xsd">
  <servers>
    <server>
       <!-- does not match BARNAME -->
      <id>FOONAME</id>
      <username>XXXXXX</username>
      <password>XXXXXX</password>
    </server>
  </servers>
</settings>

maven-surefire-plugin only uses 67MB of heap?

Today i  had to do some merging of artifacts (code and pom.xml). Then i wondered, why the tests didn’t run properly.

java.lang.OutOfMemoryError: Java heap space” was the reason. But why? I didn’t change the tests and i carefully merged the configuration. So i connected VisualVM to the surefire process and saw that only ca. 67MB max heap were available. I reviewed my MAVEN_OPTS, but my settings didn’t apply…

The culprit is a bug. See http://jira.codehaus.org/browse/SUREFIRE-501.

The workaround is to place your max heap configuration in the configuration section of the plugin. As seen in the linked bug issue:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <!-- http://jira.codehaus.org/browse/SUREFIRE-501 -->
    <argLine>-Xmx256m</argLine>
  </configuration>
</plugin>