In his article titled “Gradle Profiles for Multi-Project Spring Boot Applications,” our colleague Justin Wilson mentions that related micro-service projects can be stored in a single repository using a parent project to group them together. While this works for smaller, simpler projects, we want to highlight some of the scalability issues with this approach and offer an alternative for larger, more complex projects.
The Issue of Coupling
The benefit of a multi-project model is that all components that inherit from the parent POM automatically use the same code for all shared components. This is also its greatest drawback, depending on the architecture of the projects in the POM.
Consider the situation where two components share a parent POM because they leverage much of the same code.
Two components can share code by utilizing a parent POM
In this case, changing some of that shared code mandates a re-test and re-deploy of each component, which is probably what is desired. Since each of the two components will already be fully regression-tested with each release, any defects caused by this change to the shared code will be caught by regression testing. So in this case it works out just fine.
Changing shared code requires regression testing both components
However, let’s consider a large project with multiple different components, all using the same parent POM to include several shared code bases.
Many components can share many code bases by inheriting from the same parent POM
A change to any shared code will automatically be included in each child project. In a parent POM scenario, all changes to shared components are forced into each child component.
The impacts of a small change to shared code can be severe when many projects share a parent POM
Let’s consider the impacts of this change to a shared component.
The code change was required by one of the components, and so the new code will be tested while testing the new feature that drove the change. All good here.
However, the change is automatically included by every other component. Will they all be tested?
Testing every component with every change to shared code is very challenging and creates a huge burden on QA and development. This creates a huge discouragement to touch anything that is shared code.
What if testing reveals that this change breaks another component? Development will have to scramble to figure out how to make the code change to the shared code in a way that does not break other components.
How does anyone know whether the changed shared code is actually being used by any other component? This requires detailed code analysis to determine if additional testing is even necessary.
Perhaps components that weren’t expecting this change and don’t have time to be tested could simply be left undeployed?
Except that these components have other changes and enhancements that were developed at the same time that do need to be deployed.
If we do this, now we have a mismatch between what is in production and what is in version control as “the latest release” (because all of these projects are in one repository, remember?)
A Better Solution: Versioning Shared Code Artifacts
A better solution to sharing code is to create a separate repository for each shared code base and control stable builds of each code base in a repository management tool like Artifactory or Sonatype Nexus.
Controlling stable versions of each shared code project allows components to upgrade independently
Need help separating a multi-project POM? Does your team have the tools in place to automate application build and deployment? Contact Credera at firstname.lastname@example.org or call 972.692.0010. For more information on source code management topics, please visit our blog or follow us at @CrederaIT.