Maven Polyglot - Forget about pom.xml

Posted by Xavier Bouclet on April 02, 2017 · 10 mins read

Fed up of pom xml files when you use Maven? Here is the solution : Maven Polyglot. Maven Polyglot is out there since over 5 years now and can be used to write pom file in other languages such as :

  • Atom

  • Groovy

  • Clojure

  • Ruby

  • Scala

  • YAML

To give it a try with an existing project, we have to use the following command line in the project :

mvn io.takari.polyglot:polyglot-translate-plugin:translate -Dinput=pom.xml -Doutput=pom.{format}

Where {format} is the file extension of the target format. In my case I tried with YAML format so I replaced {format} with yml.

This the pom.xml I tried out :

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>fr.ablx.yml</groupId>
    <artifactId>backend</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <!-- Project Properties -->
        <dataBaseSchema>DATABASE</dataBaseSchema>
        <!-- Build properties -->
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <spring.boot.version>1.4.2.RELEASE</spring.boot.version>
        <spring.loaded.version>1.2.6.RELEASE</spring.loaded.version>
        <lombok.version>1.16.10</lombok.version>
        <jsonpath.version>2.2.0</jsonpath.version>
        <!-- Report properties -->
        <maven.site.version>3.4</maven.site.version>
        <asciidoctor.version>1.5.3</asciidoctor.version>

        <debug>true</debug>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring.boot.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.2.0</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok-maven -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.hsqldb/hsqldb -->
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.3.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.0</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.5</version>
        </dependency>

    </dependencies>

    <build>
        <resources>
            <resource>
                <filtering>true</filtering>
                <directory>${project.build.sourceDirectory}\..\resources</directory>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <filtering>true</filtering>
                <directory>${project.build.testSourceDirectory}\..\resources</directory>
            </testResource>
        </testResources>
        <finalName>mysample-web</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring.boot.version}</version>
                <!-- <configuration> <fork>true</fork> <jvmArguments> -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
                    </jvmArguments> </configuration> -->
                <dependencies>
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>springloaded</artifactId>
                        <version>${spring.loaded.version}</version>
                    </dependency>
                </dependencies>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-site-plugin</artifactId>
                <version>${maven.site.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>org.asciidoctor</groupId>
                        <artifactId>asciidoctor-maven-plugin</artifactId>
                        <version>1.5.3</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/libs-snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>central</id>
            <url>https://repo1.maven.org/maven2</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/libs-snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>central</id>
            <url>https://repo1.maven.org/maven2</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </pluginRepository>
    </pluginRepositories>
</project>

This is the pom.yml file I obtained ;

modelVersion: 4.0.0
groupId: fr.ablx.yml
artifactId: backend
version: 0.0.1-SNAPSHOT
packaging: jar
properties: {debug: true, asciidoctor.version: 1.5.3, lombok.version: 1.16.10, dataBaseSchema: DATABASE,
  maven.site.version: 3.4, java.version: 1.8, maven.compiler.target: '${java.version}',
  spring.loaded.version: 1.2.6.RELEASE, project.build.sourceEncoding: UTF-8, jsonpath.version: 2.2.0,
  spring.boot.version: 1.4.2.RELEASE, maven.compiler.source: '${java.version}'}
dependencies:
- {artifactId: spring-boot-starter-web, groupId: org.springframework.boot, version: '${spring.boot.version}'}
- {artifactId: spring-boot-starter-test, groupId: org.springframework.boot, scope: test,
  version: '${spring.boot.version}'}
- {artifactId: spring-boot-starter-data-jpa, groupId: org.springframework.boot, version: '${spring.boot.version}'}
- {artifactId: json-path, groupId: com.jayway.jsonpath, scope: test, version: 2.2.0}
- {artifactId: lombok, groupId: org.projectlombok, version: '${lombok.version}'}
- {artifactId: hsqldb, groupId: org.hsqldb, version: 2.3.4}
- {artifactId: commons-dbcp, groupId: commons-dbcp, version: 1.4}
- {artifactId: gson, groupId: com.google.code.gson, scope: test, version: 2.8.0}
- {artifactId: commons-lang3, groupId: org.apache.commons, version: 3.5}
build:
  finalName: mysample-web
  plugins:
  - groupId: org.springframework.boot
    artifactId: spring-boot-maven-plugin
    version: ${spring.boot.version}
    dependencies:
    - {artifactId: springloaded, groupId: org.springframework, version: '${spring.loaded.version}'}
  - groupId: org.apache.maven.plugins
    artifactId: maven-site-plugin
    version: ${maven.site.version}
    dependencies:
    - {artifactId: asciidoctor-maven-plugin, groupId: org.asciidoctor, version: 1.5.3}
  resources:
  - {directory: '${project.build.sourceDirectory}\..\resources', filtering: true}
  testResources:
  - {directory: '${project.build.testSourceDirectory}\..\resources', filtering: true}
pluginRepositories:
- id: spring-snapshots
  layout: default
  snapshots: {enabled: true}
  url: http://repo.spring.io/libs-snapshot
- id: central
  layout: default
  releases: {enabled: true}
  url: https://repo1.maven.org/maven2
pomFile: {}
repositories:
- id: spring-snapshots
  layout: default
  snapshots: {enabled: true}
  url: http://repo.spring.io/libs-snapshot
- id: central
  layout: default
  releases: {enabled: true}
  url: https://repo1.maven.org/maven2

We can see the pom.xml has been shrinked to a pom.yml with 56 line. A win of 100 lines. So big pom files become more readable. After the creation of the pom.yml, I had to add the following extensions.xml in my project :

<?xml version="1.0" encoding="UTF-8"?>
<extensions>
  <extension>
    <groupId>io.takari.polyglot</groupId>
    <artifactId>polyglot-yaml</artifactId>
    <version>0.1.19</version>
  </extension>
</extensions>

Yes we can’t remove XML completely but this file is rather simple and may be one day we will be able to completely get rid of it. The extensions.xml has to be placed in the project folder in the folder .mvn.

The pom.yml file went fine except for the line pomFile:{}. This line broke my build but when I removed it everything went back to normal.

Now I am able to use my mvn command as before.

[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ backend ---
[INFO] Building jar: /home/thor/projets/sources/java/backendyml/target/mysample-web.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.960 s
[INFO] Finished at: 2017-04-02T16:56:33-04:00
[INFO] Final Memory: 20M/403M
[INFO] ------------------------------------------------------------------------