Introduction
Mulesoft offers built-in support for managing mule projects with maven. This highly recommended feature provides benefits in terms of portability, maintainability and integration into existing CI/CD tools. As the IT project progresses the number of mule projects increases and not long after that upgrading dependencies becomes a near impossible task that can take days to complete, even with plain mule maven projects.
Fortunately maven offers the possibility to provide common configurations in parent POMs. In this post I will show you how to create and use a parent POM in mule projects.
Project outline
For the sake of simplicity I am using a small example setup. Imagine an order management system with a connection to salesforce to collect customer information and a connection to a MongoDB database with orders. The customer information is exposed through the customers-system-api and the order information is exposed through the orders-system-api. Both system APIs are part of the same order-management and share the HTTP listener configuration.
The full project sources can be found here
“Disclaimer: The flows and connector configurations only contain the minimal required properties and do not a represent a complete setup. Since the scope of this guide is the maven setup, this part of the projects is complete and will build successfully.”
The POMs for these 2 API projects have similar dependencies and plugins, but also very specific dependencies as you can see below.
orders-system-api pom.xml
customers-system-api
Step 1: Move version definitions to the properties
A great benefit of Anypoint studio is the automatic addition of dependencies to the POM when you drag a component from the pallet into the canvas. There is however one thing you should do yourself. As you can see in both POMs above, the versions of these dependencies is specified at the dependency and not in the properties section. The transfer of dependencies to a parent will be much easier if the versions are only specified in the properties. So let’s clean up the current POM’s now.
orders-system-api
In the orders-system-api the following versions need to be specified:
- build-helper-maven-plugin
- mule-module-mongo
- order-management (the custom domain)
After refactoring you should end up with something like this:
sysem-api POM.xml changes
customers-system-api
In the customers-system-api the following versions need to be specified:
- build-helper-maven-plugin
- mule-module-sfdc
- order-management (the custom domain)
After refactoring you should end up with something like this:
sysem-api POM.xml changes
Step 2: Create the parent POM project
With clean project POMs, the next step is to create the parent POM. Basically there are two ways to approach this. I could create a new empty maven project and build up the POM from scratch, but since the children were created as mule maven projects I will create the new project the same way.
Create new mule project
In studio a new mule maven is created as follows:
- File > New > Mule Project
- In the popup, fill the name of the project and check the box ‘Use maven’
- Click finish
Change the project packaging
A parent POM project is packaged as pom, a mule parent pom is no different. So this is the first adjustment to be made.
change parent pom packaging
Remove mule files
Anypoint studio is very helpful for creating a new project, since it creates all files needed for a deployable mule API. The only file needed for a parent POM project is the pom.xml and the following files and directories can be removed from the parent-pom project:
- mule-project.xml
- src/main/app
- src/main/api
Optionally the project properties in Anypoint studio can be cleaned up. This does not affect the POM structure, and is not in scope for now.
Step 3: Leverage dependency management
The dependency management section is intended for the management of dependency configuration (i.e. version specification, transitive dependency exclusion).
Create and fill the dependency management section
Now the dependency management section is created in the parent POM and the complete dependencies section is copied into this new section.
dependency management section
Step 4: Leverage plugin management
The plugin management section within the build section of a POM works the same way as dependency management, with the difference that is is used for plugins. For this to work in a parent POM the plugins section only has to be wrapped by the pluginManagement tag.
The build-helper-maven-plugin version definition should be transferred to the properties section as well.
build section with plugin management
Step 5: Inherit parent
The setup of the parent POM is now done and the time has come to inherit this POM in the children. With a large set of APIs this step process can be quite a puzzle, but the trick is to take it one API at a time, preferably in pair and followed by a review (if this is not the standard way of working in your team). Before proceeding to changing the first child the parent POM needs to be added to the local maven repository. This should be done every time the POM is changed.
In the root directory of the parent pom project execute: mvn install
Define parent in the API project
In the POM of the API the parent section needs be added. In this case the groupId of both parent and child is the same, thus this can be removed in the child.
parent section
Clean duplicate definitions from child POM
All elements that are already defined in the parent POM can now be removed from the child POM.
Caveat: When using a private artifact repository that is not in your maven settings you will need to define this repository in a distributionManagement section inside the child projects, otherwise the parent POM can not be resolved during the build.
Cleanup dependencies section
Since all the dependencies where copied into the dependency management section the configuration of the dependencies can now be cleaned up. The project was created as a mule project so it is very likely that all child projects also depend on these libraries. Of course these children could have been slimmed down already and unnecessary dependencies were removed. In that case the the actual inheritance step will need more care than in this post is described, but the principle is the same.
cleaned dependencies section
Copy remaining definitions to the management sections in the parent
All definitions, both dependencies and plugins, must be copied to respective management section in the parent. Don’t forget to move the defined properties along with this move.
Check duplicate definitions with sibling projects
All duplicate definitions found in sibling projects (other projects that inherit the same parent) can be moved up to the parent.
Starting with the order-system-api this POM and the parent POM look as follows after completing these actions:
order-system-api POM
order-management-parent-pom POM
After finishing the second child, the customer-system-api project, the result is again different for all three POMs. Can you spot the changes?
customer-system-api POM
order-system-api POM
order-management-parent-pom POM
Conclusion
Managing and maintaining the source projects in large scale Mulesoft API environments can evolve to a near impossible task, but leveraging the full possibilities of a build tool like maven will significantly ease the burden. I am fully aware that my example comes nowhere near a real life situation. To make it up to you, keep an eye on the blog, in my next post on parent POMs I will cover a POM inheritance model with multiple layers and different parents for various types of mule APIs / batch projects. I hope you have enjoyed reading this post. Any comments and remarks are more than welcome.
Glossary
Sources used for this post:
Mulesoft and maven: https://docs.mulesoft.com/mule-user-guide/v/3.9/using-maven-with-mule
Mulesoft shared resources: https://docs.mulesoft.com/mule-user-guide/v/3.9/shared-resources#deploying-with-shared-resources
Maven parent POMs: https://maven.apache.org/pom/index.html
Maven dependency management: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
Maven integration for eclipse: http://www.eclipse.org/m2e/