DependcyManagement or dependencies ?? in pom maven - java

According to the maven docs Dependency management
is a mechanism for centralizing dependency information.
and from this question here SO Question, many people suggested to use Dependency managmement instead of dependencies when we have a common jar file for all children.
as in dependency management , dependencies are propogated only when children request for it but incase of dependencies the dependecies are propogated even when not required.
but wouldn't it be a better approch when the jar file is common to all children ,i.e when all the children inherit the same jar file
for example (rewritten example taken from maven docs)
child a
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
</dependency>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
</dependency>
</dependencies>
child b
<dependencies>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
</dependency>
</dependencies>
parent of both a and b
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
but wouldn't this yeild the same result ??
parent of both a and b
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
child a
<dependencies>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
</dependency>
</dependencies>
child b
<dependencies>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
</dependency>
</dependencies>
or did i misunderstand them??
and which one should i use and in what conditions ??

Dependency management section in the parent pom is managing versions and only versions of these libraries, when you are using them in the child projects.
Dependency section on the contrary ENFORCES all child modules to have these dependencies, regardless child modules need them or not.
If you are sure ALL your child modules will use group-a:module-a:version, then feel free to declare it in parent dependencies section.
If you have at least one child module in the project, where such enforced dependency is unnecessary, then dependencyManagement better suites your need.

Related

dependencyManagement and version of dependencies

In the pom file I have the dependencyManagement tag (could be also inherited from parent) and i would like to know how this tag can influence the version of dependencies. so let show an exemple:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
In the exemple below what version of the hamcrest-core dependency will be used? the version 2.2 or 1.0?
dependencies defined in the pom should get priority over dependencyManagement.
Using dependencyManagement is useful when you have child projects under a parent project,
Dependencies specified in the parent pom dependencies section will always be included as a dependency of the child modules.
Dependencies specified in the dependencyManagement section, will only be included in the child module if they were also specified in the dependencies section of the child module.
You can specify the version and scope in the parent, but you can leave them out when specifying the dependencies in the child POM (to ensure all projects are using same version).

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

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

Package doesnot exist on maven compilation

There exist a class in project that uses ILoggingEvent which is found to be imported from logback-classic.jar. It is available in project as maven dependency as well and in .m2 folder. But when i do mvn clean install, I get below error:
[ERROR] /C:/Users/xxx/project/LogMonitor.java:[6,34] package
ch.qos.logback.classic.spi does not exist
cannot find symbol symbol:
class ILoggingEvent
When i extracted files from jar,I was able to find the same package with that jar. Above all , i see no error mark in LogMonitor class too , though it is the one which uses ILoggingEvent
I tried maven update,project clean. But still i see it failing. There is no issue in configuration of maven as another repository is built successful. Please favour on how it can be resolved
Edit:
pom file of repo where this code exist.:
<parent>
<groupId>com.common</groupId>
<artifactId>common-pom</artifactId>
<version>0.25.5</version>
</parent>
<artifactId>aws</artifactId>
pom of common:
<groupId>com.common</groupId>
<artifactId>common-pom</artifactId>
<version>0.25.5</version>
<packaging>pom</packaging>
<name>Common</name>
<modules>
<module>xxx</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>xxx</artifactId>
<version>${project.version}</version>
</dependency>
<dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
First of all it is bad practice to have actual dependencies in a parent pom. Instead you should only have the dependency-management in the parent pom to specify the versions of the dependencies that should be used and then in the consuming children the required dependencies. Otherwise you might end-up with jars on the classpaths of projects that do not actually require them.
In short:
The parent pom (you common pom) should only contain:
<groupId>com.common</groupId>
<artifactId>common-pom</artifactId>
<version>0.25.5</version>
<packaging>pom</packaging>
<name>Common</name>
<modules>
<module>xxx</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
</dependency>
</dependencies>
<dependencies>
<dependencyManagement>
And the consumers of the parent pom will then contain the dependencies without the version number:
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
The important part is that you specify the correct version number and the designated scope at some point(see https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope).
Your dependency should look like this:
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
The scope is maybe set to <scope>test</scope> . If you want to use it in src/main/java, you have to set the scope at compile (default when no scope is defined)

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?

Declaring multiple artifactId under one groupId in a pom.xml

I'm declaring quite a few dependencies within one package in a Maven pom.xml, and the document is getting very long and difficult to maintain as is, even without a separate dependency block for each referenced artifact. Instead of doing this:
<dependencies>
<dependency>
<groupId>com.test.foo</groupId>
<artifactId>bar1</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.test.foo</groupId>
<artifactId>bar2</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.test.foo</groupId>
<artifactId>bar3</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
Is it possible (and I'd be willing to work with a plugin, if necessary) to do something like this:
<dependencies>
<dependency>
<groupId>com.test.foo</groupId>
<artifactId>bar1</artifactId>
<artifactId>bar2</artifactId>
<artifactId>bar3</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
No. But if you own those dependencies (I assume from your code that you do) you can have a module aggregating all those dependencies, then you can depend on that module. Or if working in a multi module project you can create a parent pom to define the dependencies from your project so you don't repeat it everywhere.

Categories

Resources