Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven Multi-Module Project Structure

Tags:

java

maven

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:

  • authentication-service (contains the code for authentication)
  • core-service (contains generated thrift sources and some common classes such as service discovery and initialization logic)

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?

like image 454
Colin M Avatar asked Jun 17 '13 11:06

Colin M


4 Answers

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.

like image 66
Nick Holt Avatar answered Oct 10 '22 19:10

Nick Holt


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.

like image 38
StanislavL Avatar answered Oct 10 '22 18:10

StanislavL


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

like image 5
whaley Avatar answered Oct 10 '22 19:10

whaley


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.

like image 3
Nicola Musatti Avatar answered Oct 10 '22 17:10

Nicola Musatti