I'm building a distributed application that is based off of a front-end (read: web-facing) HTTP API which calls into underlying (read: non-web-facing) Thrift Services.
As an example, I may have:
All of the individual services depend on core-services, as does the HTTP web-facing API. I have this as a multi-module project right now, but I would like each to be separate (and tracked in their own repositories - though I know I could still do this with a multi module build).
tl;dr -
Is it a common build practice to have a module (core-service) which is individually built and then pushed to a maven repo (and then included as a jar in the other projects), or would it be better in this case to do a multi-module project?
Personally I try to avoid multi-module projects as, if you're using the Maven Release Plugin, you are locked into releasing all your modules together.
While this may sound like a convenience the problem arises when you need to do bug fix release to one of the modules - you end up releasing all the modules, not just the module with the bug fix, incrementing their version even though they haven't changed.
You also take a hit if you're running CI with multi-module projects - you're build typically runs over all modules from you root pom but if you're working in a particular module, you end up taking the hit of building those that haven't changed, in effect losing some of the benefits that the modularization was meant to provide.
So, go with independent modules but, and this is the important bit, create a common 'dependency' pom used by each.
A 'dependency' pom is a pom that standardizes all the dependencies across your projects and is different in that those dependencies are specified in the dependencyManagement
section rather than the dependencies
section (it also sets up standard plugin config, etc). This allows your project poms to specify the dependency pom as their parent and then declare the dependencies they need minus the versions, which are picked up from the 'dependency' pom and thus standardized across your projects.
If you are still concerned about being able to built everything, this can be achieved with a simple batch-file.
I would say multi-module project is better. In case of placing core service in the repository developers should care about versions. Developer1 needs the old service but Developer2 updates the service.
Multiple branches also could be a problem.
A multi-module build should be favored when all of the individual modules will have the same lifecycle as each other... in other words, when they are always released together, have their version numbers incremented together, etc. etc.
A strong example of this in the OSS world is the apache camel project. For instance, all of the bundled components exist as individual modules that can be included separately in your project, but are tied to the same lifecycle as the camel core distribution.
Maven multi-module builds allow for some conveniences when it comes down to putting your projects in CI or loading them in IDEs for instance but, generally speaking, if all of the individual modules do not share the same lifecycle, then a multi-module project is not a great fit
In principle it is always better to have your projects evolve as independently as possible. However this is more an organizational issue rather than a technical one. When all is said and done your project structure should be consistent with your organization.
This boils down to keeping projects separate and have depending projects manage dependencies by means of a local repository manager if they are either maintained by different people or it makes sense to release them at different times. Otherwise you're probably better off with a multi-module project structure.
In our project we went for a sort of an in-between choice: we do have a multi-module structure, but all the projects reside in independent Subversion repositories, so that they can be branched separately, and we use the aggregator project to choose how to mix and match projects from different branches by means of svn:externals
in order to create customized releases for specific customers.
The downside is that maintaining a similar structure is complicated and time-consuming. We have developed a significant amount of scripts to partly automate these tasks. This is particularly burdensome because the Maven release plugin
is not capable of dealing with modules hooked by means of Subversion externals.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With