Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven 2 - different dependency versions in test and compile

I have project that depends on commons-httpclient [2.0] (compile).

I would like to write some jbehave tests - jbehave-core 3.4.5 (test). Both this dependencies depend on commons-lang but in different versions - 1.0.1 and 2.5.

dependency

When I execute mvn package I get [BUID FAILURE] in tests section. There is an exception for my testcase in surefire-plugin output:

java.lang.NoSuchMethodError: org.apache.commons.lang.StringUtils.substringBeforeLast(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

As I looked in source code - in commons-lang 1.0.1 - indeed, there is no StringUtils.substringBeforeLast(...) method. Why maven uses commons-lang from commons-httpclient (compile) and not from jbehave-core in testing?

I can't afford to exclude this conflicting dependency in commons-httpclient so it must stay in compile time.

So how can this be resolved? - commons-lang 2.5 version in testing and 1.0.1 in compile time.

like image 754
Xeon Avatar asked Jul 04 '11 20:07

Xeon


People also ask

How do I exclude a specific version of a dependency in Maven?

Multiple transitive dependencies can be excluded by using the <exclusion> tag for each of the dependency you want to exclude and placing all these exclusion tags inside the <exclusions> tag in pom. xml. You will need to mention the group id and artifact id of the dependency you wish to exclude in the exclusion tag.

Can we install 2 versions of Maven?

With jenv you can easily install several versions side by side and easily pick which one to use system-wide or just on an individual shell. That makes building one project with Maven 3.1 and another with 3.5 as easy as pie.

Does Maven override dependency version?

By taking advantage of Maven's nearest definition logic, developers can override the version of a dependency by declaring it on the root pom. xml file.


2 Answers

Maven 3:

Maven 3 will attempt to obtain the nearest dependency, effectively ensuring that only one of the compile or test scoped dependency is used for both the compile and test phases.

(Thanks Vineet Reynolds)

Maven 2 (OLD):

try to define 2 different <dependency> tags with different versions and scopes. Use tag <scope>test</scope> inside dependency for tests and <scope>compile</scope> for compilation.

like image 193
AlexR Avatar answered Sep 21 '22 16:09

AlexR


In Maven 3, you can trick maven by adding a dot after groupId

<dependency>
  <groupId>groupId.</groupId>
  <artifactId>artifactId</artifactId>
  <version>version1</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>groupId</groupId>
  <artifactId>artifactId</artifactId>
  <version>version2</version>
  <scope>compile</scope>
</dependency>

The sequence matters here. need to have test first and then compile.

like image 42
zheng Avatar answered Sep 19 '22 16:09

zheng