How to load maven dependencies from another file? - java

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.

Related

Maven: why are dependencies declared in parent pom not inherited by child pom?

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.

pom use a common dependency for 3 applications Spring-mvc

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>

Using several pom files to build a project

I have two distinct complex build task which must be done sequentially by maven. For example creating war files, library and ...
As far as I know, I have to split these tasks into separate maven pom files. By this approach, each pom file has a specific responsibility, I can keep them as simple as possible and above all, as a result of some technical issues, I have to do this.
I put shared dependencies between these two files in a parent pom file to reduce duplication. In this case create-jar.xml and create-war.xml are tasks and parent.xml contains shared dependencies.
parent.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
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>main</groupId>
<artifactId>main</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.13</version>
</dependency>
</dependencies>
</project>
create-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
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>
<parent>
<artifactId>main</artifactId>
<groupId>main</groupId>
<version>1.0</version>
<relativePath>parent.xml</relativePath>
</parent>
<groupId>create</groupId>
<artifactId>create</artifactId>
<version>1.2-SNAPSHOT</version>
<packaging>jar</packaging>
</project>
create-war.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
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>
<parent>
<artifactId>main</artifactId>
<groupId>main</groupId>
<version>1.0</version>
<relativePath>parent.xml</relativePath>
</parent>
<groupId>create-war</groupId>
<artifactId>create-war</artifactId>
<version>1.1-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
</configuration>
</plugin>
</plugins>
</build>
</project>
What I need is to call mvn install of both pom files by one command. The Order is really important for me as create-jar must run before create-war.
There are two approaches.
First inheritance, By using create-jar.xml as a direct parent of create-war.xml, therefore by running create-war, create-jar is called.
The other solution is composition by running create-jar.xml from create-war.xml. I'm not sure how can I do that. But I think maven-invoker or maven-antRun plugins can be helpful.
I'd be happy to give me a hand.
Check this sample project.
Basically you will need a parent pom which will call your 2 child poms.
The above example is a bit long but they will explain each and every step in layman's term.

Java Classes Not Found In WAR Module of a Multi Module Maven Application

I had a multi module application called ParentApp(Which is a parent project) and it has JARMOdule, WARModule, EARModule. EAR Module has dependedncies of JARModule and WARMOdule
ParentPOM
<?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>ParentApp</groupId>
<artifactId>ParentApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>JARModule</module>
<module>WARModule</module>
<module>EARModule</module>
</modules>
</project>
EARModule 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>
<parent>
<groupId>ParentApp</groupId>
<artifactId>ParentApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>EARModule</artifactId>
<packaging>ear</packaging>
<dependencies>
<dependency>
<groupId>ParentAPP</groupId>
<artifactId>WARModule</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>ParentAPP</groupId>
<artifactId>JARModule</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
And respective JAR and WAR Poms which doesn't have any dependecies, WARModule is a WebApp, I had a class in WARModule when i build the ParentApp with mvn clean install
under target folder under classes i still have
I'm basically trying to have a rest service in WARModule but unable to make it work, any help is appreciated. Thanks!!
You need to follow the Maven standard folder structure.
You should put all your java code inside src/main/java folder.
Looking at the image you uploaded, it looks like the SampleApp.java is not present in the correct directory as expected by maven.

Maven module - How to use it as an external lib in an unrelated project

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.

Categories

Resources