Maven pom dependencies between app and common - maven

Every applications has its own pom.xml and root has its own pom.xml. common is in every web app and it has its own pom.xml. I want to get different values from common pom.xml based on webapp loads. For instance common should give value1 for web-ap1 and same common should give value2 for web-app2. How should i get different value from common pom ?
my-project
+ pom.xml
+-- common
+ pom.xml
+-- web-app-1
+ pom.xml
+-- web-app-2
+ pom.xml ?

Related

Parent POM Having a Dependency on its own Modules

SO I have a Parent POM with three modules defined as so:
<modules>
<module>m1</module>
<module>m2</module>
<module>m3</module>
</modules>
The parent also has two dependencies defined on its own modules:
<dependency>
<artifiactId>m1</artifactId>
</dependency>
<dependency>
<artifiactId>m2</artifactId>
</dependency>
When I try to build the project the build for the first module fails because it cannot find itself in the repository.
I have already figured out the when building m1 its trying to resolve the parent dependency on m1 in order to build m1. Obviously if you depend on yourself and you don't exist how can you build.
My question is should the Parent POM besides stating the modules have a dependency on them as well? Wondering what the correct practice is here?
NOTE: Parent has no code to itself:
parentProj
m1
java
resources
m1Pom
m2
java
resources
m1Pom
m3
java
resources
m1Pom
parentPom
I think you've confused things a bit.
You need three things:
An aggregator
A parent POM
Modules
Your structure should look like this:
your-project/
|- module1/
| |- src/main/java/
| |- src/main/resources/
| |- src/test/java/
| |- src/test/resources/
| |- pom.xml
|- module2/
| |- src/main/java/
| |- src/main/resources/
| |- src/test/java/
| |- src/test/resources/
| |- pom.xml
|- module3/
| |- src/main/java/
| |- src/main/resources/
| |- src/test/java/
| |- src/test/resources/
| |- pom.xml
|- your-parent/ [This is your parent]
| |- pom.xml
|- pom.xml [This is your aggregator]
Further clarifications:
In your-project/pom.xml you should only define your <modules/> section and not have any other extendable things like <build/>, or <dependencies/>, or <dependencyManagement/> sections.
You should have the sections mentioned above in the your-project/your-parent/pom.xml file.
Your modules should use your-project/your-parent/pom.xml as their parent.
I'm not sure why you need the parent to depend on modules in the aggregator. I think you most-probably don't want to do this. Define these dependencies explicitly where needed, instead of doing it by default when extending the parent.
Based on my years of experience as a build and release engineer, I would strongly recommend that you not mix the aggregator and the parent. These are logically separate concepts and although they can be the same thing, they actually are not. This way things are much more decoupled and easier to manage. When you change things in the parent, you really only want to be changing the parent, not the whole aggregator. If the two are not separate, this is much more complicated and tends to make things slower for you, if you get what I mean.

Maven multi module project setup with various, different dependencies

Let me just say this first: I am brand new to Maven. That said I searched around but have not found answers to the following question. I found answers to similar questions, just not this scenario. Or maybe I just misunderstood the answers and this can be solved simply wiht a multi module setup.
I'd have the following dependency hierarchy:
database
| |
| +---core
| | |
| | +---business
| | |
| | +------App1
| | |
| | +------App2
| |
| +---------------App3
|
+----------------------App4
I'd like to make it work so that changes only result in new releases of any "upstream" modules/Apps. Is this indeed a simple case of multi-module maven setup or do I need to do something else?
If you want that releasing one component produce a new release of each project, just use maven-release-plugin: http://maven.apache.org/maven-release/maven-release-plugin/.
Documentation
As per doc, this would :
Check that there are no uncommitted changes in the sources
Check that there are no SNAPSHOT dependencies
Change the version in the POMs from x-SNAPSHOT to a new version (you will be prompted for the versions to use)
Transform the SCM information in the POM to include the final destination of the tag
Run the project tests against the modified POMs to confirm everything is in working order
Commit the modified POMs
Tag the code in the SCM with a version name (this will be prompted for)
Bump the version in the POMs to a new value y-SNAPSHOT (these values will also be prompted for)
Commit the modified POMs
Because of the maven multi module structure, they are linked together, and each project would be bumped into a new release.
In a few words, this will :
move version 1.0-SNAPSHOT --> 1.1-SNAPSHOT
tag 1.0
generate 1.0.jar (ou war or anything else)
Plugin usage
Assuming that SCM is correctly defined, and repository and distribution management configured, just add these lines
<project>
[...]
<build>
[...]
<plugins>
[...]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.4.2</version>
<!-- optional, basic format is ${project.artifactId}-${project.version}.${project.type}-->
<configuration>
<tagNameFormat>v#{project.version}</tagNameFormat>
</configuration>
</plugin>
[...]
</plugins>
[...]
</build>
[...]
</project>
And call
mvn release:prepare
mvn release:perform
Inheritance vs Dependency
You may consider the two differents Maven approches :
inheritance, that means parent and multi/sub modules
aggregation, in other words : use of dependencies
In a multi-maven project, all your modules, including parent, share the same lifecycle. Releasing one imply releasing all, and so, releasing just one is a non sense.
In your case, you can't modify app 1 to 3 whithout impacting app 4.
If App 4 depends App 1, obviously App 1 can't depends on App 4 (circular references are not allowed).
So, you want to isolate App4 and App1 to 3 lifecycles, you should not use multi-modules, but just share a parent project, or a hierachy of pom like corporate > main project > sub project (not submodule).
After that, just declare a dependency between App 4 and App 1. (... into app4 pom.xml)
Just another thought : the name of your projects and submodules sounds strange. "Classical" hierarchy is often (considering multi business object domain for a large project):
Main Project (sometimes EAR) --> POM
|-- Business Object / DAO --> POM
| |-- Domain 1 --> JAR
| `-- Domain 2 --> JAR
|-- Core (depends on BO) --> JAR
`-- IHM / Web App (depends on core) --> WAR
So, database is rarely at the top of hierarchy.

Large quantity of profiles in pom.xml

I have the maven project with five separate modules each of them have pom.xml with duplicated profiles. Is there any options to move all profiles from pom to separate file?
You can put the profiles into the parent pom. They get inherited during the build:
parent pom (with all common profiles)
- module1
- module2
- module3
- module4
- module5
You need to reference the modules correctly
from parent pom using the <modules> tag
from each module reference the parent using the <parent> tag

Build Multiple EARs choosing subset of jars

Our current working Maven structure builds one EAR and is as below
workspace
>parent proj (containing root pom.xml)
>ear proj
>web proj
>jar1
>jar2
>jarN
We now need to customize this such that we build multiple EARs (for different requirements) using a combination of jars.
So the suggested workspace will now look like this:
workspace
>parent proj (containing root pom.xml)
>ear projects
>ear1
>ear2
>web projects
>web1
>web2
>component jars
>jar1
>jar2
>jarN
and in ear1 project pom.xml we want to pick and choose the web projects and jar projects which we need.
The question is:
a) is this above structure possible - since the folders named "ear projects", "web projects", "component jars" do not actually have a POM and build nothing
b) is is possible for an ear1 pom.xml to be built using artefacts outside of the same folder?
Earlier project ear1 was parallel with the jar1 and jar2 and all were child modules of the root pom.xml. But in the proposed structure, ear1 is built using the modules not in parallel, but ../web projects/web1 ../component jars/jar1 and so on.
c) is there a better way to achieve this?
The offered workspace looks good. For clarity, I'll put it here (note, ear, web and components are all empty directories).
parent (contains root pom.xml)
|--- ear
|--- ear1 (contains ear1 pom.xml)
|--- ear2 (contains ear2 pom.xml)
|--- web
|--- web1 (contains web1 pom.xml)
|--- web2 (contains web2 pom.xml)
|--- components
|--- jar1 (contains jar1 pom.xml)
|--- jar2 (contains jar2 pom.xml)
|--- jarN (contains jarN pom.xml)
Since project dependencies are taken from repository (local or remote), there is no problem that modules aren't going to be located on the same level. You should declare them as usual dependencies. For example, in ear1 you can specify:
<dependencies>
<dependency>
<groupId>_your_groupId_</groupID>
<artifactId>_jar1_artifactId_</artifactId>
<version>_jar1_version_</version>
<dependency>
<dependency>
<groupId>_your_groupId_</groupID>
<artifactId>_web1_artifactId_</artifactId>
<version>_web1_version_</version>
<dependency>
</dependencies>
I'm not sure if I totally understand your needs, but I'll try to describe what I would do.
You can use profiles to specify which projects to build. For example, assume ear1 project depends on jar1, jar2, jar4 and web2 projects. In this case, in your root pom.xml file you can specify a profile like this:
<profiles>
<profile>
<id>ear1</id>
<modules>
<module>components/jar1</module>
<module>components/jar2</module>
<module>components/jar4</module>
<module>web/web2</module>
<module>ear/ear1</module>
</modules>
</profile>
</profiles>
If you run mvn package -P ear1, then Maven will build only those modules that are specified in <modules> section of the profile.

Where placed the scm tag?

I have a little probleme with the scm tag in my pom.xml file.
My project architecture is like this:
Parent
Submodule1
Submodule2
reactor
Parent is the project which hold all maven plugins configuration, librairies version ect. It's the parent of reactor project which is the parent of all submodules.
Reactor is a pom.xml which contains tags to compile all submodules.
I would like put the scm tag on the parent pom.xml because it's the higher pom.xml. But I get an error when I want to do a "mvn release:prepare".
So I put the scm tag in the reactor pom.xml and it works.
It's good for me, it works :) but I don't understand why I need to put the scm tag in the reactor pom.
Someone can explain me this behavior ?
Thanks.
Edit:
Here is the folder structure:
root
parent
pom.xml (parent)
submodule1
pom.xml
submodule2
pom.xml
pom.xml (reactor)
Here is the interesting part of pom reactor:
<parent>
<groupId>groupId</groupId>
<artifactId>parent</artifactId>
<relativePath>./parent/pom.xml</relativePath>
<version>1.0.2-SNAPSHOT</version>
</parent>
<modules>
<module>parent</module>
<module>submodule1</module>
<module>submodule2</module>
</modules>
Finally, here is the error for the release:prepare:
[INFO] Unable to tag SCM
Provider message:
The svn tag command failed.
Command output:
svn: Path 'http://10.211.55.4/svn/trunk/reactor' does not exist in revision 112
First requirement is that trunk, tags and branches folder in SVN exist which i assuem but
you have to define the scm part only in the reactor and not in the parent.
root
+-- pom.xml (reactor)
+-- parent
! +-- pom.xml (parent)
+-- submodule1
! +-- pom.xml
+-- submodule2
+-- pom.xml
Furthermore you should define the maven-release-plugin (reactor) as well with true.
The default handling of such situation is that Maven will do relative changing of the SVN paths. This will produces trouble like you have. So you have to put the information into the reactor pom NOT into the parent pom. Very important is to have only a single configuration.
Furthermore i would recommend to remove the parent and put the information into the reactor, cause you would get trouble during site generation phase.
root
+-- pom.xml (parent)
+-- submodule1
! +-- pom.xml
+-- submodule2
+-- pom.xml

Resources