I'm just curious, what happens if there are used both inheritance and aggregation in the same maven application?
This is the application structure:
my-project-app
my-project-jar
my-project-war
Now, in app's pom.xml, I declare jar and war projects as modules, and in the same time the the poms from both modules declare the app pom as their parent. It is create some kind of redundancy here, isn't it?
What is the best solution for this case?
It's not redundant. They both do different things.
If you use aggregation (define <modules>), you just say which projects have to be built, and its package type is pom.
If you inherit (define <parent>), you'll inherit the parent pom's preferences.
See:
Inheritance and aggregation create a nice dynamic to control builds through a single, high-level POM. You will often see projects that are both parents and aggregators. For example, the entire maven core runs through a single base POM org.apache.maven:maven, so building the Maven project can be executed by a single command: mvn compile. However, although both POM projects, an aggregator project and a parent project are not one in the same and should not be confused. A POM project may be inherited from - but does not necessarily have - any modules that it aggregates. Conversely, a POM project may aggregate projects that do not inherit from it.
More infos here.
Related
I am wondering if there is a way to run a Maven subproject alone. I mean, in several code samples you can find a group of maven projects with a common parent. There is a way to replace parent in order to be able to run just a subproject.
Lets suppose this repository https://github.com/in28minutes/spring-boot-examples
There is way to run just spring-boot-tutorial-soap-web-services/ project?
Thanks in advance.
maven projects are identified by pom.xml and you can run any maven project individually. (Any maven goal).
cd into_a_maven_project(identified by pom.xml).
mvn install(this will run install phase for the project).
There are several relationships among maven projects.
Parent-child
Submodule
Dependency
Parent-child: This relationship is used in defining a pom. For instance, When a set of pom shares a lot, you can define a parent pom(parent maven project) and reference from the child project. (reference is done from child to parent)
When you run child project, the parent project is used only to inherit the pom(copy the content of parent pom). Child pom overrides the configuration in parent pom.(child pom contains little because of the fact that required configurations copied from the parent pom)
Submodule: This relationship is used when it makes sense to build multiple projects together. In this case, you run build in the project referencing submodules. (This is not a parent child relationships, the pom is not inherited if the project is not also a parent). The result is that the submodule projects become part of the build. (The order of the build is determined by dependencies between them)
Dependency: This relationship is used when the code in a project depended by your project. The build order is calculated using this relationship.
I have Maven project with multiple submodules. One of these submodules, let's say submodule X depends on all other submodules, as it is Maven Plugin that integrates everything else.
Now I want to use this Maven Plugin during verify stage in my parent POM to do real run of it over entire project (kind of eating own dogfood).
Unfortunatelly I'm getting error:
The projects in the reactor contain a cyclic reference
So how can I make such dogfood integration test for a Maven Plugin submodule?
I would review aggregation and inheritance: they are indeed two different concepts in Maven often used in combination but which can however be used in a complete separated manner as well.
In this case, your plugin submodule is certainly defined as a module in the aggregator pom (that is, it is a submodule). But I also presume the plugin submodule also has as parent pom the aggregator pom as well (that is, the aggregator pom is also the parent pom, which is a normal approach, but not always required).
Is the latter required? You could keep on having the multi-module/aggregator approach without necessarely having the aggregator as parent of the plugin submodule. As such, the plugin subModule would still be a module of the aggregator pom but it would not have as a parent the aggregator pom, decoupling it from it and as such breaking the cyclic dependencies.
Possible drawback: in the aggregator pom you were also defining common things (dependencies management, properties) required also in the plugin submodule. If the case, you would then need to duplicate/review these common settings only for the concerned submodule.
Small suggestion from my side. Cyclic means you have some transitive dependency in your modules. Can please check the dependency tree of your modules and resolve the circular dependency first.
In my project, we are given a sample project structure to be followed and I am very new to multi-module projects.
We have a parent project and 4 sub-projects that have that as parent.
And in the parent project, only 3 out of those 4 are configured as modules.
What's the difference/significance in having a project as a child but not as a module to the parent project?
Other than dependency management, what do we achieve by using multi-module project hierarchy?
1) The "parent-child" relationship helps to manage dependencies. Say in your company(or project), you have some common libs that nearly all projects(or sub-projects) need to depend on, or you have a standard build configuration. You'd better put these common dependencies and build config in your parent pom, so that all children can inherit from parent. This is quite like inheritance in OOP.
2)If a project can be divided into many modules, and these modules highly couple with each other. Which means in most cases they are modified and build together, and none of them can be taken apart as a library for other projects. Then you can declare them as modules of a multi-module maven project.
But personally, I don't quite recommend multi-module maven project since it not flexible and more complex to build and to work with IDE,CI or other tools.
I have encountered the below "pattern" for maven parent-child relationships:
http://yuml.me/3f8dd366
In this example we have a module with 2 sub modules. The module has a parent pom "Parent for building the Module" which knows the two sub-modules as it's children.
The sub-modules how ever have no idea that this parent knows them, and they think their parent is the one named "Parent for dependency management". Which has common configurations like dependency management, plugin configuration, common properties etc.
My question:
Is this a "good" pattern? Meaning does it have advantages/disadvantages as the seemingly more intuitive patter of child<->parent relationship
One interesting thing to look at is the aggregator pom.
It's a pom that groups project by module, without having a "parent-child" relationship. The aggregator pom doesn't have dependencies management. It only manages the build.
Having both parent(s) pom and aggregator pom is quite a powerful feature of maven.
You can find more information here.
This maven page also has valuable insight on how to set up pom for complex projects.
Hum... I think I disagree with the terms on your picture. Here is how I see this:
This way of organizing modules can be confusing for lot of developpers, but it is a legal way of doing things.
Anyway, I don't recommend this approach because it's confusing. But sometimes, their is no alternatives.
When using this configuration ?
One (or more) of the sub module already have a parent (i.e. was developed in another project but you need to rebuild it). Note that the <module> entry in multi-module project is a relative path so you can have something like:
<modules>
<module>../../somedir/othermodule</module>
...
</modules>
When possible, I recommend to use the multi-module also as the parent because:
less confusing
clean and readable <modules> and <parent> sections (no need to use ugly relative paths to specify the parent or the submodules)
you can organize your modules in a clean hierarchical structure under SCM (so that maven-release-plugin will be happy) (I know that eclipse don't like hierarchical projects, but that's another problem)
This is actually good to have a company wide configuration pom which doesn't care about it's children and contains stuff like properties, dependecyManagement, repositories, pluginManagement etc. which all of them will inherit
Maybe this can help you: Company wide parent pom
In a nutshell, what I am trying to do is build a bunch of libraries and applications, all Maven projects, all at once. From what I understand a way to accomplish this just in one command line run of mvn package would be to create a multimodule project that will list each module that I would like to build, throw them in the Maven reactor, and build.
Following examples in the Maven book it seems that normally a multimodule pom sits in a directory above the individual modules. However it is also normally the case that a parent pom sits in a directory above the modules, which raises the question, is it normally the case that a multimodule build should also be a parent? I think not; however I wonder why I am running into this funny design quirk.
So, I'm wondering the right way to set this up. I see the following conventions / requirements:
The multimodule pom must have knowledge of where the other modules live on disc. Since it is actually doing the build from source it can't simply rely on already installed versions (since it's installing them!)
The parent doesn't actually have to be a physical directory up although that would be preferable. I see this as the convention best to break.
Really the individual libraries/application shouldn't even need to know they are being built as part of a multimodule build.
How is this usually set up in a multimodule build? Is there a simpler way to manage building multiple Maven projects all at once?
I put all the individual modules within the root module. Some software has trouble with multiple layers of hierarchy.
To make a child module refer to it's parent on the same level:
<parent>
<groupId>com.domain</groupId>
<artifactId>xyz</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../xyz/pom.xml</relativePath>
</parent>
I suggest you do not put anything in the multimodule (e.g. properties) that individual modules need to inherit. If you do, you won't be able to build the other modules independently.
I would go so far as to say that this is the fuzzy part of the "conventions". The documentation, and common sense, both suggest that project aggregation ( aka multi-module builds ) and inheritance are two different mechanisms provided to handle different use cases.
At the same time, it seems that there is a de facto convention ( yeah, I know ) of combining both the project aggregation and inheritance parent roles into a single pom. In fact, both the element of the parent declaration and the module element of the project aggegration mechanism seem to steer the use toward this combination.
Personally, I find it very usefull to separate the parent pom out on a regular basis. And I also find it useful ot locate parent pom in a totally separation location in my source control, and thus my folder structure. However, it rarely seems useful to locate builds that are a part of the same multi-module build structure in source control / folder structure. Perhaps this is even a good measure of whether something should be included in the same aggregate build; if it seems to deserve collocation in the source folder structure, then perhaps its a strong candidate for aggregation.
The only thin I am sure of is that these things are worth sorting out a head of time. And it's probably better to error on the side of not creating monolithic build structures . . . it's very hard to deal with a huge lump of aggregated, parent child build modules that isn't really necessary. On the other hand, aggregating individual builds to run together is a functionality provide at higher levels, such as the CI build server. So, I guess I might suggest erroring on the side of more independence.