How To Use CircleCI Java CI/CD Pipeline

Oleksii Dushenin
5 min readSep 18, 2021

--

In a How To Analyze Java Application With SonarQube post, SonarQube was presented as a major tool for static code analysis. In this post, CI/CD pipeline example will be reviewed. There are a lot of CI/CD tools. Some of the examples are Jenkins, CircleCI, TeamCity, etc. Each of them can be used as a tool to build your CI/CD pipeline. In this article, CircleCI will be used to create a simple pipeline for a Java application.

Java Application

In order to show the usage of CircleCI, a java application is required. A very simple application with one Java class will be used.

package com.datamify.development.ci;

public class Element {

private final int value;

public Element(int value) {
this.value = value;
}

public Element add(Element element) {
return new Element(this.value + element.value);
}

public int getValue() {
return this.value;
}

}

It was covered with a single test.

package com.datamify.development.ci;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class ElementTest {

@Test
void shouldTestAddElement() {
final Element firstElement = new Element(5);
final Element secondElement = new Element(7);

final Element resultElement = firstElement.add(secondElement);
assertEquals(resultElement.getValue(), 12);
}

}

CircleCI Java pipeline can be used to validate your code based on predefined rules. It can be done at various stages of application development. The most commonly used approach is to verify your code on a pull request level in order to simplify a code review process. Also, applications can be built and deployed on a server to serve the application requests.

In this post, CircleCI will be used to check the source code on each commit:

  • Build should not have failed tests.
  • Test coverage is checked with Jacoco.
  • Code analysis is performed by PMD.
  • Code style checks are executed with CheckStyle.

Configuration details can be found in previous posts. The final build.gradle has the next form:

plugins {
id 'java'
id 'jacoco'
id 'pmd'
id 'checkstyle'
}

group 'com.datamify'
version '1.0-SNAPSHOT'

repositories {
mavenCentral()
}

dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
}

test {
useJUnitPlatform()
finalizedBy jacocoTestReport
}

jacocoTestReport {
dependsOn test
reports {
html.required = true
}
}

jacocoTestCoverageVerification {
violationRules {
rule {
limit {
minimum = 0.8
}
}
}
}

pmd {
consoleOutput = true
toolVersion = "6.21.0"
rulesMinimumPriority = 5
}

checkstyle {
toolVersion '8.40'
ignoreFailures true
}

tasks.withType(Checkstyle) {
reports {
xml.required = true
html.required = true
}
}

check.dependsOn jacocoTestCoverageVerification

CircleCI Java Configuration

CircleCI needs configuration to create a CI/CD pipeline. It is specified in .circleci/config.yml file.

In our case, it will be a very simple configuration.

version: 2.1
jobs:
build:
docker:
- image: cimg/openjdk:11.0.12

environment:
JVM_OPTS: -Xmx3200m

steps:
- checkout

- run: ./gradlew clean build

- store_test_results:
path: build/test-results

- store_artifacts:
path: build/reports/tests/test
destination: test_result

- store_artifacts:
path: build/reports/jacoco
destination: test_coverage

- store_artifacts:
path: build/reports/pmd
destination: pmd

- store_artifacts:
path: build/reports/checkstyle
destination: checkstyle

To begin with, the configuration version is specified. After that, the build job is configured. This job uses cimg/openjdk:11.0.12 docker image because our application uses 11 Java ( docker images details). After that Java virtual machine options can be specified.

version: 2.1
jobs:
build:
docker:
- image: cimg/openjdk:11.0.12

environment:
JVM_OPTS: -Xmx3200m

Secondly, each job consists of multiple steps.

At first, the repository is checked out from GitHub.

    steps:
- checkout

After that, the application is built. Note, that this command will download the required dependencies. It can be optimized with caching dependencies.

- run: ./gradlew clean build

The next step is required to view test result in CircleCI.

      - store_test_results:
path: build/test-results

After that reports (test execution, Jacoco, PMD, CheckStyle) are saved to the Artifacts section.


- store_artifacts:
path: build/reports/tests/test
destination: test_result

- store_artifacts:
path: build/reports/jacoco
destination: test_coverage

- store_artifacts:
path: build/reports/pmd
destination: pmd

- store_artifacts:
path: build/reports/checkstyle
destination: checkstyle

Details about CircleCI Java configurations can be found here.

CircleCI Java GitHub Configuration

CircleCI is integrated with GitHub. A free account can be created at CircleCI. You can log in with your GitHub account.

You will see repositories that can be set up.

In our case, we use a development-ci project. As a result, a correspondent Set Up Project can be used.

On the next screen, the CircleCI configuration has to be created or selected. In our case, it is already created.

The new build will be created on each commit. Consequently, you can see the list of your builds.

Each build has its details.

In the Steps tab, all executed steps can be reviewed.

In the Tests tab, it can be seen that the created test is successful.

And in the Artifacts tab, all generated reports can be viewed.

Summary

In this post, CircleCI was used as an example of a CI/CD pipeline tool for Java applications. It is usually used on each Pull Request in order to simplify the code review process and guarantee build stability. Look at CircleCI Documentation for more details.

The source code is available at Github.

Originally published at https://datamify.com on September 18, 2021.

--

--