I am trying to exclude transitive dependency using following in the pom file
<dependency>
<groupId>xxxxx</groupId>
<artifactId>xxxxxx</artifactId>
<exclusions>
<exclusion>
<groupId>yyyyyyy</groupId>
<artifactId>yyyyyyy</artifactId>
</exclusion>
</exclusions>
</dependency>
where xxxxxx is the project I need. I am trying to avoid the transitive dependent project yyyyyy, that comes with it as it conflicts with the other version of the same project I already have as dependency.
When i build my project with this configuration and refresh eclipse, the project yyyyyyy-version.jar still shows in my classpath entry. I have to manually delete that classpath entry to make it work.
Please guide what am i doing wrong here. How to specify the exclusion in pom file so that I don't get this classpath entry.Thanks.
Update - I am not having any problem in the build but while i try to run the application , it find a particular parameter in 2 versions of a project - The desired one and the undesired one coming as a transitive dependency.
Perform mvn dependency:tree and analyze who has this transitive dependency too. Currently, there is no global exclude feature but an appropriate JIRA issue exists.
Related
I have a large Maven project with many modules and many pom.xml files. The project has changed and I suspect the pom's contain some unnecessary dependencies. Is there is a command which removes any unused dependencies from a pom?
The Maven Dependency Plugin will help, especially the dependency:analyze goal:
dependency:analyze analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared.
Another thing that might help to do some cleanup is the Dependency Convergence report from the Maven Project Info Reports Plugin.
You can use dependency:analyze -DignoreNonCompile
This will print a list of used undeclared and unused declared dependencies (while ignoring runtime/provided/test/system scopes for unused dependency analysis.)
## Be careful while using this, some libraries used at runtime are considered unused
For more details refer to this link
As others have said, you can use the dependency:analyze goal to find which dependencies are used and declared, used and undeclared, or unused and declared. You may also find dependency:analyze-dep-mgt useful to look for mismatches in your dependencyManagement section.
You can simply remove unwanted direct dependencies from your POM, but if they are introduced by third-party jars, you can use the <exclusions> tags in a dependency to exclude the third-party jars (see the section titled Dependency Exclusions for details and some discussion). Here is an example excluding commons-logging from the Spring dependency:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.5</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Have you looked at the Maven Dependency Plugin ? That won't remove stuff for you but has tools to allow you to do the analysis yourself. I'm thinking particularly of
mvn dependency:tree
I had similar kind of problem and decided to write a script that removes dependencies for me. Using that I got over half of the dependencies away rather easily.
http://samulisiivonen.blogspot.com/2012/01/cleanin-up-maven-dependencies.html
You can use DepClean https://github.com/castor-software/depclean/
DepClean is a tool to automatically remove dependencies that are included in your Java dependency tree but are not actually used in the project's code.
You can use dependency_cleaner https://github.com/junaidbs/dependency_cleaner
This jar will help to identify and remove unwanted dependency from pom.
It will automate the process of Removing a dependency and run then check whether the dependency needful
If you are using eclipse, right-click on the jar in Maven Dependencies:
Select Maven -> Exclude Maven Artifact...
I am migrating everything to spring-boot version 1.4.3.RELEASE.
Before the migration I was already using spring-data-solr version 2.1.0.RELEASE.
After introduction of spring boot i started noticing some errors, missing methods etc...
So i did some digging and found that within spring boot dependencies, spring-data-releasetrain uses older version of spring-data-solr than the version that is mandatory for me.
I have attempted to redeclare dependency with the version in my pom.xml, with no luck.
What is odd is that when i check my build path under the maven dependencies, the dependency is right for spring-data-solr version 2.1.0.RELEASE. So this does not cause any compile time issues, this happens only at run time...
I was wondering whether i can just exclude spring-data-solr and reimport my own? or is there better way to manage that?
Yes you can exclude the unwanted versions and reimport your own.
But this makes only sense, if your version of spring-data-solr is compatible with the spring-boot version you are using, at compile-time as well as at run-time.
The easiest way to do this, is to declare the desired version in the dependencyManagement section of your pom. See introduction-to-dependency-mechanism
dependency management takes precedence over dependency mediation for transitive dependencies
Which means, the version you declare in dependency management should override the versions from transitive dependencies.
I had constellations, where this was not sufficient and I still found the unwanted version in my classpath. If this happens, you have to exclude that unwanted dependency.
In Maven an exclusion looks like this :
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.7.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
</exclusions>
</dependency>
In the above code I am excluding spring-beans, so it is not introduced in the unwanted version required by spring-security-oauth2.
You need to do this for all dependencies, that somehow tear in your spring-data-solr in an unwanted version.
Your best friend when doing this is
mvn dependency:tree -Dverbose -Dincludes=org.springframework.data:spring-data-solr
Which shows you exactly, which dependencies your project has to spring-data-solr and why they are there. See Maven for details
So you make mvn dependency:tree, add exclusion and repeat until you have no dependency to the unwanted version anymore.
Than finally you add once the dependency to the desired version.
I have tried to search web for the problem I am facing but maybe I am not asking google the right question so here I am.
I am using IntelliJ IDEA for my multi-module project. For one of my modules, one of the class file is using a static import -
import static javax.ws.rs.core.Response.Status.Family.familyOf;
Being a big project, there are a lot of dependencies downloaded from internal repo but for some reason IntelliJ refuses to use the dependency "javax.ws.rs-api-2.0" instead it is using "jersey-core-1.8". Because of this it is throwing a compilation error saying Cannot find symbol "familyof".
I looked into Response.java from both the dependencies and found that jersey dependency does not have familyof method while javax.ws.rs-api-2.0 has it but IntelliJ doesnt use this dependency. How do I fix this problem. Most of the developers in my team are using Eclipse and they do not have this problem. I am trying to get used to IntelliJ IDE but cant seem to figure a way out of this. Any help in this regard is much appreciated.
PS - This issue does not occur in Eclipse IDE.
I could resolve this issue by following the below mentioned steps -
Goto "Open Module Settings" Command+Down arrow key
Select Dependencies tab
Search for the above two dependencies in the list
Move "javax.ws.rs-api-2.0" dependency up to ensure this dependency is above "jersey-core-1.8" dependency.
I don't think this is a permanent solution but it seemed to work. if someone with in-depth knowledge of Java/Mave/IntelliJ has an answer to this question that would be great!
You may be able to get the right result every time with Maven by shuffling around the dependencies in the pom.xml, and make sure the dependency you want to take precedence is declared first in the list of dependencies. yes, the order in which the dependencies are declared in pom.xml matters !
Then, if all of you are using the same Maven version, you should have a consistent result.
How does Maven choose between two versions of a same dependency?
As explained here, Maven chooses the first met dependency that's why it works when you change the order of the dependency in the pom.
How to find Maven dependencies conflicts?
In a terminal, in the pom folder :
mvn dependency:tree -Dverbose | grep "conflict"
will give you all the dependencies in conflict in your project.
With Eclipse IDE, click on the pom and on the Dependency hierarchy tab. Then, fill the Filter field with a dependency. On the left side, you will see the conflicts (like with mvn dependendy:tree, with filtered results) and on the right side, the dependencies chosen.
With IntelliJ, the documentation of IntelliJ can help you. There is a diagram view to find the conflicts.
How to resolve Maven dependencies conflicts?
Add dependencyManagement tag in the pom to tell Maven which dependency you want
Example :
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependencies>
</dependencyManagement>
Change the order of the dependency in the pom
Add an exclusion of the dependency
Example :
<dependency>
<groupId>com.my.groupid</groupId>
<artifactId>my-artifact-id</artifactId>
<version>1.2.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</exclusion>
</exclusions>
</dependency>
Why is there a difference between IntelliJ and Eclipse?
You can add a dependency to a module without adding it to the pom as explained in the documentation of IntelliJ. It's probably possible with other IDE.
IntelliJ IDEA lets you add a Maven dependency to your project. We recommend that you specify the dependency inside your POM. Dependencies that you set up manually inside IntelliJ IDEA module settings will be discarded on the next Maven project import.
The Maven plugin in Eclipse (M2Eclipse) may load dependencies differently compared to mvn
Please, read the documentation of IntelliJ to configure the project dependencies easily.
I have a Maven Java project. I don't want my project dependencies to be satisfied by chance through a chain of subdependencies when compiling the project. It is OK for me when building the final war when maven must check all used dependencies and add necessary libs to the war, but when compiling the code I want to be sure that only direct dependencies are used. Why?
Let's say I have two dependencies:
<dependency>
<groupId>com.package</groupId>
<artifactId>module-1</artifactId>
</dependency>
<dependency>
<groupId>com.package</groupId>
<artifactId>module-2</artifactId>
</dependency>
For our project module-1 and module-2 serve completely different purposes, but somewhere in the dependency tree of module-2, module-1 is used. I delete module-1 dependency, but maven continue to build my project without compilation errors, because it resolves module-1 from module-2 sub-dependencies. This change goes unnoticed.
After sometime we decide to remove module-2, because we don't need it. Strange enough but we can not any more compile classes which were using imports from module-1 and which are not connected to module-2 logic.
This is a simple case, but in big project this can make quite a dependency mess.
You can use the Maven dependency plugin goal "dependency:analyze" to give you a report of all used dependencies which are not declared on the current module (included transitively). That way Maven will still use transitive dependencies (no way around that I guess), but you can force yourself via the plugin to make sure these are also declared. It will also warn you of unnecessary dependencies. Mind, the plugin analyzes the compiled classes. At times, you may need to configure the plugin, because occasionally it may not detect that a dependency is required at compile time but not at runtime, e.g. because a constant was inlined.
If you really need to do this then you can setup exclusions in the pom.
e.g. here's an example of an exclusion in one of my poms where I don't want it to automatically get commons-logging because I'm using a different logging provider.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
You could do something like this (untested)
<dependency>
<groupId>com.package</groupId>
<artifactId>module-2</artifactId>
<exclusions>
<exclusion>
<groupId>com.package</groupId>
<artifactId>module-1</artifactId>
</exclusion>
</exclusions>
</dependency>
I wouldn't necessarily recommend this though. It makes sense in the case of my logging exclusion because I'm using slf4j instead of commons logging. I've seen other examples where this is used to exclude spring 2 if the project as a whole is using spring 3.
It's a bit difficult to tell from your example because it's so vague. In general you should keep your dependencies to a minimum. If module-2 depends on module-1 then it implies that your application won't compile or run without module-1. If in fact it can live happily without it then it's not really dependent.
As a side note it's a bit alarming that you don't have a version number against the dependencies. You'll probably find maven warns you about this. It's good practice to always include a version number. If you're dependent on a module which is currently in development then you should use the .SNAPSHOT suffix on the version to get the latest build for that version.
There seems to be no way to tell maven not to resolve dependency transitively: How to exclude all transitive dependencies of a Maven dependency. One of the reason's I think, is that the user can soon run into runtime troubles, when he finds that some of the artifacts are not being resolved at runtime or there are artifact versions problems. However, if you check the link out, you can make each of the deps 'standalone' with a wildcard exclusion pattern.
One other option is to use <optional> dependency for each of your module-X sub-dependencies. This will make sure the project compiles and non of your module-X would be resolved transitively. Like:
<dependency>
<groupId>com.package</groupId>
<artifactId>module-1</artifactId>
<optional>true</optional>
</dependency>
Still, analyzing the dependency tree might be the most safe and predictable choice.
It does sound a bit strange what you plan to do. In a way you sabotage the dependency management you want to use.
If your module-2 depends on module-1 and has a dependency to it, then any module that depends on module-2 only need to define that one.
You may be able to restrict the depth of the resolution using exclusions: Exclude all transitive dependencies of a single dependency
Newer versions of maven allow wildcards in those.
But: you will need to re-add the ones you actually need, this is by repeating the dependencies you have an other modules. This duplicates the work.
If there are artifacts that cause weirdness it may be possible to define a scope: http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html so it is not propagated to dependant modules as well.
I added some jars as dependencies in pom.xml, but it seems that some of them are useless because those jars were already downloaded using dependencies mechanism...
Is there a way to see those "built-in" dependencies, so that I could add only the needed dependencies in my pom.xml?
For example if I add a hibernate dependency in pom.xml one for cglib is not needed.
Don't do that - list every dependency of your code, but not of the libraries you use; Maven will do its transitive dependency thing and take care of them.
you can run mvn dependency:tree to get the whole tree including the transient dependencies that get included in your project.
There you can start looking
Hope that helped
First, check out Transitive Dependencies:
Transitive dependencies are a new
feature in Maven 2.0. This allows you
to avoid needing to discover and
specify the libraries that your own
dependencies require, and including
them automatically.
Then, a good dependency analyzer will help...
The mvn command-line is your first aid:
mvn dependency:tree
Sometimes you have to figure out where the version numbers came from (See also: Dependency Management). Here you'll have to unveil the parent relationships, and the 'effective-pom' command can help with that:
mvn help:effective-pom
Tool support is helpful as well...
m2eclipse has a Dependency Tree tab that shows how the different hierarchies collapse::
alt text http://www.sonatype.com/books/m2eclipse-book/reference/figs/web/eclipse_pom-editor-depend-tree.png
IntelliJ has another interesting view that lets you detect the conflicts:
(source: jetbrains.com)
If you are using Eclipse then you are see a visual dependency tree which is automatically generated. While adding a dependency if you do not want it to automatically pull some transitive dependencies use the exclusions tag like so
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernate.version}</version>
<exclusions>
<exclusion>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
<exclusion>
<groupId>asm</groupId>
<artifactId>asm-attrs</artifactId>
</exclusion>
<exclusion>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</exclusion>
</exclusions>
</dependency>
There are some known conflicts when using certain versions of hibernate and AOP due to cglib.
Is there a way to see those "built-in" dependencies, so that I could add only the needed dependencies in my pom.xml?
There are no built-in dependencies. However, when declaring a dependency on a given artifact, Maven will also retrieve the dependencies of this dependency, transitively. Such dependencies are called 3.4.4. Transitive Dependencies:
A transitive dependency is a dependency of a dependency. If project-a depends on project-b, which in turn depends on project-c, then project-c is considered a transitive dependency of project-a. If project-c depended on project-d, then project-d would also be considered a transitive dependency of project-a.
So if you need a dependency in your project, just declare it (and the dependencies of this dependency will come transitively).
To visualize the dependency tree of a project, the best tool is mvn dependency:tree (or any fronted offered by your favorite IDE). This is a must use tool to analyze your dependencies and check them for proper convergence and potential conflicts resulting in expected version being used.
For example if I add a hibernate dependency in pom.xml one for cglib is not needed.
Actually, this is a bad example, cglib is an optional dependency of Hibernate Core which declares in its pom.xml:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-cglib-repack</artifactId>
<version>2.1_3</version>
<optional>true</optional><!-- think of it as "excluded by default" -->
</dependency>
Hibernate gives you the choice between javassist and cglib, it's up to you to decide which one to use and to declare it explicitly, hence the optional status.
See also
Introduction to the Dependency Mechanism
The whole section 3.4. Project Dependencies in the Maven Reference Guide