Discover our knowledge. Read our blogs!

Learn more

We build all our solutions with WSO2 and we are proud that we are WSO2 Premier Certified Integration Partner and Value-Added Reseller.

Learn more

Versioning in Maven of a WSO2 ESB/ WSO2 EI Multi Module project

35 min read

Versioning in Maven project of WSO2 ESB  WSO2 EI multi module project - women who like codeAs a java based product, the WSO2 ESB / WSO2 EI multimodule project can be built with Maven. Maven Multi Module projects contain multiple modules with each their own pom file. We use Maven in continuous development, which gives extra management to a project, and the possibility to have it as a part of a bigger project. In this blog I will tell you more about it.

For an ESB development, we use sub-projects of type carbon archive, esb and registry. We can also add custom mediators, custom java projects, as well as test (sub)projects.

WSO2-esb-samples

Pom file of Maven parent project

xml version="1.0" encoding="UTF-8"?>

<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd"
 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
>
       <modelVersion>4.0.0</modelVersion>
       <groupId>com.example</groupId>
       <artifactId>wso2-esb-samples</artifactId>
       <version>1.0.0.0</version>
       <packaging>pom</packaging>
       <name>wso2-esb-samples</name>
       <description>wso2-esb-samples</description>
       <modules>
              <module>esb-samples</module>
              <module>registry-samples</module>
              <module>car-archive</module>
              <module>test-project</module>
       </modules>
       <properties>
              <maven.car.deploy.skip>false</maven.car.deploy.skip>
              <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
              <maven.deploy.skip>true</maven.deploy.skip>
       </properties>
       <repositories>
              <repository>
                      <releases>
                             <enabled>true</enabled>
                             <updatePolicy>never</updatePolicy>
             <checksumPolicy>ignore</checksumPolicy>
                      </releases>
                      <id>wso2-nexus</id>                          <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>a              </repository>
              <repository>
                      <releases>
                             <enabled>true</enabled>
                             <updatePolicy>never</updatePolicy>   <checksumPolicy>ignore</checksumPolicy>
                      </releases>
                      <id>wso2-maven2-repository-1</id>
                      <url>http://dist.wso2.org/maven2</url>
              </repository>
              <repository>
                      <releases>
                             <enabled>true</enabled>
                            <checksumPolicy>ignore</checksumPolicy>
                      </releases>
                      <id>wso2-nexus-maven2-repository-1</id>
          <url>http://maven.wso2.org/nexus/content/groups/wso2-
public/</url>
              </repository>
       </repositories>
       <build>
              <plugins>
                      <plugin>
                             <artifactId>maven-eclipse-plugin
</artifactId>
                             <version>2.9</version>
                             <configuration>
                                    <buildcommands />
                                    <projectnatures>
<projectnature>org.wso2.developerstudio.eclipse.mavenmultimodule.
project.natur
</projectnature>
                                    </projectnatures>
                             </configuration>
                      </plugin>
              </plugins>
       </build>
       <profiles>
              <profile>
                      <id>dev</id>
                      <activation>                 
<activeByDefault>true</activeByDefault>
                      </activation>
                      <properties>
                             <carbon.server.url>https://localhost:9443</carbon.server.url>
                             <carbon.user>admin</carbon.user>
                             <carbon.password>admin</carbon.password>
                      <JMSserver>tcp://localhost:61616</JMSserver>
                             <JMS_Incoming_queue>incoming.queue</JMS_Incoming_queue>
                             <JMS_Outgoing_queue>outgoing.queue</JMS_Outgoing_queue>
                             <TestMode>true</TestMode>
                      </properties>
              </profile>
       </profiles>
</project>


Let’s dig in to version management.

By default, versions in eclipse consist of 3 parts, major, minor and bugfix version components, i.e. 1.0.0. It is possible your projects to have 4 parts in a version. In the following examples, I will use a 4-part version number, such as 1.0.0.0. With the maven versions plugin we are able to change the artifact version of all pom.xml files involved in this project. The following command is used to set the new version from any version to 1.2.3.4:

mvn versions:set -DnewVersion=1.2.3.4  

After execution of the command, the version of the parent project and all sub-projects is set to the new value.

The project version in all pom files are changed.

Main pom snippet

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"
 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance">
       <modelVersion>4.0.0</modelVersion>
       <groupId>com.example</groupId>
       <artifactId>wso2-esb-samples</artifactId>
       <version>1.2.3.4</version>
       <packaging>pom</packaging>
       <name>wso2-esb-samples</name>
       <description>wso2-esb-samples</description>
       <modules>
              <module>esb-samples</module>
              <module>registry-samples</module>
              <module>car-archive</module>
              <module>test-project</module>
       </modules>

 

Esb project pom snippet

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd"
 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance">
       <modelVersion>4.0.0</modelVersion>
       <parent>
              <groupId>com.example</groupId>
              <artifactId>wso2-esb-samples</artifactId>
              <version>1.2.3.4</version>
       </parent>
       <groupId>com.example.esb-samples</groupId>
       <artifactId>esb-samples</artifactId>
       <version>1.2.3.4</version>
       <packaging>pom</packaging>
       <name>esb-samples</name>
       <description>esb-samples</description>

 

Artifact.xml and versions

In WSO2 esb and registry project there is a file named artifact.xml which contains the artifacts within the project (sequence, template, registry resource). All artifacts have their own version.

Artifact.xml in esb project

<?xml version="1.0" encoding="UTF-8"?>
<artifacts>
     <artifact name="accounts" groupId="com.example.esb-samples.endpoint" version="1.0.0.0" type="synapse/endpoint" serverRole=
"EnterpriseServiceBus">
        <file>src/main/synapse-config/endpoints/accounts.xml</file>
    </artifact>
    <artifact name="mail_receiver" groupId="com.example.esb-samples.proxy-service" version="1.0.0.0" type="synapse/proxy-service" serverRole="EnterpriseServiceBus">
        <file>src/main/synapse-config/proxy-services/mail_receiver.xml</file>
    </artifact>
</artifacts>

 

Artifact.xml in the registry project

<?xml version="1.0" encoding="UTF-8"?>
<artifacts>
     <artifact name="xslt" groupId="com.example.registry-samples.resource" version="1.0.0.0" type="registry/resource" serverRole=
"GovernanceRegistry">
        <collection>
            <directory>xslt</directory>
            <path>/_system/governance/config/xslt</path>
        </collection>
    </artifact>
    <artifact name="endpoints" groupId="com.example.registry-samples.resource" version="1.0.0.0" type="registry/resource" serverRole=
"GovernanceRegistry">
        <collection>
            <directory>endpoints</directory>
            <path>/_system/governance/config/endpoints</path>
        </collection>
    </artifact>
</artifacts>

 

In case you do not see the artifact.xml in Eclipse Project Explorer

In the default WSO2 Developer Studio for Eclipse, artifact.xml files are not visible. You can see them in file system, or in Navigator perspective, and since you need to be aware of those files, you can customize the view in Eclipse as follows:

  1. Right click on the menu in project Explorer
  2. Select Customize View
  3. Uncheck Hide Artifact.xml files box

Customize view in eclipse

Hide artifact in eclipse

When you create a new artifact using WSO2 Developer Studio, the version of that artifact is taken from the project pom at the moment of the artifact creation. If we increase version of the project through Maven, the versions in artifact.xml file are not changed automatically. We want to have the matching version numbers between the maven project and the artifacts like a sequence and any other artifact when we build a project.

We will achieve update of the versions in the artifacts with these 2 steps:

  1. Change version of the dependency artifacts in the car pom
  2. Change versions of the artifacts in the artifact.xml

Change version of the dependency artifacts in the car pom

It is easy to use the variable ${project.version} in the version element of the dependency.

    <dependency>
      <groupId>com.example.esb-samples.proxy-service</groupId>
      <artifactId>sample-proxy</artifactId>
      <version>${project.version}</version>
      <type>xml</type>
    </dependency>

 

Car project pom file

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.example</groupId>
    <artifactId>wso2-esb-samples</artifactId>
    <version>1.0.1</version>
  </parent>
  <groupId>com.example</groupId>
  <artifactId>car-archive</artifactId>
  <version>1.0.1</version>
  <packaging>carbon/application</packaging>
  <name>car-archive</name>
...
...
  <dependencies>
    <dependency>
      <groupId>com.example.esb-samples.endpoint</groupId>
      <artifactId>accounts</artifactId>
      <version>${project.version}</version>
      <type>xml</type>
    </dependency>
    <dependency>
      <groupId>com.example.esb-samples.endpoint</groupId>
      <artifactId>echo</artifactId>
      <version>${project.version}</version>
      <type>xml</type>
    </dependency>
    <dependency>
      <groupId>com.example.esb-samples.proxy-service</groupId>
      <artifactId>sample-proxy</artifactId>
      <version>${project.version}</version>
      <type>xml</type>
    </dependency>
  </dependencies>
...
</project>

 

Change versions of the artifacts in the artifact.xml

A simple replacement of the version inside the artifact.xml file will not work because if we add the ${project.version} in the place of the version, the build will take this exact string and attach it as it is a version number. The variable will not be changed in the moment when the artifact.xml is used to build the artifact files. Moreover, in m2 folder you will find the string “${project.version}” as a suffix to the artifact files, instead of the real version.

In order to solve updating of the versions inside the artifact files, we can use maven-antrun-plugin in the pom file of the project that contains the artifact file.

Execution phase is important

Maven-antrun-plugin should run on the phase validate, because after this phase, the artifact.xml file is used by the wso2 maven plugins to complete the build.

ESB sample proxy

The ant task should have a regular expression for finding version-attributes with a version number. The substitution expression should be the replacement of that attribute value with the project’s version number.

Plugin execution specification

<plugins>
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.8</version>
        <executions>
          <execution>
            <id>artifacts_version</id>
            <phase>validate</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <tasks>
                <replaceregexp byline="true">
                  <regexp pattern="(?&lt;!xml) version=&quot;(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)?(?:(\d+)\.)?(\*|\d+)(-SNAPSHOT)?&quot;" />
                  <substitution expression=" version=&quot;${project.version}&quot;" />
                  <fileset dir=".">
                    <include name="artifact.xml" />
                  </fileset>
                </replaceregexp>
              </tasks>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>


Executing the command mvn clean install after the version increase (mvn versions:set _DnewVersion=1.2.3.4) will change all artifact versions to the new version which confirms compliance of our code with the latest version number from the main pom file.

The regular expression

The regular expression for version number with four numeric groups and optional –SNAPSHOT is

<regexp pattern="(?&lt;!xml) version=&quot;(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)?(?:(\d+)\.)?(\*|\d+)(-SNAPSHOT)?&quot;" />

Versions matching the above regex patterns are:

111.222.333.444

111.222.333.444-SNAPSHOT

With this specific part of the regex: (?&lt;!xml), we make sure to exclude the first line in the xml: <?xml version="1.0" encoding="UTF-8"?>.

The substitution pattern

The substitution pattern is

  <substitution expression=" version=&quot;${project.version}&quot;" />

Notice the empty space at the beginning, the escaped sign for quote &quot; and the parameter ${project.version} which is the version of the main project.

Table 1 Artifact file from ESB project

<?xml version="1.0" encoding="UTF-8"?><artifacts>
     <artifact name="accounts" groupId="com.example.esb-samples.endpoint" version="1.2.3.4" type="synapse/endpoint" serverRole=
"EnterpriseServiceBus">
        <file>src/main/synapse-config/endpoints/accounts.xml</file>
    </artifact>
     <artifact name="mail_receiver" groupId="com.example.esb-samples.proxy-service" version="1.2.3.4" type="synapse/proxy-service" serverRole="EnterpriseServiceBus">
        <file>src/main/synapse-config/proxy-services/mail_receiver.xml</file>
    </artifact>
</artifacts>

 

Table 2 Artifact file from Registry project

<?xml version="1.0" encoding="UTF-8"?>
<artifacts>
     <artifact name="xslt" groupId="com.example.registry-samples.resource" version="1.2.3.4" type="registry/resource" 
serverRole="GovernanceRegistry">

        <collection>
            <directory>xslt</directory>
            <path>/_system/governance/config/xslt</path>
        </collection>
    </artifact>
    <artifact name="endpoints" groupId="com.example.registry-samples.resource" version="1.2.3.4" type="registry/resource" 
serverRole="GovernanceRegistry">

        <collection>
            <directory>endpoints</directory>
            <path>/_system/governance/config/endpoints</path>
        </collection>
    </artifact>
</artifacts>

 

References

[1] https://maven.apache.org/index.html
[2] https://maven.apache.org/guides/introduction/introduction-to-the-pom.html
[3] https://svn.wso2.org/repos/wso2/trunk/tools/ide/eclipse/docs/src/site/xdoc/devs_maven_support.xml

New Call-to-action 

Care to share?
   
Picture of Jenny Gligorovska
Published December 21, 2018

Jenny Gligorovska

Jenny Sladjana Gligorovska is an IT expert with 12+ years of experience in enterprise environments developing projects in Telecommunication, CRM, e-Commerce, Payments, Geographic Information Systems and various Governmental fields. Within the development of complex systems, Jenny has been in roles such as Software Architect, Project Manager, Team Leader, and always to the bottom of it: a Developer.

Responses

Stay up to date with the latest articles