I appologize for the length of this post, but I had trouble making it more concise without presenting the picture. I've recently inherited the job of build-master for a maven 3.0 multi-module project. The problem is that the structure of the project/modules is a disaster. From the way things are currently stored in Source Control (we use RTC) to the pom structure of the modules, I'm tearing my hair out trying to get a full build cycle completed each time.
As a project hierarchy goes, all the modules are stored "flat"; ie: everything is at the same level. I have a parent pom, and all modules depend on the parent. However, the parent is at the same level as all my other modules.
Ex:
c:\dev\MyEarProject
+ parent-pom
- pom.xml
+ module1
- pom.xml (depends on parent-pom)
- src
- main
- ...
+ module2
- pom.xml (depends on parent-pom)
- src
- main
- ...
+ module3
- pom.xml (depends on parent-pom)
- src
- main
- ...
The parent pom defines all the modules required to build the project, as well as a bunch of properties for artifact version numbers used throughout the different submodules:
<modules>
<module>../module1</module>
<module>../module2</module>
<module>../module3</module>
</modules>
<properties>
<org.springframework.version>3.0.5.RELEASE</org.springframework.version>
<slf4j.version>1.6.4</slf4j.version>
<repositoryAddress>${snapshots.repo.url}</repositoryAddress>
<my.hibernate-module.dao.impl>1.2.3</my.hibernate-module.dao.impl>
<my.hibernate-module.dao.api>1.2.3</my.hibernate-module.dao.api>
</properties>
Each module's pom, in turn, depends on the parent pom via the pom's artifact number:
<parent>
<groupId>com.cws.cs.lendingsimulationservice</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.6</version>
</parent>
To make things even more confusing, the actual artifact name may, or may not (depending on the module), match the module path. For example, module1 may be located in path c:\dev\MyEarProject\module1
but have artifact name hibernate-module
. However, due to the way it is stored in RTC, the directory is called module1
when it is checked-out.
The easiest way to build everything, of course, is to go into c:\dev\MyEarProject\parent-pom\
and run mvn clean deploy
. This works fine when in SNAPSHOT mode as the SNAPSHOT repo allows for multiple deployments of the same artifact version. But in release mode, this fails.
This structure is causing 2 problems for me.
- Everytime I need to make a version change to a property in the parent, I have to update the parent-pom version number, and all the child modules parent pom's version, and all the child modules version themselves (since the parent changed).
- Whenever I need to deploy a release cycle, mvn will throw an error if one of the modules has not changed since the last cycle and consequently cannot be redeployed to the same repo (the repo does not allow overwriting existing artifacts)
So I'm looking for the best way to restructure this project to avoid these problems. For the parent pom, I know I can use a relative path to point to the parent instead. However, given the "flat" structure of the modules, is this a recommended approach (ie: the parent pom relative path would be ../parent-pom/pom.xml - seems a little odd to me)? Additionally, given that the versioning control of the parent is independent of the modules, would using a relative path not just open the door to additional confusion (ie: there would be no way to know which version of the parent pom is associated with which version of the submodule).
Secondly, how can I build the entire ear without encountering the deploy errors I am having? Since the artifact already exists in the repo, I don't need to rebuild and redeploy it. I tried using --projects but with the number of modules involved, it gets extremely difficult to manage.