I want to use the last version of the powermock library (1.6.5) through Maven. But My package cannot be compiled, since Maven finds dependency Convergence error. Below you can see that there are 2 different versions of org.objenesis:objenesis library in the same dependency:
Dependency convergence error for org.objenesis:objenesis:2.1 paths to
dependency are:
+-mypackage:v1-SNAPSHOT
+-org.powermock:powermock-api-mockito:1.6.5
+-org.mockito:mockito-core:1.10.19
+-org.objenesis:objenesis:2.1
and
+-mypackage:v1-SNAPSHOT
+-org.powermock:powermock-api-mockito:1.6.5
+-org.powermock:powermock-api-mockito-common:1.6.5
+-org.powermock:powermock-api-support:1.6.5
+-org.powermock:powermock-reflect:1.6.5
+-org.objenesis:objenesis:2.2
I tried to make an exclusion, but I cannot exclude only one version, I need to exclude all of them, which does not pass me, as I think.
Did you have the same problem? What can I do?
There two different version of objenesis, because two different libraries depends on two different version ofobjenesis`: PowerMock and Mockito. You have two options to resolve the issue:
Exclude org.objenesis:objenesis from PowerMock dependencies and add it manually to your pom.
Exclude mockito-core from PowerMock dependencies and add it as separated decency to your pom with excluding objenesis.
I followed the answer from Arthur, but only made an exclusion for objenesis to the powermock-module-junit dependency. After that the enforcer plugins was happy.
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.0</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
Related
I have a project A which creates 10 artifacts with same group id . For example generated artifacts from the project A will be -
<groupId>com.example.abc</groupId>
<artifactId>A1</artifactId>
<version>v1</version>
<groupId>com.example.abc</groupId>
<artifactId>A2</artifactId>
<version>v2</version>
Likewise from A1 to A10 and v1 to v10 . Group Id remains same.
The generated artifacts needs to be used in another project B but I need to exclude two dependencies which are common to all the ten artifacts generated by Project A.
I know I can add dependency management tag in Project B's pom.xml with explicit exclusions tag.
What I am looking for is a less verbose way of excluding those two dependencies ? I tried with
<dependencyManagement>
<dependency>
<groupId>com.example.abc</groupId>
<artifactId>*</artifactId>
<version>*</version>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencyManagement>
which is not working .
Is there any less verbose way ?
could you declare the mockito dependency as a one provide.
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>YOUR VERSION</version>
<scope>provided</scope>
</dependency>
Note: The dependency won't end up inside the build artifact but it's still available during tests
Take a look at here too.
Regards.
I have a fairly large legacy project that I'm adding a component to. This component uses HtmlUnit. I can compile it ok with Maven but when I run it I get:
java.lang.NoSuchMethodError:
org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>
(Ljavax/net/ssl/SSLContext;[Ljava/lang/String;[Ljava/lang/String;Ljavax/net/ssl/HostnameVerifier;)
So it's missing the correct constructor. I think this is almost certainly a version conflict in httpclient but I'm not sure how to resolve it. Here's the relevant part of my pom.xml (note all the games I've been trying to play with exclusions and dependency management):
<dependencies>
<dependency>
<groupId>com.mycompany.mine</groupId>
<artifactId>my-base-project</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>base-project</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
</dependencyManagement>
Any ideas?
Edit: it's been suggested that this question is a duplicate of this one, but it's not since the dependency type in this case is not war.
In order to identify conflicting dependecies, use mvn dependency:tree. I like to pipe it to a text file for ease of use:
mvn dependency:tree > tree.txt
Then, use your favorite text editor to look for multiple versions of a depedency.
Alternatively, if you are looking for a specific groupId or artifactId, use the -Dincludes flag:
mvn dependency:tree -Dincludes=<groupId>:<artifactId>:<version>:<packaging>
mvn dependency:tree -Dincludes=org.springframework <<< get all dependencies with by groupId
mvn dependency:tree -Dincludes=:spring-web <<< get all dependencies by artifactId
You might also want to add the -Dverbose flag here.
To resolve dependency conflicts, there are two ways:
1) Exclude the one you don't want
<depdency>
<groupId>some.stuff</groupId>
<artifactId>with.transitive.depdency</artifactId>
<exclusions>
<exclusion>
<groupId>something</groupId>
<artifactId>unwanted</artifactId>
<exclusion>
<exclusions>
<depdency>
With this way, you will have to exclude on every dependency that brings in a transitive one. For this reason I like the other one better.
2) Explicitly add the version you want
<dependency>
<groupId>something</groupId>
<artifactId>with.version.conflict</artifactId>
<version>what I want</version>
</dependency>
This will make sure that any transitive dependency will be swapped with this exact version. This might also lead to errors though, if some framework actually needs an older version. For using this strategy safely, your dependencies will need to be fairly close to the newest available version (or versions released at the same time).
I'm having some problems with conflicting versions of some jars. I have a dependency on a library group-a:artifact-a:0.0.1 that has a dependency on group-b:artifact-b:0.0.1, but I don't want that group-b:artifact-b:0.0.1 to be included given that I know that at runtime there will be group-b:artifact-b:0.0.2.
How do I have to write the pom.xml file?
Is this one of the following correct? And what's the difference between these?
Solution 1:
Exclude group-b:artifact-b from group-a:artifact-a:0.0.1:
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>0.0.1</version>
<exclusions>
<exclusion>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
Solution 2:
Add group-b:artifact-b dependency as provided:
<dependencies>
<dependency>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
Solution 3:
Add group-b:artifact-b dependency as runtime:
<dependencies>
<dependency>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
Solution 4:
Add group-b:artifact-b dependency as provided or runtime and exclude it from group-a:artifact-a:0.0.1.
UPDATE:
Sorry for not being explicit, but yes #Tunaki's assumption is correct, the dependency group-b:artifact-b:0.0.2 is not required at compile time.
Option 5: Just declare the version explicitly in your POM.
Maven will overwrite the transitive dependencies if you explicitly declare them in the pom. You don't need to do any mucking about with provided or runtime scope.
According to the docs (emphasis mine):
Dependency mediation - this determines what version of a dependency will be used when multiple versions of an artifact are encountered. Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, until Maven 2.0.8 it was not defined which one would win, but since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.
So your pom should just be:
<dependencies>
<dependency>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
<version>0.0.2</version>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
You should use solution 4. Let's go through each solution:
Solution 1
This is using the exclusions principle of Maven. Maven resolves dependencies transitively. But when you do not want a specific transitive dependency to be included in your classpath, you can exclude it using this mechanism.
The excluded dependency will not be used at compile-time or run-time.
But this is not what you want, since you know that your project requires group-b:artifact-b at run-time. In this scenario, the pom.xml does not declare it.
Solution 2
You are using the provided scope. provided in Maven means that this dependency is required at compile-time but should not be included in the final artifact. Typically, this dependency will be provided at run-time by a container, such as a web server.
As such, Maven will override the transitive dependency group-b:artifact-b:0.0.1 of group-a:artifact-a. In the final dependency tree, group-b:artifact-b:0.0.2 will be resolved as a provided dependency and will not be included in the final artifact (for example, if building a war, this library will not end up in WEB-INF/lib).
Solution 3
This time, you are using the runtime scope. This is much like Solution 2.
The difference is that in the final dependency tree, group-b:artifact-b:0.0.2 will be resolved as a run-time dependency and will be included in the final artifact (for example, if building a war, this library will end up in WEB-INF/lib).
Solution 4
This is the same as solution 2 and 3. The difference is that Maven will not override the dependency since you are explicitely excluding it from the list of transitive dependencies of artifact-a. But the result will be the same.
What is the correct solution?
This really depends on how your dependency will be present at run-rime. If it provided by a container, you should use Solution 4 with the provided scope. If not, you should use Solution 4 with the runtime scope.
I am suggesting this solution because:
You are explicitely excluding the unwanted dependency from artifact-a transitive dependency: this makes it more clear that that specific dependency should not be used in the project.
You are explicitely including the wanted dependency in the right scope and the right version. Again, this makes the pom.xml easier to read and to understand.
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>0.0.1</version>
<exclusions>
<exclusion>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
<version>0.0.2</version>
<scope>provided</scope> <!-- or runtime, depending on your specific case -->
</dependency>
</dependencies>
I got Exception
java.lang.NoSuchFieldError: reportUnusedDeclaredThrownExceptionIncludeDocCommentReference outside eclipse in command line using maven.
The gwt libraries are declared at the top of list of dependencies and GWT 2.5.1 is being used.
How to solve this issue? Please help
Well, I figured out what is the problem.
In my pom.xml , I have this dependency
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>4.7.0</version>
The problem with this is that, jasper reports has a dependency on jdtcore
<dependency>
<artifactId>jdtcore</artifactId>
<groupId>eclipse</groupId>
<version>3.1.0</version>
</dependency>
jdtcore actually creates a conflict with the gwt compiler. To solve this problem, I need to add an exclusion in the jasper dependency like this
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>4.7.0</version>
<exclusions>
<exclusion>
<artifactId>jdtcore</artifactId>
<groupId>eclipse</groupId>
</exclusion>
</exclusions>
</dependency>
Now if still need the jdtcore library in the web app (normally to dynamically compile jasper reports) we can add the dependency with scope runtime like this
<dependency>
<artifactId>jdtcore</artifactId>
<groupId>eclipse</groupId>
<version>3.1.0</version>
<scope>runtime</scope>
</dependency>
Last note, if anybody gets the problem, then should look if any dependency in pom.xml has got a dependency on jdtcore, exclude it and include it as runtime
Hope this helps
For gradle exclude transitive dependency as follows in build.gradle:
dependencies {
compile('net.sf.jasperreports:jasperreports:3.7.4') {
//Exclude as it caused problems with GWT:
//http://stackoverflow.com/questions/17991063/java-lang-nosuchfielderror-reportunuseddeclaredthrownexceptionincludedoccomment
exclude group: 'eclipse', module: 'jdtcore'
}
}
Except after I made this change my jasper compilation fails. I am not sure yet how can I get Jasper compilation and GWT compilation to coexist in same project?
I have a case that I have the following cyclic dependencies in maven:
JAR A version 1.1 depends on JAR B version 1.0
JAR B version 1.1 depends on JAR A version 1.0
For some reason that I don't know, Maven brings all the 4 JARs: A 1.0, A 1.1, B 1.0 and B 1.1, which results in a classpath conflict.
This really sucks. I already ask the developers of both JARs to fix this, however I can't simply sit and wait for the day that they decide to fix this.
I tried this:
<dependency>
<groupId>groupA</groupId>
<artifactId>artifactA</artifactId>
<version>1.1</version>
<type>pom</type>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>groupB</groupId>
<artifactId>artifactB</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>groupB</groupId>
<artifactId>artifactB</artifactId>
<version>1.1</version>
<type>pom</type>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>groupA</groupId>
<artifactId>artifactA</artifactId>
</exclusion>
</exclusions>
</dependency>
The result is that maven excludes all of the JARs as if none dependency were added, and the project does not compiles because there are missing classes.
So, other than just asking both JARs developers to solve this, what can I do? How can I import both the new dependencies while leaving out both the old ones?
Pragmatic solution would be to redeclare the unwanted dependencies as provided, for example:
<dependency>
<groupId>groupA</groupId>
<artifactId>artifactA</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
I'm not particularly fond of using provided in such manner, since it leaves the dependency in the compile time and could lead to unwanted compile dependencies, but I see no other way in your case ;(.