Maven package module behaviour [duplicate] - java

Scenario:
I have a main level project A and within A , two child projects B and C worked on by different developers , but they agree on the abstraction through common interfaces.
B depends on C (dependency).
In B's pom I added
<dependency> .. details of project C..</dependency> .
Doing this, maven inserts the dependencies fine except that project C is not recompiled.
I want project C to automatically re-compile every time I compile B.

If you want to build B and automatically build it's dependencies you can use the advanced options of the maven reactor like –-also-make-dependents .
mvn clean install –-projects B –-also-make
Or short
mvn clean install -pl B -am
That will compile all submodules of A whose B depends on .
There are a useful post on sonatype blog on the advanced options of maven reactor.
http://www.sonatype.com/people/2009/10/maven-tips-and-tricks-advanced-reactor-options/

List projects B and C as modules in the pom of the project A. Now when you build project A, it should build project B and C automatically and in the correct order.
<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>multi</groupId>
<artifactId>A</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<modules>
<module>B</module>
<module>C</module>
</modules>
</project>

I often use Maven reactor plugin to deal with these type of problems. This plugin even covers tough requirements that a complex project with many sub modules in a complex structure may has.
See link for examples.
For above situations, using
mvn reactor:make -Dmake.folders=B
to build B and C (and all dependencies of B if any).
Hope this helpful.

Related

Unable to build JAR file for my maven PARENT prroject

I have created two training projects aiming to the creation of a Java Test Automation Framework with Selenium.
Both projects have been stored in my personal git: https://github.com/omarjmc
Framework: Contains main classes and all the code needed to execute successfuly the tests
Project: Demo project that will use the methods specified in the Framework project
Additionally i added the dependency to the Framework project in the demo Project's POM and I also created a release of the Framework project and attached the JAR file
enter image description here
Currently I have to clone both repositories and run mvn clean install on the framework to get the JAR file and change the packaging back to pom, but I want to just clone the demo project, run mvn clean install there and still get the Framework JAR file.
What am I missing the POM file?
Omar you have to create a maven multi module project for this requirement. Project will be the parent project and it should contain framework as child.
The basic code structure for pom.xml for Project should be like this.
<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>com.project</groupId>
<artifactId>multi</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>project</name>
<modules>
<module>framework</module>
</modules>
</project>
You can refer below the github project for this exact requirement.
https://github.com/jamesward/maven-multi-module-example
I created a multi-module proyect, but it only works if you download the original repository, what I want is to have them in separate repositories and just download, and use, the project child

Maven project inheritance: Cannot resolve imports from parent project

I set up two (maven) projects, the first contains simple Java-Classes. The first project should act as a master/parent project over (yet only one) many project.
I need that the second project, should be able to use some classes from the parent project.
What I have tried yet.
1.) I have installed the first project with mvn install
2.) Declared the first-project as parent in the pom of the second-project. <parent>...</parent>
In the second project, try to import classes from first project, failes. I'm not able to use classes from the first-project.
Let me show some snippets of both pom:
1) First pom:
<groupId>com.sample</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
2.) Second pom.xml:
<parent>
<groupId>com.sample</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
</parent>
Is it possible, to use components from parent pom/project??
Your question was already answered there : Maven include parent classes
You need to understand the concepts behind a multi modules project and how the maven dependencies management works.
A lot of documentation is available, for example : https://www.baeldung.com/maven-multi-module
Technically you can do this by changing the packaging of the parent pom from pom to jar, but there cannot be a good reason to do what you want. The parent module is not there to be a provider of classes for the children modules.
Just move your classes from the parent module into another module, and add a dependency to this module into your second pom.xml.

How Maven looks for dependencies

I have read many documentation and tutorial about getting started with Maven. But few things are still not clear to me :
1) When pom.xml contains <dependency>, Maven will put that artifact/JAr in Maven local Repository. Right ?
2) Suppose, I have sub modules in my MAven project. Then what is the correct way to build the project ? one should start from parent module and then go to further sub modules. right ? and that way maven will create dependency jars and put them in local Maven Repo folder ?
3) For example, if my sub module pom.xml contains following dependency. How should I provide it (vd-ps.jar) to Maven so that Maven finds it when I do Maven clean install on Submodule/pom.xml? I mean to say what does Maven require or from where does it generate such user defined vd-ps.jar ? from compiled class files ?
<dependencies>
<dependency>
<groupId>com.b.t</groupId>
<artifactId>vd-ps</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
Ok, let me ask directly what I want to achieve: I have following pom.xml. and from it I would like to create a separate maven project (Say PTest) that uses dependencies (jars) of another big multi module maven project. Here :- I have a module named v-parent in my multi module project which has pom.xml in its trunk folder.
<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>com.b.t</groupId>
<artifactId>v-parent</artifactId>
<version>3.9.0</version>
</parent>
<groupId>com.b.t.test</groupId>
<artifactId>p_test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ptesting</name>
<dependencies>
<dependency>
<groupId>com.b.t</groupId>
<artifactId>v-ps</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
</project>
1) Now where should I put this sub module v-parent in my newly created Maven project (PTest) in eclipse ?
I mean how do I exactly make my PTest/pom.xml find this parent jar v-parent.jar ?
I have separate jar file named v-ps.jar. where should I put it exactly (in which structure) in Maven local repo so that it can find it ?
Each time you run
mvn clean install
Your project will be built and the resulting artifact will be 'installed' in your local repository (usually ~/.m2/repository). So if you build the project which makes the jar com.b.t:vd-ps:1.1.0 this will then be available in your local repository for other projects to use as a dependency.
If you dependency is in another module under the same parent it can in included like so :
<dependency>
<groupId>com.b.t</groupId>
<artifactId>vd-ps</artifactId>
<version>${project.version)</version>
</dependency>
If you run a
mvn clean deploy
Your artifact will be built and deployed to the remote repository (Nexus or Artifactory or similar), provided you have the correct config in your pom.xml
See https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
1) Now where should I put this sub module v-parent in my newly created Maven project (PTest) in eclipse ?
I mean how do I exactly make my PTest/pom.xml find this parent jar v-parent.jar ?
So in this case "v-parent" will be another project in Eclipse of packaging type "pom". And if you want to build the child project "p_test" and its dependency "v-ps", you could list them as modules in the "v-parent" project's pom file like below:
<project>
<groupId>com.b.t</groupId>
<artifactId>v-parent</artifactId>
<version>3.9.0</version>
<packaging>pom</packaging>
<modules>
<module>p_test</module> <!-- Make sure you provide the right path here -->
<module>v-ps</module> <!-- Make sure you provide the right path here -->
</modules>
</project>
Now when you run "mvn clean install" on "v-parent" it should build "p_test" and "v-ps" projects and places a copy of their jar files in your local .m2/repository, assuming those projects don't error our during the build. So the parent project acts like an aggregate for the sub-projects and helps building them all at one shot.
I have separate jar file named v-ps.jar. where should I put it exactly (in which structure) in Maven local repo so that it can find it ?
If you have the source for this project, then you should include it as part of the "v-parent" project's pom as a module like I mentioned above, and when you build the parent, on success, the jar gets written to your local .m2 repo. Or if you have the source for "v-ps" project, you could directly build that using "mvn clean install" and the jar will be written to the repo.

Maven Project Structure with Multiple Modules

I am somewhat new to the Maven project structure. I am creating a project this is going have two jars. Neither jar is dependent on each other, however, they will use some of the same libraries and there are two helper classes I created (one for logging) that would be used in both.
I was following this guide as far as project structure goes: http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
My current project only has one module. I am using the IntelliJ IDE to create my build.xml (using ANT) to create my Jars. The IntelliJ build.xml, however, did not work off the bat and I had to do some manual editing to have it build both jars. I believe this would be solved if each jar was in it's own module. Also, according to the following, it seems they should be anyway http://www.jetbrains.com/idea/webhelp/module.html
This is where I am a little confused. If I do create a second module for my second jar, how do I deal with classes that are shared by both modules? Whenever I go to create a new module , IntelliJ gives the new module it's own src/ path.
As I said, I am new to the Maven project structure. I am also fairly new to ant and building jars using a build.xml. If I am completely on the wrong path please let me know so I can fix this problem early.
Thanks ahead of time.
Create a multi-module project (x) which contains a pom.xml with packaging = 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>test</groupId>
<artifactId>x</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>x1</module>
<module>x2</module>
</modules>
</project>
and 2 regular (jar) projects (x1 and x2). This is how the project structure should look like
x
x1
...
pom.xml
x2
...
pom.xml
pom.xml
The main project pom should contain dependencies common to both modules. Nested projects poms should have a reference to the 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>
<parent>
<groupId>test</groupId>
<artifactId>x</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>x1</artifactId>
</project>
See more here http://maven.apache.org/guides/mini/guide-multiple-modules.html
If you are going to do things the maven way you should remember that each (maven-)project only builds one artifact. So if you want to build two jars you will need two maven-projects (p1,p2) each with their own pom.xml.
If you got some classes that are used by both of these projects they will have to go to their own maven-project as well to build their own module-jar (p3).
p3 will then be included in p1 and p2 as a dependency.
To build these jarrs in one go you could resort to the module-layout suggested by Evgeniy Dorofeev

Build order of Maven multimodule project?

The situation is, I have two Maven multimodule projects with the same structure:
Parent
- Module 1
- Module 2
When I build project 1, I see that parent is built first (order is parent->module1->module2). However for project 2, parent is built at last (order is module1->module2->parent). Why are the two projects have different build orders? Furthermore, how can I manually control the build order?
Update 1:
Both parent projects are simple POM projects without source code, so I can't explain the build order as per the dependency graph.
Update 2:
The parent POMs are the same except the GAV and child module names:
<?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>parent-group-id</groupId>
<artifactId>parent-artifact-id</artifactId>
<version>parent-version</version>
<packaging>pom</packaging>
<name>parent-name</name>
<modules>
<module>module-1</module>
<module>module-2</module>
</modules>
</project>
The build order is determined by the Maven reactor which is a mechanism that automatically ensures correct build order for multimodule builds by sorting the projects.
See the official documentation for how it works.
It says:
The following relationships are honoured when sorting projects:
a project dependency on another module in the build
a plugin declaration where the plugin is another modules in the build
a plugin dependency on another module in the build
a build extension declaration on another module in the build
the order declared in the element (if no other rule applies)
You can't manually control the build order. If you want to change the order you have to make changes to your project that influence the reactor sort order.
At a high level, the build order is based on a topological sort of the module dependency graph.
EDIT: Question for you. I understand that project 1 contains two modules and so does project 2. But do the modules in project 2 explicitly declare the "parent" pom as a parent? I'm thinking that perhaps your project 1 modules explicitly declare the parent pom, and the project 2 modules don't. Which would mean that the project 2 "parent" isn't really a parent at all and therefore doesn't have to be built before the modules. That's my guess anyway.
I've been having this issue lately with CentOS 7. I updated Maven to 3.5.3 from 3.0.5 and the problem has been solved. If anyone have this issue as well you can try doing that first.
Summary
Why?
Maven is using <module> declarations to determine the list of modules to include in the current run. Maven is using <parent> declaration to generate effective POM for each included module, which is then used to execute the build for that module.
In Project 1, each of module1 and module2 specify parent module in <parent> section.
In Project 2, neither module1 nor module2 specify parent module in <parent> section.
How can I manually control the build order?
By changing dependencies between modules, including <parent>, <dependencies>, plugin dependencies, etc. as described in the official documentation.
Please check also Introduction to the POM for the discussion on aggregation and inheritance.
Details
There are 4 possible scenarios of module relationships in Maven in terms of aggregation (<module> declaration) and inheritance (<parent> declaration).
Let's assume a module A with packaging pom and a module B (packaging does not matter). The module A could either be a parent or an aggregator. The module B could either reference A as parent or not.
Case 1:
Neither A nor B reference each other - the modules are independent.
The Maven can not control build order, each module gets built independently, with manual build order control.
Case 2:
The module A includes the module B in <modules>. The module B does not declare A as parent. The module A is an aggregator for the module B in this case.
Maven invocation mvn -f A/pom.xml will first build B, and then A.
Maven invocation mvn -f B/pom.xml will build B only.
Case 3:
The module A includes the module B in <modules>. The module B declares A as parent. The module A is both the parent and the aggregator (reactor) for the module B in this case.
Maven invocation mvn -f A/pom.xml will first build A, and then B.
Maven invocation mvn -f B/pom.xml will build B only, but will use the POM of A to generate effective POM of B by resolving it either from the local repository or by following /project/parent/relativePath.
Case 4:
The module A does not include the module B in <modules>. The module B declares A as parent. The module A is the parent for the module B in this case.
Maven invocation mvn -f A/pom.xml will build A only.
Maven invocation mvn -f B/pom.xml will build B only, but will use the POM of A to generate effective POM of B by resolving it either from the local repository or by following /project/parent/relativePath.

Categories

Resources