Question 1)
The best way to manage application lifecycle and releases is to use the release plugin.
As you may know, Maven philosophy is convention over configuration. Maven convention is to use snapshot versions (those ending with -SNAPSHOT) during development and assigning a non snapshot version only for releases.
Say you're developing version 1.1.1. While under development, you just use 1.1.1-SNAPSHOT. Maven will take care of updates of the snapshot. If using an artifact repository, you can use -U to make sure you always have the last version of the snapshots.
When the release is ready, release plugin generates and deploys version 1.1.1 and updates POM's with the new development version, such as 1.1.2-SNAPSHOT.
About multimodule projects, there are two scenarios: modules are related but independent (such as several web applications) or they are modules of a single big application or library and they share versions. You seem interested in the latter.
The best way in this case is just to inherit the same parent (maybe also root) module, including its version. You reference parent group:artifact:version and you do not specify a version for the children. Generally you also inherit group, so your child pom can look like:
<parent>
<groupId>com.mycompany.myproject</groupId>
<artifactId>myproject-parent</artifactId>
<version>1.1.1-SNAPSHOT</version>
<relativePath>../myproject-parent</relativePath>
</parent>
<artifactId>myproject-module1</artifactId>
Now you just need to take care of children pointing to the right version of the parent with the help of the release plugin.
To help it know about children, you should make your parent pom also a root pom by including the modules section as shown later.
Question 2)
I usually declare properties in the parent with all versions of all artifacts which may be referenced. If several modules share version, you just need one property. The parent can look like:
<groupId>com.mycompany.myproject</groupId>
<artifactId>myproject-parent</artifactId>
<version>1.1.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<myproject.version>1.1.1-SNAPSHOT</myproject.version>
</properties>
.......
<modules>
<module>../myproject-module1</module>
...
</modules>
Children can reference other modules using
<version>${myproject.version}</version>
It is a very bad practise to declare dependencies using LATEST. Say you do this for version 1.1.1. Now you're working with version 1.1.2-SNAPSHOT and probably you have artifacts with this version installed in your local repo.
Now say for some reason you need to rebuild version 1.1.1, for instance because of a bug in production. Your build will use the new version. If you're lucky, this will break the build. If you're unlucky it may even go unnoticed to production.
Last but not least, some people like using property values to declare children versions. This is strongly discouraged and will be reported as a warning by maven. I personally don't ever do it. The reasons are also related to reproducibility of builds and the fact that maven assumes that a release build will never change. Having a module version be externally tweakable is not really a good idea.
EDIT:
Case when module versions are not aligned.
Actually both scenarios can be mixed.
You can have, for instance:
Parent
---Component1
---Component2
---Component3
------Comp3Module1
------Como3Module2
------Comp3Module3
Where parent and the three component versions are different and the three modules of component3 share its same version as explained before.
Question 1)
In this case each module has its version independently specified.
As said before, it's a bad practise to use a property to specify module version, reason why I can only recommend to literally specify versions.
As already said, to manage versioning, the best way is to use release plugin, and integrate it with the version control system, such as SVN.
Other answers give details on how to use it, so I won't elaborate it further, unless requested.
Question 2)
The recommended approach is the same explained for the case of sharing the same version, only that you need several properties.
The parent can look like:
<properties>
<myproject.group>com.mycompany.myproject</myproject.group>
<component1.version>1.1.1-RC1</component1.version>
<component2.version>1.1.1-RC2</component2.version>
<component3.version>2.0.0</component3.version>
<properties>
Then you can use dependency management to centralise version management in the parent.
For instance, in parent pom,
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>component1</artifactId>
<version>${component1.version}</version>
</dependency>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>component2</artifactId>
<version>${component2.version}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>comp3module1</artifactId>
<version>${component3.version}</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>comp3module1</artifactId>
<version>${component3.version}</version>
<type>ejb-client</type>
</dependency>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>comp3module2</artifactId>
<version>${component3.version}</version>
<type>war</version>
</dependency>
</dependencies>
</dependencyManagement>
Now, to reference any module from any other module, it's as easy as:
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>component1</artifactId>
</dependency>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>comp3module1</artifactId>
<type>ejb-client</type>
</dependency>
Versions are automatically managed from the parent. You don't need to maintain them in children dependencies, which become also less verbose.
${mod1.version}
variable set in the parent pom, then called in the child poms<version>${mod1.version}</version>
and for dependencies, although from Maven 3's warnings, I am sure there are many good reasons not to do this. – Checkerberrymod1.version
toproject.version
, in the parent's POM, and that lead to a recursive error. When I setmod1.version
to a constant then it works. Now I just need a way to set all themodX.version
's and the parent's version to the same value at the beginning of a release cycle. – Wertheimerpom.xml
before release. But I'm confused as to why you would want to up version sub-components for a major release when they hadn't actually changed? – Checkerberry