Wednesday, January 19, 2022

A Sample of Maven Parent POM to create Library and Spring Based Release Builds

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.idd.abc</groupId>
  <artifactId>abc-parent</artifactId>
  <version>0.0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Base Parent POM for ABC application</name>
  <description>See README.md</description>

  <properties>
    <java.release.version>1.8</java.release.version>
    <maven.compiler.source>${java.release.version}</maven.compiler.source>
    <maven.compiler.target>${java.release.version}</maven.compiler.target>
    <maven.build.timestamp.format>yyyy-MM-dd_HH-mm-ss</maven.build.timestamp.format>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    <app.id>${project.artifactId}</app.id>
    <start-class>com.idd.abc.base.Application</start-class>

    <spring-boot.version>2.6.2</spring-boot.version>
    <spring-core.version>5.3.14</spring-core.version>

    <log4j2-logstash-layout.version>1.0.5</log4j2-logstash-layout.version>

    <buildnumber-maven-plugin.version>3.0.0</buildnumber-maven-plugin.version>
    <git-code-format-maven-plugin.version>2.7</git-code-format-maven-plugin.version><!-- 3.0 available, requires JDK 11 -->
    <git-commit-id-plugin.version>4.9.10</git-commit-id-plugin.version>
    <googleformatter-maven-plugin.version>1.7.5</googleformatter-maven-plugin.version>
    <maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version>
    <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
    <maven-enforcer-plugin.version>3.0.0</maven-enforcer-plugin.version>
    <maven-failsafe-plugin.version>2.22.2</maven-failsafe-plugin.version>
    <maven-resources-plugin.version>3.2.0</maven-resources-plugin.version>
    <maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>

    <local-log-location>C:\\app\\spring-boot-poc\\logs</local-log-location>
    <server-log-location>/app/abc/logs</server-log-location>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

      <!-- Remove dependencies on logback -->
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>${spring-boot.version}</version>
        <exclusions>
          <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
          </exclusion>
          <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
          </exclusion>
          <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
          </exclusion>
          <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
          </exclusion>
          <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
          </exclusion>
        </exclusions>
      </dependency>

      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring-boot.version}</version>
        <exclusions>
          <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
          </exclusion>
          <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
          </exclusion>
          <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
          </exclusion>
          <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
          </exclusion>
          <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
          </exclusion>
        </exclusions>
      </dependency>

      <!-- Remove dependencies on commons-logging -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring-core.version}</version>
        <exclusions>
          <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
          </exclusion>
        </exclusions>
      </dependency>

    </dependencies>
  </dependencyManagement>

  <dependencies>
    <!-- re-defined -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
    </dependency>

    <!-- Web -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Cache -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
      <groupId>com.github.ben-manes.caffeine</groupId>
      <artifactId>caffeine</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.retry</groupId>
      <artifactId>spring-retry</artifactId>
    </dependency>

    <!-- production ready -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
      <groupId>io.micrometer</groupId>
      <artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>
    <dependency>
      <groupId>io.micrometer</groupId>
      <artifactId>micrometer-registry-jmx</artifactId>
    </dependency>

    <!-- logging -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>

    <!-- logstash layout -->
    <dependency>
      <groupId>com.vlkan.log4j2</groupId>
      <artifactId>log4j2-logstash-layout</artifactId>
      <version>${log4j2-logstash-layout.version}</version>
    </dependency>

    <!-- AspectJ -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
    </dependency>

    <!-- method Level Validation -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

    <!-- tests -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <groupId>org.skyscreamer</groupId>
          <artifactId>jsonassert</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <!-- JUnit -->
    <dependency>
      <groupId>org.junit.platform</groupId>
      <artifactId>junit-platform-launcher</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- JUnit 5 -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-params</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- JUnit 4 backward compatible -->
    <dependency>
      <groupId>org.junit.vintage</groupId>
      <artifactId>junit-vintage-engine</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- mock -->
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-inline</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- asynchronous systems testing -->
    <dependency>
      <groupId>org.awaitility</groupId>
      <artifactId>awaitility</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- devtool -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <optional>true</optional>
    </dependency>

    <!-- Spring configuration metadata for contextual help in IDE -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
      <optional>true</optional>
    </dependency>

  </dependencies>

  <build>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
          <include>**/*.yaml</include>
          <include>**/*.yml</include>
          <include>**/*.txt</include>
          <include>**/*.cql</include>
        </includes>
      </resource>
      <resource>
        <directory>src/main/config</directory>
        <filtering>false</filtering>
        <includes>
          <include>**/*.jks</include>
          <include>**/*.xml</include>
        </includes>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>src/test/resources</directory>
        <filtering>true</filtering>
      </testResource>
    </testResources>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compiler-plugin.version}</version>
        <configuration>
          <encoding>UTF-8</encoding>
          <source>${java.release.version}</source>
          <target>${java.release.version}</target>
          <annotationProcessors>
            <annotationProcessor>lombok.launch.AnnotationProcessorHider$AnnotationProcessor</annotationProcessor>
          </annotationProcessors>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>${spring-boot.version}</version>
        <configuration>
          <mainClass>${start-class}</mainClass>
        </configuration>
        <executions>
          <execution>
            <id>spring-boot</id>
            <goals>
              <goal>build-info</goal>
              <goal>repackage</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>${maven-resources-plugin.version}</version>
        <configuration>
          <encoding>UTF-8</encoding>
          <escapeString>\</escapeString>
        </configuration>
        <executions>
          <execution>
            <id>copy-jar</id>
            <phase>package</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${basedir}/target/appBundle</outputDirectory>
              <resources>
                <resource>
                  <filtering>false</filtering>
                  <directory>${basedir}/target</directory>
                  <includes>
                    <include>*.jar</include>
                  </includes>
                </resource>
              </resources>
            </configuration>
          </execution>
          <execution>
            <id>copy-config</id>
            <phase>package</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${basedir}/target/appBundle/.openshift</outputDirectory>
              <resources>
                <resource>
                  <directory>.openshift/stores</directory>
                  <filtering>false</filtering>
                </resource>
                <resource>
                  <directory>.openshift/params</directory>
                  <filtering>true</filtering>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>${maven-assembly-plugin.version}</version>
        <executions>
          <execution>
            <id>dist</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
            <configuration>
              <appendAssemblyId>false</appendAssemblyId>
              <descriptors>
                <descriptor>${basedir}/assembly.xml</descriptor>
              </descriptors>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>pl.project13.maven</groupId>
        <artifactId>git-commit-id-plugin</artifactId>
        <version>${git-commit-id-plugin.version}</version>
        <executions>
          <execution>
            <phase>validate</phase>
            <goals>
              <goal>revision</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <generateGitPropertiesFile>true</generateGitPropertiesFile>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven-surefire-plugin.version}</version>
        <configuration>
          <argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
          <excludes>
            <exclude>*Validation.java</exclude>
          </excludes>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>${maven-failsafe-plugin.version}</version>
      </plugin>
      <plugin>
        <groupId>com.theoryinpractise</groupId>
        <artifactId>googleformatter-maven-plugin</artifactId>
        <version>${googleformatter-maven-plugin.version}</version>
        <dependencies>
          <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-core</artifactId>
            <version>3.8.1</version>
          </dependency>
          <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-settings</artifactId>
            <version>3.8.1</version>
          </dependency>
        </dependencies>
        <executions>
          <execution>
            <id>reformat-sources</id>
            <configuration>
              <includeStale>true</includeStale>
              <style>GOOGLE</style>
              <formatMain>true</formatMain>
              <formatTest>true</formatTest>
              <filterModified>false</filterModified>
              <skip>false</skip>
              <fixImports>true</fixImports>
              <maxLineLength>100</maxLineLength>
            </configuration>
            <goals>
              <goal>format</goal>
            </goals>
            <phase>process-sources</phase>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>com.cosium.code</groupId>
        <artifactId>git-code-format-maven-plugin</artifactId>
        <version>${git-code-format-maven-plugin.version}</version>
        <executions>
          <!-- On commit, format the modified java files -->
          <execution>
            <id>install-formatter-hook</id>
            <goals>
              <goal>install-hooks</goal>
            </goals>
          </execution>
          <!-- On Maven verify phase, fail if any file (including unmodified) is badly formatted -->
          <execution>
            <id>validate-code-format</id>
            <goals>
              <goal>validate-code-format</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <googleJavaFormatOptions>
            <aosp>false</aosp>
            <fixImportsOnly>false</fixImportsOnly>
            <skipSortingImports>false</skipSortingImports>
            <skipRemovingUnusedImports>false</skipRemovingUnusedImports>
          </googleJavaFormatOptions>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>${maven-enforcer-plugin.version}</version>
        <executions>
          <execution>
            <id>enforce-rules</id>
            <goals>
              <goal>enforce</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <rules>
            <banDuplicatePomDependencyVersions />
              <requireJavaVersion>
                <version>${java.release.version}</version>
              </requireJavaVersion>
            <!-- 
              <requireMavenVersion>
                <version>(3.8.0,3.9)</version>
                <message>Invalid Maven version. It should be 3.8.x</message>
              </requireMavenVersion>
             -->
            </rules>
          </configuration>
      </plugin>
    </plugins>
  </build>

  <profiles>
    <profile>
      <id>local</id>
      <activation>
        <os>
          <family>!unix</family>
        </os>
      </activation>
      <properties>
        <parent_property>PARENT_PROPERTY_LOCAL</parent_property>
        <EPAAS_ENV>e1</EPAAS_ENV>
        <log.file.location>${local-log-location}</log.file.location>
        <springboot.profiles>${app.id},e0</springboot.profiles>
      </properties>
      <build>
        <finalName>app</finalName>
      </build>
    </profile>
    <profile>
      <id>server</id>
      <activation>
        <os>
          <family>unix</family>
        </os>
      </activation>
      <properties>
        <parent_property>PARENT_PROPERTY_SERVER</parent_property>
        <log.file.location>${server-log-location}</log.file.location>
        <springboot.profiles>${app.id}</springboot.profiles>
      </properties>
      <build>
        <finalName>app</finalName>
      </build>
    </profile>
    <profile>
      <id>server-lib</id>
      <properties>
        <parent_property>PARENT_PROPERTY_SERVER_LIB</parent_property>
        <log.file.location>${server-log-location}</log.file.location>
        <springboot.profiles>${app.id},e0</springboot.profiles>
      </properties>
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>${maven-resources-plugin.version}</version>
            <configuration>
              <encoding>UTF-8</encoding>
              <escapeString>\</escapeString>
            </configuration>
            <executions>
              <execution>
                <id>copy-jar</id>
                <phase>none</phase>
              </execution>
              <execution>
                <id>copy-config</id>
                <phase>none</phase>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring-boot.version}</version>
            <executions>
              <execution>
                <id>spring-boot</id>
                <phase>none</phase>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>${maven-assembly-plugin.version}</version>
            <executions>
              <execution>
                <id>dist</id>
                <phase>none</phase>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>

  <scm>
    <connection>scm:git:https://stash...</connection>
    <developerConnection>scm:git:https://stash....</developerConnection>
    <tag>HEAD</tag>
  </scm>
  <distributionManagement>
    <repository>
      <id>corporate</id>
      <url>dav:https://.../</url>
    </repository>
    <snapshotRepository>
      <id>snapshots</id>
      <url>dav:https://.../</url>
    </snapshotRepository>
  </distributionManagement>
</project>

assembly.xml

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>bin</id>
    <formats>
        <format>tar.gz</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/appBundle</directory>
            <outputDirectory>.</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>



> README FILE

---

## An Spring Boot based application targets OpenShift deployment.

* The parent POM provides dependency definitions and dependencies management for most commonly used d Spring Boot features.
* This POM also provide Maven plugins and their configurations to be used by Jenkins builds that target OpenShift deployments and releases.

### Out-of-box Features:

- Spring Boot
- Spring MVC over Tomcat - REST endpoints
- Spring Actuator - production-ready features
- MicroMeter over Prometheus - metrics
- Log4j over slf4j
- Log4j MDC - mapped diagnostic contexts
- Lombok integration
- Cache with Spring/Caffeine
- Spring Bean Validation - entity and service validation
- ePaaS Vault integration - password management

- JUnit 4&5 integration
- Awaitility integration
- Mockito integration

- git-commit-id-plugin
- spotless code formatter

### Usage

#### Maven Profiles
There are 3 Maven profiles defined:

1. local: build a Spring Boot based package locally.
2. server: build an OpenShift release
3. server-lib: build a re-usable library as jar

#### Build parent POM and install it to local Maven repository

```
mvn -Pserver-lib,!local clean install
```


No comments:

Post a Comment