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.
Related
My multi module project structure is:
Parent project - MyProj
|
|- ChildProj1
|
|- ChildProj2
Another project TestProj depends on child1 and child2.
So, what should be the POM dependencies in TestProj POM file for Jenkins to detect and include the child1 and child2 SVN projects while building and executing the test cases using Jenkins? I have created two projects in Jenkins. TestProj's build is triggered on build completion of MyProj. But, it doesn't seem to work. What should be the dependencies in TestProj POM? I have given the following dependencies:
<dependencies>
<dependency>
<groupId>proj1</groupId>
<artifactId>child1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>test</scope>
<systemPath>https://subversion.assembla.com/svn/child1/pom.xml</systemPath>
</dependency>
<dependency>
<groupId>proj1</groupId>
<artifactId>child2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>test</scope>
<systemPath>https://subversion.assembla.com/svn/child2/pom.xml</systemPath>
</dependency>
Dependencies can only be made on jar files which are located locally. if you need systemPath you can use this but it should be prevented...If you need them as it looks like you should create multi module build.
+ (root) pom.xml (modules)
!
+-- child1 (pom.xml)
!
+-- child1 (pom.xml)
which is checked in one into SVN where root is in the trunk of svn repository...
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 ?
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.
I have the following maven-setup:
parent-project
|- libraries
|- utilities
|- core
|- component1
|- component2
in the parent i define all dependency- and pluginmanagement and the infos about the dev-team. utilities containing functional artifacts like the website skin and checkstyle-config, libraries are bundle-artifacts for simplifying the dependencies. The site is build on the core-module and its sub modules. The parent-part of the core pom.
<parent>
<artifactId>parent</artifactId>
<groupId>my.group</groupId>
<version>3.0.0</version>
</parent>
<artifactId>core</artifactId>
<version>3.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
When staging or deploying the site, the page is located in a "core"-subdir (e.g. /target/staging/core/index.html). Is there a way to locate the site of core in the root?
Atm i use a "dirty hack". On the webserver i created a syslink with ln -s ./ core so he don't knows its the same dir.
Solution was, that maven generates that subdirectory only, when the url for deploying is inherited from the parent. All I need to do was move the distributionManagement section for site deploy and the url element from parent to core.
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