I have a dependency called "general-lib" which will be modified and used by 3 teams.
Admin, Child-ABC and Child-XYZ are those 3 projects. Those 3 apps
deployed in same server.
Child-XYZ and Child-ABC are communicating to
Admin app frequently.
When we change general-lib version, I want
that Child apps also should use same version what admin app uses.
Finally that particular dependency version should be managed at super application.
is there any to do that ? Please let me know if I need to explain better.
You can define a BOM (Bills of Materials) where you can move the dependecyManagement for the common artifacts and then declare it as a parent in your 3 projects. This is an example of BOM:
<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>your.group.id</groupId>
<artifactId>whatever-BOM</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<general-lib.version>1.0.2</general-lib.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>your.groupid</groupId>
<artifactId>general-lib</artifactId>
<version>${general-lib.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
For more details on BOM, you can read the article Spring with Maven BOM that even if it's related to Spring, it will explain in a detailed way what are BOMs and how to use them.
Ohter possibility, is to define those 3 projects as a module of a higher level project and manage in this one the dependencyManagement.
<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>your.group.id</groupId>
<artifactId>whatever</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>Admin</module>
<module>Child-ABC</module>
<module>Child-XYZ</module>
</modules>
<packaging>pom</packaging>
<properties>
<general-lib.version>1.0.2</general-lib.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>your.groupid</groupId>
<artifactId>general-lib</artifactId>
<version>${general-lib.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Related
I've started to create a java project using the dropwizard framework and maven. My pom.xml file looks like
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.dexcane</groupId>
<artifactId>dexcane-backend</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<dropwizard.version>2.1.4-SNAPSHOT</dropwizard.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/io.dropwizard.archetypes/dropwizard-archetypes -->
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-core</artifactId>
<version>2.1.4-SNAPSHOT</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
I'm following the dropwizard tutorial. When I hover over the "2.1.4-SNAPSHOT" dependency Intellij says "Dependency 'io.dropwizard:dropwizard-core:2.1.4-SNAPSHOT' not found ". Does anyone know what's wrong with the import? The tutorial says the current version of dropwizard is 2.1.4-SNAPSHOT.
You shouldn't add it with the type of pom as its packaging is jar.
When I declare a dependency in a parent pom 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<!-- not relevant for this question -->
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.12</version>
</dependency>
</dependencies>
</project>
above i have declared spring-core as a dependency for parent pom.
Now in child pom, i am importing the parent pom -
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>deps2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- not relevant for this question -->
</dependencies>
</project>
Now on looking at the dependencies inherited by child pom, there are none. Should NOT the spring-core jar be inherited by child project in all cases. As the parent pom directly depends on this jar and is it not passed on/inherited by child projects.
Note: This question is not about dependency management and versions
I understand dependencyManagement, which is to ensure that a set of projects have the same version and scope of a depencency.
There is a difference between placing a parent tag and Bill of materials (importing the pom in the dependency management section)
Using <parent> is a "real inheritance" in maven. You define this tag on the child pom and by that you will get all the dependencies defined in the parent pom automatically (also properties and plugins).
The Bill of Materials on the other hand (This is how its called in the official documentation) doesn't import any dependencies by itself, however it allows to avoid specifying the versions of the dependencies in the pom of your application, because you define them in this BOM.
So to answer your question, you should really rewrite the child pom as:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>deps2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<!-- not relevant for this question -->
</dependencies>
</project>
Your child pom is a standalone pom because you didn't specified a parent. You define a parent by adding this tag :
<parent>
<groupId>yourpackage</groupId>
<artifactId>yourartifactid</artifactId>
<version>version</version>
</parent>
In your case, this block should do the trick :
<parent>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
I know that your question was not about depedencies management; but for people that would not know the difference I'll write some words about that.
Note that by importing your pom in <dependenciesManagement> you don't have any impact given that it only defines intentions of use but not concrete import. The <dependencies> contains the concrete imports and it's only its content that you can use in your application.
We have a multi module project where we define several dependencies in parent pom under dependencyManagement tag to manage dependencies version.
It works fine for several modules but one.
Parent pom
<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>my.org.product</groupId>
<artifactId>product-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<parade-web.version>2.0.0</parade-web.version>
<!-- other properties -->
</properties>
<modules>
<module>../ProductWeb</module>
<!-- other modules -->
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>my.org.parade</groupId>
<artifactId>ParadeWeb</artifactId>
<version>${parade-web.version}</version>
</dependency>
<!-- other dependencies -->
</dependencies>
</dependencyManagement>
</project>
ProductWeb pom
<?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>
<parent>
<groupId>my.org.product</groupId>
<artifactId>product-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../productparent</relativePath>
</parent>
<artifactId>ProductWeb</artifactId>
<packaging>war</packaging>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency> <!-- 'dependencies.dependency.version' for my.org.parade:ParadeWeb:jar is missing. -->
<groupId>my.org.parade</groupId>
<artifactId>ParadeWeb</artifactId>
<type>war</type>
</dependency>
<!-- other dependencies -->
</dependencies>
</project>
If I add <version>${parade-web.version}</version> in my ProductWeb pom, NetBeans warns me that
Overrides version defined in DependencyManagement. The managed version is 2.12.2-RELEASE.
The only difference between this dependency and the other is the war type, but I don't get why dependency management fails to sets its version.
UPDATE
I managed to omit version tag but I needed to add <type>war</type> on both parent and child.
I don't understand. Does parent try to resolve dependency version looking for a war but then doesn't pass it through its children?
Add <type>war</type> to the dependencyManagement. This should do the trick.
I would like to have a "dependencies file" to be able to load this file into different maven poms. I have two poms in my project which are similar to some degree. I want the identical configuration in a third pom to be loaded by the working poms.
Is this possible?
e.g. something like:
<project A>
<dependencies>
<file> "depend.xml" </file>
</dependencies>
...
<project B>
<dependencies>
<file> "depend.xml" </file>
</dependencies>
...
You can create a parent POM file, which all your projects inherit. By specifying dependencies, versions, etc. in the parent POM file, you don't need to respecify them in each project (unless you need to override them for whatever reason).
There's more information at: https://www.smartics.eu/confluence/display/BLOG/2013/07/22/Using+Aggregate+and+Parent+POMs
You could create a hierarchical project making A and B a module of a common parent and manage your dependencies there.
Parent
<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>my.package</groupId>
<artifactId>parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>Parent</name>
<modules>
<module>A</module>
<module>B</module>
</modules>
...
<dependencies>
....
</dependencies>
</project>
A
<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>
<artifactId>A</artifactId>
<packaging>jar</packaging>
<name>A</name>
<parent>
<groupId>my.package</groupId>
<artifactId>parent/artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
Use properties
You can also introduce variables to organize your versions using this pattern.
...
<properties>
<alib.version>4.7</alib.version>
<properties>
...
<dependencies>
<dependency>
<groupId>alib</groupId>
<artifactId>someArtifact</artifactId>
<version>${alib.version}</version>
</dependency>
</dependencies>
I was not used to the concept of "build lifecycle". I thought that I have to have different poms for different tasks. e.g. one for packaging and one for deployment. After I found out that I can assign the plugins execution to specific phases I'm able to get along with only one pom which eliminates my whole question.
I have set-up a modular project in Maven with a parent project having more than one child projects.
The pom.xml of parent looks as follows -
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>parent-app</artifactId>
<version>${parent-application.version}</version>
<packaging>pom</packaging>
<dependencies>...</dependencies>
<properties>
<parent-application.version>1.0</parent-application.version>
</properties>
<modules>
<module>parent-model</module>
<module>parent-masters</module>
<module>parent-web</module>
</modules>
</project>
The pom.xml of child projects looks as follows -
<project ...>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.company</groupId>
<artifactId>parent-app</artifactId>
<version>${parent-application.version}</version>
</parent>
<packaging>jar</packaging>
<artifactId>child-model</artifactId>
<dependencies>...</dependencies>
</project>
Now, I need to use one of the child projects as a lib in a separate unrelated project. The pom of the new project looks like below.
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>unrelated-app</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>child-model</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
I keep getting the below error
Illegal character in path at index 57: http://repo.maven.apache.org/maven2/com/company/parent-app/${parent-application.version}/parent-app-${parent-application.version}.pom
The reason seems that I am inheriting the version attribute in child-model from prent-app.
Is there a way to overcome this issue? OR do I need to provide the version for each child module in respective pom.xml and cannot inherit from common parent.
Thanks in advance.
There is a way to overcome this issue with relativePath but I would not recommend it (take a look at this answer)... You should always provide version for parent module. To update all versions of all modules (parent+children) you can use maven-version-plugin or maven-release-plugin.