These are the steps to follow:
Linking a BOM
This is an optional step but very useful in my opinion. We’ve seen recently the importance of having a Bill of Materials (BOM) for our Mule apps in this post, and we’ve also seen that parent POM and BOM are not the same. In fact, BOM and parent POM are complementary, we should use both.Question is, how can I use both if I can only declare one parent POM for my mule apps? How do I reference both?
One way to do it (there are other ways), is to reference the BOM as the parent POM of the parent POM. It sounds confusing but it’s simple.
In our parent POM, at the begining of the pom.xml we just need to include the coordinates of the BOM:
This way, all of our child mule projects will inherit all the elements defined in the parent POM. And, on the other hand, the versions of all plugins and dependencies of the child mule project will be managed by the BOM.
Notice that we haven’t included the versions numbers for plugins and dependencies. Those versions will be inherited by the BOM.
In our parent POM, at the begining of the pom.xml we just need to include the coordinates of the BOM:
<parent>
<groupId>[YOUR_ANYPOINT_ORG_ID]</groupId>
<artifactId>bom</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
</parent>
Dependencies in Maven are transitive, which means that child projects will inherit from the parent POM and from the dependencies of the parent POM (in our case the BOM).
With this approach also, we don’t have to specify the versions for the dependencies in the parent POM, they will be picked up from the linked BOM.
With this approach also, we don’t have to specify the versions for the dependencies in the parent POM, they will be picked up from the linked BOM.
Parent POM Coordinates
Next, we need to specify the Maven coordinates for our POM file.- groupId - If you’re planning to store the parent POM file in Exchange here we’ll provide the Org Id or Business Group Id of our Anypoint org. Some customers deploy the parent POM to a private repository like Nexus of JFrog. In these cases, we typically use the reverse domain name, e.g. com.company.my
- artifactid - Provide a name for the parent POM.
- version - we’ll start with 1.0.0 in this example but obviously this is something that we’ll be changing over time and redeploying with each new version.
- packaging - For a parent POM, we must specify the packaging as pom so that Maven knows this is a parent pom and not a mule app.
<groupId>[YOUR_ANYPOINT_ORG_ID]</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
Common elements for our Mule Apps
The rest of our parent POM file will be the definition of all the elements that will be inherited by our child mule projects. In this post we’ll just use a simple example, but if you want to deep dive into everything we could include into a parent POM check out this other post. In particular, we’ll put the following to be shared with all our mule apps:Plugins
- Mule Maven Plugin
- Maven Clean Plugin
- HTTP Connector
- Sockets Connector
- Secure Properties module
- APIkit router
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>fc9e3283-a489-4e88-99aa-cceea4aa5ea1</groupId>
<artifactId>gon-bom</artifactId>
<version>1.0.0</version>
</parent>
<groupId>fc9e3283-a489-4e88-99aa-cceea4aa5ea1</groupId>
<artifactId>gon-parent-pom</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>gon-parent-pom</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<app.runtime>4.6.1</app.runtime>
<mule.maven.plugin.version>4.1.0</mule.maven.plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mule.tools.maven</groupId>
<artifactId>mule-maven-plugin</artifactId>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.mule.modules</groupId>
<artifactId>mule-apikit-module</artifactId>
<classifier>mule-plugin</classifier>
</dependency>
<dependency>
<groupId>org.mule.connectors</groupId>
<artifactId>mule-http-connector</artifactId>
<classifier>mule-plugin</classifier>
</dependency>
<dependency>
<groupId>com.mulesoft.modules</groupId>
<artifactId>mule-secure-configuration-property-module</artifactId>
<classifier>mule-plugin</classifier>
</dependency>
<dependency>
<groupId>org.mule.connectors</groupId>
<artifactId>mule-sockets-connector</artifactId>
<classifier>mule-plugin</classifier>
</dependency>
</dependencies>
<repositories>
<repository>
<id>anypoint-exchange-v3</id>
<name>Anypoint Exchange</name>
<url>https://maven.anypoint.mulesoft.com/api/v3/maven</url>
<layout>default</layout>
</repository>
<repository>
<id>mulesoft-releases</id>
<name>MuleSoft Releases Repository</name>
<url>https://repository.mulesoft.org/releases/</url>
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>mulesoft-releases</id>
<name>MuleSoft Releases Repository</name>
<layout>default</layout>
<url>https://repository.mulesoft.org/releases/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
Install the parent POM
Once our parent POM definition is ready, the last step is to make it available for future projects/apps. In this post, we’ll be installing the parent POM to our local maven repository (~/.m2/repository) for simplicity. In future posts, we’ll see how to deploy it to Exchange or to a private repository, which is the best practice for an organization with a team of developers.For that, we’ll run the maven commands with the maven installation of our system, not with the embedded maven instance in Anypoint Studio.
With that, right after you Save the pom.xml file, you will see that Anypoint Studio automatically downloads the dependencies in our parent POM. Double check the left panel of Studio:
Open a terminal from the folder of your parent POM project (in Anypoint Studio, right click on the project name > Show in > System Explorer. From there run the following:
mvn clean install
Verify that our parent POM is now available in our local repository. Go to your [HOME_DIRECTORY]/.m2/repository and look for the maven coordinates of your parent POM.
Test the parent POM
Time to see if it works. Create a new Mule project and open the pom.xml. This is how to use the parent POM:Reference the parent POM
At the begining of the pom file of our test project, we need to declare the parent POM with the parent element. For that, we need to specify the maven coordinates of our recently created parent POM project.<project>
...
<parent>
<groupId>[YOUR_ANYPOINT_ORG_ID]</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.0</version>
</parent>
...
</project>
Remove the redundant elements
You’ll notice that there are some elements that Anypoint Studio includes by default with each new Mule project that are part of our parent POM. We don’t need them anymore, as they will be automatically imported from our parent POM, so we can remove the following:- Properties
- Plugins:
- Mule Maven Plugin
- Maven Clean Plugin
- Dependencies (Connectors):
- HTTP Connector
- Sockets Connector
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>[YOUR_ANYPOINT_ORG_ID]</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.0</version>
</parent>
<groupId>[YOUR_ANYPOINT_ORG_ID]</groupId>
<artifactId>mule-child-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>mule-application</packaging>
<name>mule-child-test</name>
<build>
<plugins>
</plugins>
</build>
<dependencies>
</dependencies>
<repositories>
<repository>
<id>anypoint-exchange-v3</id>
<name>Anypoint Exchange</name>
<url>https://maven.anypoint.mulesoft.com/api/v3/maven</url>
<layout>default</layout>
</repository>
<repository>
<id>mulesoft-releases</id>
<name>MuleSoft Releases Repository</name>
<url>https://repository.mulesoft.org/releases/</url>
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>mulesoft-releases</id>
<name>MuleSoft Releases Repository</name>
<layout>default</layout>
<url>https://repository.mulesoft.org/releases/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
Notice as well that, Anypoint Studio is picking up the versions from the BOM. That means our project is inheriting from our parent POM and BOM files. Nice!
Our final test - Create a simple flow for a hello-world app and run it, just to make sure we can build our project.
Our final test - Create a simple flow for a hello-world app and run it, just to make sure we can build our project.