I have a multi module maven project and I would like to use versions in such a way that the developer has to touch only the root project pom to change the version of all modules.
For example
ProjA contains
Module1
Module2
Module3
All the modules contain their own Poms and have ProjA's pom as their parent. Once I run the build I get a jar created for each module. Now For building a newer version of ProjA, I just have to change the version of the ProjA's pom and all the poms of the modules should pick up this new version from the parent. This works if I harcode the parent version in all the module's pom. But this will also force me to update the poms of all modules for every version change in the parent pom which defeats it purpose.
Is there a way to avoid this and still achieve the stated behaviour?
Use the Maven Versions Plugin and its versions:update-child-modules goal:
versions:update-child-modules updates the parent section of the child modules of a project so the version matches the version of the current project. For example, if you have an aggregator pom that is also the parent for the projects that it aggregates and the children and parent versions get out of sync, this mojo can help fix the versions of the child modules. (Note you may need to invoke Maven with the -N option in order to run this goal if your project is broken so badly that it cannot build because of the version mis-match).
Related
I have a library which I "mavenized" recently and put into a local git repository.
In order to lock some plugin versions I created a simple parent pom which defines the plugin versions via pluginManagement (the parent pom file is not checked into any SCM repository). I specify the parent pom in my libraries pom file:
<parent>
<groupId>org.my.company</groupId>
<artifactId>superpom</artifactId>
<version>1</version>
</parent>
I use default directory structure.
When I try to perform a release using the release plugin I run into a problem.
mvn release:prepare runs fine however when I run mvn release:perform maven checks out the corresponding tag from my local git repository into the target/checkout folder and tries to run the deploy goal.
However the build fails with the error message that it can't find the parent pom file defined in my library pom file.
I assume that's related to the fact that maven tries to find the parent pom file in the target folder and it is not available there.
Is there an easy way how to solve this problem?
Update:
I have multiple unrelated GWT libraries which should share the common company parent pom file in order to specify plugin versions.
The parent pom is just used for defining some default versions and won't contain any module definitions because all GWT libraries are unrelated.
The GWT library are really simple and have no real dependencies to any other libraries apart from the default ones (gwt, junit)
Update2:
I solved the problem by installing the superpom into my local repository by running mvn install in the folder of my superpom.
The first fail you did is not to versionise the parent pom where you defined the pluginManagement area. This is the first step you must do put the pom.xml which you like to use a parent. Secondly you have to put the information about the VCS into the scm area of that pom. After you cleaned up everything you must do a mvn release:prepare release:perform of the parent pom. After that you are able to use it as a parent in your other projects. Furthermore you should define the distributionManagement area in your parent pom.
I use a project layout like the first one described in the accepted answer to this question. If my parent-pom is managed, built and deployed separate from my project POMs, how can I ensure the pluginManagement section of my parent-pom is valid?
Maven only checks plugins that actually get used in the build as far as I can tell. Since most of the plugins I'm declaring in pluginManagement don't get used when I build the parent-pom, I have no way of knowing if I have an invalid entry until a child project tries to use a plugin it expects to be managed by the parent-pom.
I've tried the versions plugin, but it seems to ignore plugins that don't exist (ex: typos). I've tried declaring the plugins in my parent-pom with inherited=false, but then I have to tie every declared plugin to a phase. Plus, I don't necessarily want to run those plugins against my parent-pom.
I know lots of people use a parent-pom or a super-pom of some type, so there has to be something I'm overlooking.
In your parent pom module create a set of test maven projects, all inheriting parent pom, using some or all of the plugins defined there, and have parent pom run and verify build success of test maven projects. maven-invoker-plugin can help you in accomplishing all this. This plugin is used a lot for testing maven core plugins so you can find more usage examples in sources of maven core plugins.
Another advice is to add plugins to parent pom pluginManagement only when you need them, then you will have opportunity to test it as well. So steps are, start building a project which uses a given plugin not yet present in parent pom, add plugin to parent pom, release parent pom snapshot, make use of that snapshot in new project, if all OK release parent pom, and adjust reference to parent pom in new project. Later for another or same project if you need additional plugin or newer version of plugin already specified in parent pom, adjust parent pom, release new parent pom snapshot, check if it works for the given project, and if it does release parent pom, and adjust parent reference to newly released parent pom.
I'm fairly new to Maven and I'd like to use it to build a multi-module project.
Lets assume I have the following svn repository structure:
- /trunk/common-services/login-service
(.jar) [re-usable components]
- /trunk/services/mybusiness-service
(.jar)
- /trunk/webservices/mybusiness-rest
(.war)
- /trunk/products/myproduct
(pom) [issue mvn command here]
What I'd like to be able to do is to checkout and build the entire "product" from a single pom using a single mvn command (from a developers pov as well as a CI pov). It's safe to assume that I have the trunk checked out.
How do I do this using Maven? I've looked at the Maven reactor plugin, but I can't figure out how to use it correctly (if it is the correct plugin to use).
The reactor plugin assumes each module has its pom.xml.
For your use case, you would want to create a pom.xml for each module (login-service, mybusiness-service and mybusiness-rest). You would specify the dependencies in each of the modules. For instance, if your mybusiness-rest depends on login-service and mybusiness-service, you would specify these projects as dependencies.
You would have a pom.xml in /trunk which specifies each of the modules to be built. You can use the reactor features in this pom.xml to determine, when to build (or not build) specific modules.
Your developers and CI can build using this single pom.
I have maven multi-modules project. At the parent level, i have some java files. And in the parent pom.xml, at the package phase i do some stuff.
Usually, when i run mvn package at parent level, the package phase of parent pom will be run and all the modules will be packaged as well.
I am looking for a way that allow me to do these (when i run mvn package):
allow me to run only paren pom.xml (the script at the package phase), not the modules. This is the 1st priority.
allow me to run paren pom.xml and some particular modules (like module 1, module 2 BUT not module 3 , module 4).
Can i use profile for those issue?
Thanks.
While I agree with the fact that you may not have optimal project structure, the answer is that Maven 2.2.1 has an option "--non-recursive" which satisfies your first requirement:
-N,--non-recursive Do not recurse into sub-projects
So something like this:
mvn --non-recursive clean compile
Why do you want to have java code on the top level? In my opinion this is not a very good idea. Have your code in the subprojects and let the top-level project be responsible for holding the general information and configuration of the entire project.
If you have some base-library code in the top-level project now, you can put it in a sub-project and set up dependencies between the projects.
Take a look at Maven parent pom vs modules pom
The nature of your question indicates that your project structure may not be optimal.
If I have a parent pom and want to inherit this to several projects. I usually do this by adding in top of the project <parent> ... </parent>. What I don't like about this approach is that if something changes in my parent I have to edit all project which are inherited by that parent to modify the version number. Is there a better approach? I hope it is understandable what I'm trying to explain.
Thanks in advance.
What i don't like about this approach
is that if something changes in my
parent i have to edit all project
which are inherited by that parent to
modify the version number. Is there a
better approach?
Yes there is! Have a look at the Maven Versions Plugin, specifically:
versions:update-child-modules updates the parent section of the
child modules of a project so the
version matches the version of the
current project.
For example, if you
have an aggregator pom that is also
the parent for the projects that it
aggregates and the children and parent
versions get out of sync, this mojo
can help fix the versions of the child
modules.
(Note you may need to invoke
Maven with the -N option in order to
run this goal if your project is
broken so badly that it cannot build
because of the version mis-match).
Edit: Of course, using Maven3 you can now have < version >-less < parent > elements in sub modules:
Developers working in multi-module or multi-pom projects won't have to specify the parent version in every sub-module in Maven 3. Instead, you can add version-less parent elements.
Ref
You can use the Maven Release Plugin when doing a release. It will update all the version numbers automatically and create a tag in your source control (if you have SCM configured in the POM).
My commands for performing a release are typically as follows, after which I export the tag from SCM and build it with "mvn clean package" or "mvn clean deploy".
svn update (or whatever SCM you use)
mvn clean
mvn release:prepare -DautoVersionSubmodules=true
mvn release:clean
So for example if you version is first "1.0-SNAPSHOT", then the release plugin will create a tag "projectname-1.0" with version "1.0", and finally increase the current version to "1.1-SNAPSHOT". The plugin will ask you for the versions and tag name, so you can override the defaults.
Automatic Parent versioning (i.e. omission of the tag) is a contentious issue in the Maven space. There is a defect logged against it. For now, it is being considered as a fix or improvement in the 2.1 version branch,
You should keep your versions as snapshots until it's time to release. This way you won't have to change it every time you change the pom. However once you've released a parent pom, you will want to make the change to all the children (assuming the parent is outside the "reactor" build...otherwise it would have been all bumped together by the release plugin). There is a relatively new plugin called the versions-maven-plugin that can assist with changing the versions.
I think the important thing to realize is that in a multi-module build, maven always uses the the version that is from your local repository. This applies in multi-module builds too! So when you reference the "parent" pom you're getting the published parent artifact from your local maven repository. So when you do mvn install you repeatedly publish each module to your local repo.
While developing, your own modules are probably versioned to something like X.X-SNAPSHOT. The reference to the parent-pom is X.X-SNAPSHOT. Don't change these before you're ready to release.
So a simple case would be:
Before initial release all modules are called 1.0-SNAPSHOT.
When makin the initial release "golden build", rename all 1.0-SNAPSHOT modules to 1.0.
When starting development on the 1.1 release, you change all version numbers to 1.1-SNAPSHOT.
And so on...
The custom is to work with snapshot versions until you're releasing, at which point you update the version numbers everywhere. In the day-to-day development you do not change the version numbers because snapshot-releases get treated differently than hard-version releases.
Edit:
After some thought I think some of your confusion in the "comments" section arises from this: The version number in your pom reflects the overall application version. Any given pom change does not necessarily change the application version number. If you need to track changes in the pom I would suggest you use a source control system. So in the 3 month period you work on version 1.0, it's reasonable to keep the version number at 1.0-SNAPSHOT. In the (for instance) 3 week period you work on 1.1, the version number is 1.1-SNAPSHOT.