Dependeny Management using POM import - maven

I am creating a project 'test-jar' in my local and i am using pom file which I don't have write access as Parent of 'test-jar' project. The parent project has already defined depedencyManagement with old versions.
As I have to update dependency versions in my project and planning to override parent's dependency Management. So, I have created another POM file with my own dependency Management and imported into 'test-jar' project.
My Project :
<project>
<artifactid>test-jar</artifactid>
<parent>
<artifactId> test-parent </artifactId>
</parent>
<dependencies>
<dependency>
<artifactId>jar/artifactId>
</dependency>
<dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<artifactId>custom-pom</artifactId>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
</project>
My Parent Project:
<project>
<artifactid>test-parent</artifactid>
<dependencyManagement>
<dependencies>
<dependency>
<artifactId>jar/artifactId>
<version>1.0</version>
</dependency>
</dependencyManagement>
</project>
My Custom POM for updated dependencyManagement:
<project>
<artifactid>custom-pom</artifactid>
<dependencyManagement>
<dependencies>
<dependency>
<artifactId>jar</artifactId>
<version>3.0</version>
</dependency>
</dependencyManagement>
</project>
The problem is, I am always getting dependency version from parent pom, though i have imported new dependency management in project.
I am using Maven 2.2.1 version here.
Is there any solution how to overwrite Dependency Management from Parent POM ?

Based on the documentation:
This scope is only used on a dependency of type pom in the
section. It indicates that the specified POM
should be replaced with the dependencies in that POM's
section. Since they are replaced, dependencies
with a scope of import do not actually participate in limiting the
transitivity of a dependency.
Apart from your problem you can simply use differerent version which are different of the onses defined in the parent pom's dependencyManagement. Furthermore you could create a separate pom wich defines the dependencies with new version (dependencyManagement) and inherits from the given parent.

Related

Maven projects - how to read a property that is defined in the pom file of a project that is added as a dependency

I am working on a large project that contains many maven projects. We are using Maven 3.3.9.
I want to use a property that is defined in one maven project in another project, but i can't access the property.
The situation is: there is one maven project called "product-packaging", that has a pom file that includes some properties. This maven project only contains a pom file. It is used for generating a package that contains a set of components that are compatible with each other.
There is another maven project called "projectX" that has a dependency on "product-packaging". In "projectX" we want to use a property that is defined in "product-packaging".
I want to add xx-ws-rest as a dependency in projectX, and i want to set the version as xx-ws-rest.version, which is a property that is defined in "product-packaging"
The pom of "product-packaging" looks like:
<project ...>
...
<properties>
<xx-ws-rest.version>1.6.0</xx-ws-rest.version>
</properties>
...
</project>
The pom of "projectX" looks like:
<project ...>
...
<properties>
<product-packaging.version>1.6.0</product-packaging.version>
</properties>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.company.product</groupId>
<artifactId>product-packaging</artifactId>
<version>${product-packaging.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.company.product.xx</groupId>
<artifactId>xx-ws-rest</artifactId>
<version>${xx-ws-rest.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.company.product.xx</groupId>
<artifactId>xx-ws-rest</artifactId>
<type>war</type>
</dependency>
....
</dependencies>
</project>
AFAIK this is not possible. The usual way to define common properties for different projects is to use a parent POM. There, you can define properties and let the different projects inherit from that parent POM - that way, the properties are visible for all child projects.

Dependencies vs DependenciesManagement?

I have gone through differences between dependencymanagement and dependencies in maven but i am still unclear when to use
just dependencies tag in parent pom and when to use dependenciesManagement tag ?
My understanding is when my all child modules need to use same dependency version then we should declare the Dependencies under Dependencies tag(without dependencyManagement tag)
But on other hand if some of the child project need to use different version then we should declare the Dependencies under Dependencies tag(which will be under dependencyManagement tag). then Child modules can refer them with overridden version
Is that correct ?
Declaring a <dependency> within <dependencyManagement> does not set the specified artifact as dependency for any project – parent or childs. It just states: If you want to use this as dependency then you can use it with these settings (version, scope, ...) without having to specify the settings again, and again, and ... You can, however, override a "management" setting in a "real" <dependency> anytime.
See also POM Reference, Dependency Management.
There are two options for a parent POM regarding your second paragraph:
As you describe correctly:
<dependencies>
<dependency>
<groupId>g-id</groupId>
<artifactId>a-id</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
I'd use this for consistency:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>g-id</groupId>
<artifactId>a-id</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>g-id</groupId>
<artifactId>a-id</artifactId>
</dependency>
</dependencies>
Your third paragraph is correct..

Maven issue when overriding an environment specific systemPath property

I experienced issues with a maven build that does not behave the same way if done on Windows (like they were done in the past) or Linux (like I want to do them now).
I want to build a project that has a dependency on another project that pom that itself imports a pom that contains a Windows path.
my project | other project
|
mybuild -------|------> pom --------> pom with systemPath
dependency import
|
But in a nutshell, here is my pom:
<groupId>test.properties</groupId>
<artifactId>buildme</artifactId>
<version>1.0-SNAPSHOT</version>
...
<dependencies>
<dependency>
<groupId>test.properties.installme</groupId>
<artifactId>module</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
</dependency>
</dependencies>
And I depend on a pom that looks like this (not under my control)
<groupId>test.properties.installme</groupId>
<artifactId>module</artifactId>
<version>1.0-SNAPSHOT</version>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>test.properties.installme</groupId>
<artifactId>dependency</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
and the problem lies in this last pom (not under my control):
<modelVersion>4.0.0</modelVersion>
<groupId>test.properties.installme</groupId>
<artifactId>dependency</artifactId>
<version>1.0-SNAPSHOT</version>
...
<properties>
<com.sun.tools.path>D:/java/jdk1.8.0_65/lib/tools.jar</com.sun.tools.path>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${com.sun.tools.path}</systemPath>
</dependency>
</dependencies>
</dependencyManagement>
I have no control on the other project in question. I totally agree that a refactoring to use environment variable in place of the hard coded paths would solve my problem.
But instead the Windows path is defined in a property. One would think that overriding the value of the property depending on my platform would be enough. But it is not.
Unfortunately in this precise case case maven seems to behave to behave poorly.
Before applying any property override in any form (in settings.xml, -Dproperty=, redefinition in root pom), maven starts building the effective pom. And during that step, if it finds the pattern I mentioned above (a dependency on another pom that itself imports a pom that contains a Windows path), then it says:
The POM for <groupId>:<artifactId>:jar:<version> is invalid, transitive dependencies (if any) will not be available
As a consequence, my project needs to explicitly define all the dependencies of the second project. And I cannot rely on transitive dependencies which gives me a lot of trouble.
In order to illustrate the issue, I created a minimal example showing the problem. It can be found here:
https://github.com/fabricepipart/test-properties
Do you see any workaround for this?
Any way to override the value of the property and still benefit from the maven transitive dependencies?
Thanks a lot

Defining a parent POM which references that POM version

I have a Maven parent-child structure.
Parent pom has a dependency defined like this in the dependencyManagment section:
<dependencyManagement>
...
<dependency>
<groupId>myGroupId</groupId>
<artifactId>dependency</artifactId>
<version>${project.version}</version>
</dependency>
...
</dependencyManagement>
Child pom uses that dependency:
<dependency>
<groupId>myGroupId</groupId>
<artifactId>dependency</artifactId>
</dependency>
The version is resolved to ${project.version} which in turn is resolved to child project version.
In my case, child has different versioning cycle to its parent. The problem is that I want the dependency included to have parent project version instead of child version. I can't assume hierachy is only one level so I can't use ${parent.version}. I want the version resolved to match the version of the pom in which it is defined.
How can I do that?
Thanks.

Maven modules are trying to use parent dependencies

I have a maven project where the parent module has a lib directory containing various jars that are necessary for compilation, but aren't included in the final product. When I try to get the children modules to build it fails. It says "The following artifacts could not be resolved" then eventually says "Could not find artifact local_dependency at C:\path\to\project\modules\module_name\lib\local_dependency.jar".
The children modules do not depend on the libraries that the parent uses, however it still wants to include them. Is there an option I need to set to prevent this?
Parent Pom snippet:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<currentVersion>1.0.0</currentVersion>
</properties>
<groupId>com.project</groupId>
<artifactId>project_artifact</artifactId>
<packaging>pom</packaging>
<version>${currentVersion}</version>
<modules>
<module>modules/module_name</module>
</modules>
<dependencies>
<dependency>
<groupId>group.id</groupId>
<artifactId>local_dependency</artifactId>
<version>1.0</version>
<systemPath>${basedir}/lib/local_dependency.jar</systemPath>
<scope>system</scope>
<optional>true</optional>
</dependency>
</dependencies>
Child pom snippet:
<parent>
<groupId>com.project</groupId>
<artifactId>project_artifact</artifactId>
<version>${currentVersion}</version>
<relativePath>../../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>net.some.dependency</groupId>
<artifactId>artifact_name</artifactId>
<version>1.0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.project</groupId> <!-- The child depends on the parent for the parent's API-->
<artifactId>project_artifact</artifactId>
<version>${currentVersion}</version>
<type>jar</type>
</depdencency>
</dependencies>
So from this, the child pom will attempt to include group.id:local_dependency from project_base/modules/module_name/lib/local_dependency.jar but it doesn't exist and doesn't need to exist.
You can exclude specific transitive dependencies in the dependency declaration. In your case, the following change in the child pom's dependency on the parent should get the build working:
<dependency>
<groupId>com.project</groupId> <!-- The child depends on the parent for the parent's API-->
<artifactId>project_artifact</artifactId>
<version>${currentVersion}</version>
<type>jar</type>
<exclusions>
<exclusion>
<groupId>group.id</groupId>
<artifactId>local_dependency</artifactId>
</exclusion>
</exclusions>
</dependency>
The child inherits the parent's dependencies, whether or not you include the dependency explicitly. Two possible ways to resolve the issue are:
Don't build any jar artifact in the parent - create a sub-module for this and use the sub-module as a dependency in its siblings.
Use a fixed path (not relative to ${basedir}, since this changes in each module build, which tries to resolve the location anew). If you always build from the parent's directory, you could use ${user.dir}.

Resources