A java template: build, report and deploy

Yves Callaert
4 min readSep 11, 2018

Template

Yes a template for a java repository to speed up the CI/CD part. Nothing exciting but while building my latest project there were some pieces of the puzzle that were missing and frustrating. If I had a template, it would have shaven a day off building the damn repo.

So I thought, why not make into a template and share the missing pieces of the puzzle.

The tools

To make it very brief, the template foresees solutions for the following technologies:

  • Jenkins
  • Kubernetes
  • Maven / Takari
  • Nexus
  • Sonarqube
  • Metrics & logstash

Takari

Takari is a tool that you can install if you need to use maven but it is not present on the target system. When you install the tool, it will install a wrapper with all the necessary functionality of maven inside the repository.

So how would you install it on your own repository ? It’s quite simple, make sure you are in the root folder of your project and execute the following command

mvn -N io.takari:maven:wrapper

After a couple of seconds the wrapper is installed and you can execute commands using the “./mvnw” executable.

Running a unit test will become

./mvnw test

Kubernetes

The repository foresees 2 templates for AKS. The first one is to create the namespace, the second one is to deploy the actual docker.

On the container part I did specify some resource limitations. Resource limitations can be specified with the following configuration

containers:
-
image: PROJECTCONTAINERREGISTRY/PROJECTNAME:__COMMIT_ID__
imagePullPolicy: Always
name: PROJECTNAME
resources:
limits:
cpu:
2000m
memory: 4096Mi
requests:
cpu:
500m
memory: 2096Mi

I would revise these values depending on the resources your project is consuming.

Jacoco and Sonarqube

As good developers we make sure we have 80% or more code coverage.

Or was it 50 😂 ?

Anyway, I used Jacoco to generate the reports and wanted to upload those reports to Sonarqube. It took me a while to get this configuration working properly.

So first let’s look at Jacoco. In the pom you will need to configure the Jacoco plugin both in the build and in the reporting section. Have a look in the repository for all configuration parameters.

On Jenkins we need to make sure that the Jacoco plugin has been installed. Next we can run the tests and create the reports.

stage ('Run unit test'){
steps {
sh './mvnw test'
step( [$class: 'JacocoPublisher',
exclusionPattern: '**/*Exception*,**/*Configuration*,**/ApiApplication*,**/*Test*'] )

}
}

If all is well Jenkins will now generate the reports. It will look something like this on the build page

Jacoco in jenkins

Now let’s put everything in Sonarqube so we can have a full report on our code there. In the root directory of the project we need to configure “sonar-project.properties”. The file will look like this

sonar.language=java

sonar.projectKey=DummyKey
sonar.projectName=DummyProject
sonar.projectVersion=1.0.0


sonar.sources=src/main/java
sonar.tests=src/test/java
sonar.binaries=target/

sonar.java.binaries=target/classes

sonar.jacoco.reportPath=target/coverage-reports/jacoco-unit.exec
sonar.java.coveragePlugin=jacoco
sonar.dynamicAnalysis=reuseReports
sonar.surefire.reportsPath=target/surefire-reports

In the Jenkins pipeline script we will trigger the build using the following commands

stage ('SonarQube analysis') {
steps {
script {
scannerHome = tool name: 'sonarqube', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
}
withSonarQubeEnv('sonarqube') {
sh "${scannerHome}/bin/sonar-scanner -X"
}
}
}

In my case we have configured the username and password inside of Jenkins so that we do not have to configure this for each build and expose it in the repositories.

If you then go to Sonarqube you will find a more in depth explanation of the coverage.

Sonarqube code coverage overview

Nexus

Don’t do manual versioning of JARs. Ever ! Please rely on a tool. No it doesn’t need to be nexus (a good alternative might be Artifactory) but let’s do Nexus for now as it rather widely used.

Let’s configure the pom first. First you will need to configure the distribution management by providing the url and telling maven what the release and the snapshot endpoint is.

<distributionManagement>
<repository>
<id>nexus</id>
<name>Releases</name>
<url>https://xxxxx</url>
</repository>
<snapshotRepository>
<id>nexus</id>
<name>Snapshot</name>
<url>https://xxxx</url>
</snapshotRepository>
</distributionManagement>

Next we will need “settings.xml”. Important in this file is the authentication. This is done by configuring the servers sections. You need to provide a username and password as given by your nexus administrator.

<servers>
<server>
<id>nexus</id>
<username>USERNAME</username>
<password>{ENCPASSWORD}</password>
</server>
</servers>

Please make sure to encrypt the password. The master encryption password goes into the “settings-security.xml”

Metrics

Part of the repository is also the “ProjectMetrics” class. I think it is always prudent to show how well your code is performing. These metrics can also be exported and you can create some fancy reports on top.

So how does it work?

The following snippet will give an insight on the metrics package.

public class ProjectMetrics {
private static final Logger log = LoggerFactory.getLogger(ProjectMetrics.class);

...
private final MetricRegistry metricRegistry;
private final Meter messageRate;

private ProjectMetrics() {
this.metricRegistry = new MetricRegistry();
messageRate = metricRegistry.meter("allMessages");

So basically we can create different types of metrics and couple them to the registry.

Next you can increase the message rate by calling the “mark” method for each message.

You can find the full usage description here.

Conclusion

Well I hope the repository gives you a good starting point or at least gives you some insights in the release part of java code. As always, the full repository can be found on my github page.

--

--

Yves Callaert

Senior Data Engineer who sometimes tries his hand at writing :)