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.
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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With