How to override default version of library included by artifact in maven? - java

I have a spring batch dependency in my pom.xml declared as below:
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>3.0.9.RELEASE</version>
</dependency>
There is one artifact xstream that is included by above with version 1.4.7 and it needs to be updated to 1.4.11.
It can be added as follow:
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11</version>
</dependency>
What is the correct way for this?I am thinking of following approach:
Both above pieces of code will be there but do I need to use < exclusions > to specifically exclude xstream artifact old version from spring-batch-core or does maven takes care of this automatically?

Better way will be using <dependencyManagement/> tag. Dependency management will make sure the version will be maintained even if some other transitive dependency brings higher version of the dependency.
Usage:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11</version>
</dependency>
</dependencies>
</dependencyManagement>
Note: dependencyManagement tag is used for defining the version and scope (if not in the default scope which is compile) of a dependency it does not add the dependencies in it to you project, you must define separate <dependencies/> section in your pom.xml for adding dependencies to your project.
In your case it will be like.
<project 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/maven-4.0.0.xsd">
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11</version>
</dependency>
</dependencies>
...
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>3.0.9.RELEASE</version>
</dependency>
...
</dependencies>
...
</project>
In this case spring-batch-core is added as a direct dependency and if it has xstream as dependecny you project will use 1.4.11 version even spring-batch-core has a different version of xstream as dependency.
Ref: Dependency Management

Related

Maven - should I include dependency that my imported library contains

Assuming that I have an artifact my-project-core that includes some dependencies with library:
<artifactId>my-project-core</artifactId>
<name>CORE</name>
...
<dependency>
<groupId>com.bun.puffy</groupId>
<artifactId>just-the-lib</artifactId>
<version>1.0.0</version>
</dependency>
And I want to use it in new project that have dependency with my-project-core
<artifactId>new-project-using-core</artifactId>
<name>NEW PROJECT USING CORE</name>
...
<dependency>
<groupId>com.bun.puffy</groupId>
<artifactId>my-project-core</artifactId>
<version>1.0.0</version>
</dependency>
<!-- should I also add this ?
<dependency>
<groupId>com.bun.puffy</groupId>
<artifactId>just-the-lib</artifactId>
<version>1.0.0</version>
</dependency>
-->
should I add dependency for just-the-lib in the new project or should I not do this and depend on the dependency of my-project-core? What are pros and cons?

Spring-Boot: How can we remove some dependencies from Effective pom?

I am using spring-boot 2.0.3.RELEASE. When I am clicking on "show Effective POM" option by using IntelliJ IDEA, it loads Effective POM. And there I can see a few dependencies that my client don't want to have at there side.
Is there any way to tell Maven not to include these dependencies? How can we exclude dependencies from effective poms?
Maven provides a way to exclude dependencies with the exclude tag
Here is an example taken from the documentation website https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
<dependencies>
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
The idea is to locate parent dependencie from where you are getting deps you don't want and add an exclusion tag.
If they are needed in runtime you can specify the scope to provided
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
That will tell maven to use the deps to compile but not no include them in the target package, and they will be provided in the production environment by the JVM executing the code.
Hope this helps

Missing artifact net.sf.jung:jung2:jar:2.0

jung2 is in maven repository, here and here.
But my Eclipse does not finding it out:
Code is here:
<project 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/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>tests.jung</groupId>
<artifactId>TryJung</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>net.sf.jung</groupId>
<artifactId>jung2</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
</project>
UPDATE
Sorry can't accept answers about dependency type, because it is not complete. The code for jung dependency was taken from Maven repository directly:
So, I need an explanation, why doesn't code, taken from repository site, work actually.
What is happening here, who is "guilty"?
As already said, you are addressing a pom file. Which is, in a sense, correct, but if you want to compile you will need to add the actual jars in the dependencies section, such as:
<dependencies>
<dependency>
<groupId>net.sf.jung</groupId>
<artifactId>jung2</artifactId>
<version>${jung.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>net.sf.jung</groupId>
<artifactId>jung-api</artifactId>
<version>${jung.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.sf.jung</groupId>
<artifactId>jung-visualization</artifactId>
<version>${jung.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.sf.jung</groupId>
<artifactId>jung-graph-impl</artifactId>
<version>${jung.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.sf.jung</groupId>
<artifactId>jung-algorithms</artifactId>
<version>${jung.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.sf.jung</groupId>
<artifactId>jung-io</artifactId>
<version>${jung.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
Do not forget to define the version property also in the properties section:
<properties>
<jung.version>2.0.1</jung.version>
</properties>
Hope this helps.
The problem is simply the artifact you are adressing is a pom file and not a jar file. That's the reason for the message.
just stumbled into the same problem pit. apparently these are pom files purely for building/documenting (all) sub-projects (or submodules in maven speak) of a project (in this case jung2)
they can't be used as a dependency in a useful way
actually you can depend on them with <type>pom</type> but will just include the dependencies of that pom but not it's modules.
see here for a more complete explanation:
How to use POMs as a dependency in Maven?

maven: how to disable certain dependencies?

Well, I'm not talking about the well-known commons-logging problem, I know I can disable it by setting the 99.0-does-not-exist version.
My problems is, some packages are contained in different dependencies, say, aspectjlib is contained both in org.aspectj:aspectjlib and aspectj:aspectjlib. In some cases, transitive dependencies may introduce the two jars at the same time, while of different versions, e.g., org.aspectj:aspectjlib:1.7.3, aspectj:aspectjlib:1.6.1. And mis-loading aspectj:aspectjlib:1.6.1 accidentally is not my intention. So is there a way like commons-logging that I can disable aspectj:aspectjlib completely?
I tried the same trick using 99.0-does-not-exist, only to find an error from maven:
[ERROR] Failed to execute goal on project XXX: Could not resolve
dependencies for project XXX:jar:1.0.0-SNAPSHOT: The following
artifacts could not be resolved:
aspectj:aspectjlib:jar:99.0-does-not-exist,
aspectj:aspectjrt:jar:99.0-does-not-exist,
aspectj:aspectjweaver:jar:99.0-does-not-exist: Could not find artifact
aspectj:aspectjlib:jar:99.0-does-not-exist in tbmirror
(http://mvnrepo.taobao.ali.com/mvn/repository) -> [Help 1]
Well, although some repositories do provide 99.0-does-not-exist for logging system dependencies like log4j, slf4j-log4j, commons-logging, etc., this is not a universal solution.
I find a solution to do this: use 'provided' scope.
To clarify, in my example above, I have two conflicting dependencies: org.aspectj:aspectjlib:1.7.3, aspectj:aspectjlib:1.6.1, I want to disable aspectj:aspectjlib:1.6.1, I only need to put this in top-level pom:
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjlib</artifactId>
<version>1.6.1</version>
<scope>provided</scope>
</dependency>
in this way, aspectj:aspectjlib:1.6.1 will never appear in the final built lib.
You can use Maven's dependency exclusions to eliminate the version you don't want. Using your example:
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-new-aspectj</groupId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-old-aspectj</groupId>
<exclusions>
<exclusion>
<groupId>org.aspectj<groupId>
<artifactId>aspectjlib</artifactId>
<exclusion>
</exclusions>
</dependency>
</dependencies>
Alternatively, you can simply pin the version you desire using dependency management:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjlib</artifactId>
<version>1.7.3</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-new-aspectj</groupId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-old-aspectj</groupId>
</dependency>
</dependencies>
If you are not sure which dependencies include which versions, you can use this to discover that info:
mvn dependency:tree -Dincludes='org.aspectj:aspectjlib'
There is no 99.0 version for aspectj:aspectjlib, your project is configured to use wrong version, check for 99.0 in your pom.xml

How to use POMs as a dependency in Maven?

Is there a way to add a pom type dependency to my POM and get all its modules?
JavaMail is a good example. Maven Central Repo has a parent POM called: com.sun.mail:all:1.5.0 with modules: mail, mailapi, mailapijar, smtp, imap, gimap, pop3, and dsn.
However, the "all" artefact only has a single file: pom.xml Is there a way to add this "all" artefact as a dependency to my POM and get all its modules? I am 90% sure this is not the right way to use dependencies in Maven, but I want to hear it from an expert on The Stack.
Ideas:
<dependencies><dependency>...<type>pom</type></dependency></dependencies>
<dependencyManagement><dependencies><dependency>...<type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
Related: Netbeans: maven dependencies of type pom
You have to go with
<dependencies>
<dependency>
<groupId>com.my</groupId>
<artifactId>commons-deps</artifactId>
<type>pom</type>
</dependency>
</dependencies>
This will transitively add all dependencies declared in com.my:commons-deps to your current POM.
Using
<dependencyManagement>
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>...</artifactId>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
works as a simple 'include' of artifacts versions in your dependency management. Thus, it won't add any dependency in your project.
I believe you can create your own POM which aggregates the dependencies you want, and then in your original project add a dependency on that aggregate pom. You will still have to add dependencies on each individual module in your dependency POM, but it will be abstracted from the actual project POMs and allows those dependencies to be managed in one place, which could become useful if you end up having multiple projects that depend on that set of dependencies.
In your example you could create a new pom like this:
<?xml version="1.0" encoding="UTF-8"?>
<project 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>mail-deps</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>mail</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>mailapi</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>mailapijar</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>imap</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>gimap</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>pop3</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>dsn</artifactId>
<version>1.5.0</version>
</dependency>
</dependencies>
</project>
Then in your original project just add:
<project 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/maven-v4_0_0.xsd">
...
<modules>
<module>src/main/java/com/mycompany</module>
</modules>
...
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>mail-deps</artifactId>
<version>1.0.0</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
The short answer: You cannot do this in Maven.
The other answers make only the "all" POM a dependency. Does not solve the issue. Another answer tries to import the dependencies of the "all" POM. I don't need the dependencies; I need the (child) modules of the "all" POM. Again, does not solve the issue.
Side note: I was using the JavaMail library incorrectly. I only needed to add one dependency: com.sun.mail:javax.mail:1.5.0
If the pom you're trying to import, contains dependencies defined in a <dependencies/> section, and you would like to import them all, you can try the code below.
(Disclaimer: I haven't done this in a while): in your <dependencyManagement/> section, add the pom dependency like this:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>kung.fu<groupId>
<artifactId>ninja</artifactId>
<version>1.2.3</version>
<scope>import</scope>
<type>pom</type> <!-- Not too sure if you needed this
when it's scoped as import,
but just in case -->
</dependency>
</dependencies>
</dependencyManagement>
It may as well be the case that you define the dependency directly in the <dependencies/> section not needing the <dependencyManagement/> bit, but as far as I recall, it should be scoped import as shown above.
As someone already wrote above : You can't do it . But this is what i did and it worked .
Lets assume you have some pom file (JavaMail in your example) with following :
<type>pom</type>
<dependencyManagement><dependencies><dependency></dependencyManagement>
And You want copy all jars mentioned in this pom to some place .
This is what i did and it is fast working solution
Open original pom and just copy-paste all dependencies section from original pom file to your new pom as is .
Of course use maven dependency plugin to copy all .

Categories

Resources