13

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?

4 Answers 4

16

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for reminding me of my issues with the Maven release plugin :-)
Just a side commentary on the usage of multi-module projects - if the modules all have a different lifecycles, then they shouldn't be part of the same multi-module structure. @colin-morelli should take this into account in his decision.
@whaley At the current moment, they all have the same lifecycle (partially because they're all currently in a multi-module project). However, the project is already large enough and takes a little bit to build, test and deploy. Ideally, I would like to get to the point where they can be released independently.
@NickHolt - I should also add that everything is currently built (and deployed) by a CI server. So yeah - I have most definitely felt the pains of having to rebuild everything from a few line change in one service.
7

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.

1 Comment

Thrift handles most changes pretty gracefully (unless you, for example, change the first parameter of a method signature to a different type). So, it's entirely possible that service A (which was compiled on version 1 of service B) could call version 2 of service B and not have any troubles. This was part of the reason for going with thrift - the applications can be loosely coupled. But, you make a valid point so +1 from me
5

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

1 Comment

I have made the decision to go with separate modules. Appreciate the advice from everyone. Gave the answer to Nick, but +1 to you as well - you both pushed me that direction.
3

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.

2 Comments

This was my feeling as well (better to have projects evolve independently). Actually, something felt wrong about making the multi-module project to begin with. Unfortunately, time constraints left it sort of non-optional, but I now have time to revisit this. They will definitely be maintained by separate teams.
Note that the approach I mentioned above, while undoubtedly complicated, relegates the aggregator project to being just that: a way to build your projects together (if you want to). This allows us to have different aggregators for different module subsets with a different purpose. One that puts everything together in order to perform releases, another one for the projects that are packaged in a single WAR file, and so on.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.