Coding Continuous Delivery with Jenkins Pipelines

Starting in their 01/2018 issue, Java aktuell published my four-part articles series Coding Continuous Delivery in German. I’m happy to announce that all parts are now available in English, courtesy of Cloudogu.

The series takes you from zero to continuously delivering your software through a sophisticated Jenkins pipeline. It starts with the fundamentals, heading on to advanced topics such as nightly builds, parallel execution, docker, shared libraries, unit testing, static code analysis with SonarQube and deployment to Kubernetes. All of the topics are described hands-on with examples comparing the scripted with the declarative syntax provided by the Jenkins Pipeline Plugin.

  1. Jenkins pipeline plugin basics | 🖺 original article PDF (German)
  2. Performance optimization for the Jenkins Pipeline | 🖺 original article PDF (German)
  3. Helpful Tools for the Jenkins Pipeline | 🖺 original article PDF (German)
  4. Static Code Analysis with SonarQube and Deployment on Kubernetes et al. with the Jenkins Pipeline Plugin | 🖺 original article PDF (German)

The examples to all articles are contained in this GitHub repository: triologygmbh/jenkinsfile and the builds can be seen in action on this Jenkins server: opensource.triology.de.

My awesome colleagues at Cloudogu GmbH and Triology GmbH – thank you so much for your support. Especially my co-author from the first article, Daniel Behrwind, who got this whole thing started.

Advertisements

The pragmatic migration to JUnit 5

This article shows how get from JUnit 3.x / 4.x to JUnit 5.x as fast as possible.

Just a short clarification of the term “JUnit 5” (from the user guide) before we take off:

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

where

  • Platform provides the Maven and Gradle Plugins and is the extension point for IDE integration,
  • Vintage contains legacy JUnit 4 API and engine,
  • Jupiter contains the new JUnit 5 API and engine.

Step 1 – Run existing tests with JUnit 5 vintage

The first thing we do is to replace the existing junit:junit depedency with the following

<dependency>
	<groupId>org.junit.vintage</groupId>
	<artifactId>junit-vintage-engine</artifactId>
	<version>5.1.0</version>
</dependency>

For Gradle see this article.

For a real world example see this commit.

Note: After upgrading fromjunit:junit:4.12 to org.junit.vintage:junit-vintage-engine:5.1.0 the execution order of @Rule seems to have changed: They seem to be now executed sequentially (from top to bottom, as defined in the test class).

Step 2 – Getting started with JUnit Jupiter and the Platform

Now lets go from vintage to the fancy new stuff. Just add the Jupiter dependency and empower surefire to use the JUnit platform:

<dependency>
	<groupId>org.junit.jupiter</groupId>
	<artifactId>junit-jupiter-engine</artifactId>
	<version>5.1.0</version>
</dependency>

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-failsafe-plugin</artifactId>
	<!-- ... -->
	<dependencies>
		<dependency>
			<groupId>org.junit.platform</groupId>
			<artifactId>junit-platform-surefire-provider</artifactId>
			<version>1.1.0</version>
		</dependency>
	</dependencies>
</plugin>

Make sure to juse either surefire 2.19.1 or 2.21.0+, as there seem to be a bug in the versions in between.

As above, for Gradle see this article.

For a real world example see this commit.

As of now, we’re ready to write new tests with JUnit Jupiter.

Here’s a pragmatic aproach how to introduce JUnit 5 from here:

  • Use the new API and all the new features for new test classes.
  • Don’t try to migrate all existing tests. It causes a lot of effort with no direct business value.
  • Instead, apply the boyscout rule by gradually migrating existing tests before they need to be changed.

When getting started wiht JUnit Jupiter you will recognize that some familiar features of JUnit now have a new API or can be achieved using different concepts. After that, there are a some new features to explore.

One way to get accustomed to the new API and concrepts is to migrate some (not all) existing tests, preferably the most complex ones. This way, you will find out how to use the new concepts and which limitations there still might be about JUnit Jupiter (e.g JUnit 4 rules that have not been ported to extensions).

Step 3 – Get accustomted to the API changes in JUnit Jupiter

There are some simple API changes but also two major concept changes: Rules and Runners are gone.

Simple API changes

  • public modifier can be removed (class and methods)
  • org.junit.Test➡️ org.junit.jupiter.api.Test
  • org.junit.Assert.assertX ➡️ org.junit.jupiter.api.Assertions.assertX
    (except assertThat)
  • Order of parameters changed in assert methods. The message parameter is now after expected and actual parameters! This can be a pitfall when migrating, because the message (strings) might silently turn to expected, if you just change the import.
  • assertThat is no longer part of the JUnit API. Instead, just use your favorite assertion library as AssertJ, Google truth or even hamcrest.
  • @Before ➡️ @BeforeEach
  • @After ➡️ @AfterEach
  • @BeforeClass ➡️ @BeforeAll
  • @AfterClass ➡️ @AfterAll
  • @Ignore ➡️ @Disabled
  • @Category ➡️ @Tag

For a real world example see this commit.

Make sure to not mix the APIs, because the tests are either run by the Jupiter or the vintage Engine, which will ignore unknown annotations.

Note that IntellI has a quick fix for migrating JUnit 4 to JUnit Jupiter. However, as of version 2018.1 this seems to only affect @Test, no asserts, exceptions, rules or runners.

Advanced API changes

Basically, Runners and Rules are replaced by Extensions, where one test class can have more than one extension.
However, some Runners have not been ported to Extensions, yet. For those you can try to use@EnableRuleMigrationSupport (see Temporary Folders). If this does not work, you will have to stick with the JUnit 4 API and vintage Engine for now.

Exceptions & Timeouts

Exceptions no longer need a Rule or the expected param in @Test. Instead, the API provides an assert mechanism now.

ExpectedException and @Test(expected = Exception.class) ➡️ assertThrows(Exception.class,() -> method());

For a real world example see this commit.

The same applies to timeouts:

@Test(timeout = 1) ➡️ assertTimeout(Duration.ofMillis(1), () ->method());

Mockito

Instead of the mockito runner, we use the new extension, which comes in a separate module.

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>${mockito.version}</version>
</dependency>

@RunWith(MockitoJUnitRunner.class) ➡️ @ExtendWith(MockitoExtension.class)

For a real world example see this commit.

Temporary Folders

Until there is an Extension, we can use @EnableRuleMigrationSupport from this module:

<dependency>
	<groupId>org.junit.jupiter</groupId>
	<artifactId>junit-jupiter-migrationsupport</artifactId>
	<version>${junit5.version}</version>
</dependency>

With this we can use the new API (org.junit.jupiter.api.Test). Howerver, rules and classes must stay public. ClassRules seem not to work.

For a real world example see this commit.

Other Rules

Here are some more rules and their equivalent in JUnit Jupiter.

  • @RunWith(SpringJUnit4ClassRunner.class) ➡️ @ExtendWith(SpringExtension.class)
  • stefanbirkner/system-rules, such as ExpectedSystemExit
    Work in progress! That is, these tests will have remain on the JUnit 4 APIs for now.
  • TestLoggerFactoryResetRule from slf4j-test
    No progress to be seen.
    Could be replaced by logback-spike. For a real world example see this commit.
  • Of course this list is non-exhaustive, there are a lot more runners I have not stumbled upon, yet.

Step 4 – Make use of new features in JUnit Jupiter

Just using the same features with different API is boring, right?
JUnit Jupiter offers some long-awaited features that we should make use of!
Here are some examples:

Optional: Further Reading

More sutainable Android Software with Project Treble and 6-y LTS Kernels on Android O?

Recently, we could read and hear about Google putting some effort in facilitating easier updates for android devices:

So, even though three years are not the promised four years, we can still see a trend of increasing years of guaranteed software support on Android phones.

That is a positive trend! I hope that Google takes the gloves off soon and guarantees four upgrades to a new android version, forcing other vendors to at least start guaranteeing something for their phones. As I said before, this would really be a unique selling point. Also this would really mean a big leap forward regarding sustainability of Android phones! Let’s see if any of the Oreo Phones being release now will support Android S 😉

Android Logging for Java Professionals – SLF4J and Logback in Android

One of my articles was published in Java Magazin 9.17. I wrote it while working on the nusic android app, about how to use SLF4J in Android using logback-android. It also features an example and a small library for android.

Triology GmbH provides an English version of this article, and also acquired the original article PDF (in German), which can be found here: Android Logging für Java-Profis – SLF4J und Logback in Android. I’d like to thank my colleagues there for their support.

Android 7 (Nougat) on a 5-year-old phone

A 5-year-old phone is not going to the kindergarden, it is more likely to be found on the phone graveryard. One important reason for this is that its manufacturer stopped caring for it at least three years ago. Fortunately, there are other caretakers – people that maintain the latest android version also for five-year-old phone grannies – in form of custom ROMs.
So, is it possible to run the latest Android version on a device that’s 5 years old? Hell, yes! This article shows how.

My old HTC One S (aka ville, the older S4 processor not the “C2” with S3 processor), launched April 2012 runs terribly laggy on its latest stock anroid 4 firmware, last update 2013 – four years ago! That’s why it was retired a long time ago. At the beginning of 2017, when the first unofficial builds of lineage OS turned up, I was surprised to see that HTC One S was among them. I was wondering, how can such an old device run the latest android version? I had to see for myself.

TLDR; Android Nougat works surprisingly well, way better than the latest Stock version but HTC makes it a hell of a way to get there. Lets see what has to be done.

Note that all files on your device will be deleted during the process!

Unlock Bootloader

To be able to flash software to our HTC devices, HTC forces us create an account on htcdev.com and register our device there. Then we receive an unlock code as zip file which we can flash on our device.


adb reboot bootloader

fastboot flash unlocktoken Unlock_code.bin

For all Windows 8 (and also Windows 10, apparently) users who have problems getting the fastboot driver to work, whereas ADB works, this little registry edit did the trick for me.

In the bootloader make sure to remember your HBoot version, it will be required during the process.

HBoot 2.16 - we're good!

HBoot 2.16 – we’re good!

Flash TWRP

Download from here to your PC and flash as follows


fastboot flash recovery twrp.img

fastboot reboot

Check HBoot version

I had to find out the hard way by flashing lineage 14.1 that there are requirements regarding the HBoot (HTC Bootloader) version:  HBoot 2.16 is required.

So better check in advance. If you’re on HBoot 2.16 flash lineage and enjoy. If not, let the games beginn.

S-OFF & root

Upgrading HBoot needs S-OFF (Security off, enables writing to /system directory). On top of unlocking our bootloader at htcdev.com we need to risk bricking our phone to enalbe writing in the /system directory of our device.
Those two things are the reasons why I most likely won’t ever buy an HTC device again.
Anyway, with the One S, we’re lucky! S-OFF takes a bit of time but not much effort and comes at almost no risk, thanks to rumrunner (a good overview of other S-OFF Mechanisms is described here). Rumrunner makes it easy to get S-OFF, but it needs root access.

What? Why are we doing this again? We want to Upgrade HBoot, that’s why we need S-OFF, in order to get S-OFF, we need root. That’s the last unpleasant surpise, promise!
Lucky again, root access can be gained easily on HTC One S. I used Superboot: Just Download, execute Script on PC while Phone phone is in bootloader mode. Root done. More detailed description here.

Then just download rumrunner follow the instructions, wait for about 10 minutes (don’t worry, your phone is restarting about one million times) and you’re S-OFF!

Upgrade HBoot

We’re getting closer. Now, with S-OFF we can flash HBoot 2.16. I followed these instructions, and found the firmware here.

Caution: After flashing HBoot 2.16, the internal memory is really small, only 50 MB left. Obviously Android 4 and Hboot 2.16 are not good friends. Don’t worry, this is solved once Android 7 is flashed.

Flash Android 7.1.2

It’s finally gonna happen. We’ll flash Lineage 14.1, Android 7.1.2 (maintained by moozon, thanks so much!). But how, the internal memory is only 50MB, but the image is almost 300MB? I copied the image to an USB thumb drive, connected it to the phone via an USB OTG adapter and flashed via TWRP Recovery. TWRP also offers ADB sideloading, which might be an alternative, it you don’t have an USB OTG Adapter at hand.

Once flashed, you finally can enjoy the latest android version on your “antique” phone. 🥂

Optional finishing and more info

Root is built-in but disabled by default. If you want root access, you can enable it in developer options.

If you need google services, get ARM | 7.1 | pico (my recommendation) from opengapps.org and flash via TWRP.

If you need more info, you might get started here: [LINEAGE OS] HTC One S Lineage OS 14.1, Android Nougat 7.1 ROM

Final thoughts

The One S with Android 7.1.2 almost works better than my HTC One M8 with Android 6! Why must HTC make it so hard to get there? And why are manufacturers not able to support their devices longer than 2 years, while the community or even single indivudals are able to do so for more than 5 years??

[EDIT 2017/06/13: Google just published the guaranteed updates for its devices: two years of upgrades and another year of security updates. While this is at least some formal guarantee (other manufacturer just don’t guarantee anything) it still is far from the five years provided by the community for my HTC One S… ]

I’m still waiting for a manufacturer that guarantees support for its devices for many years. That would really be a unique selling point! I can’t believe no manufacturer uses this USP on the highly competitive market for mobile devices. In addition, this would be so much more sustainable, and contribute to a green(er) IT. While the whole world complaints about planned obsolescence, why is there no manufacturer that uses this fact for positive marketing?

[EDIT 2017/07/01: HMD Global (owner of the Nokia brand) just announced that they intend to provide plain vanilla android phones with support “even after two years“. I looking forward to their next anouncements. My calls might just have been heard 👂]

[EDIT 2017/10/05: Google talks about four android version upgrades being possible from Android O and releases Pixel 2 with three years of support. See More sutainable Android Software with Project Treble and 6-y LTS Kernels with Android O?]

What is Google doing, by the way? They introduce Safety Net, providing the oportunity for developers to hide their apps on Google Play from specific devices, such as the ones running custom ROMs. So now, no more Netflix, etc. for custom ROMs. Effectively, this is another punch for the custom ROM scene after the death of CyanogenMod.

Lets just hope custom ROM developers will not be discouraged by these facts and continue their imporant work, making success stories such as the one of my HTC One granny possible.

Thank you android community, XDA forums, custom ROM developers, etc. for sharing your work and never giving up! 👍

Automatic checks for vulnerabilities in Java project dependencies

 Java aktuell published an article I wrote on a topic at work for TRIOLOGY GmbH.

You can find an English version on the TRIOLOGY Blog: Automatic checks for vulnerabilities in Java project dependencies. The article shows an approach to keeping your Java project dependencies free of known vulnarabilities (e.g. CVEs) using the OWASP Dependency check with Jenkins and Maven. There also is an example project on GitHub.

The original article PDF (in German) is available for download here: Automatisierte Überprüfung von Sicherheitslücken in Abhängigkeiten  von Java-Projekten.

TRIOLOGY also published a short Q&A on the article, which can be found here.

Maven: Create a more sophisticated build number

Earlier this year, while working on a project for TRIOLOGY GmbH, I once again used maven to write a version name into an application, using the mechanism described in my post Maven: Create a simple build number. As a more sophisticated version name was required for this project, we expanded it by a time stamp, SCM information (branch and commit), build number and a also created a special name for releases. You can find a how-to here – Version names with Maven: Creating the version name – which is the first part of a small series of blog posts on this topic.

The second part shows how the version name can be read from within the application. While writing the examples for the post, I wondered how many times I must have implemeted reading a version name from a file in Java. Way too often! So I decided that this would be the very last time I had to do it, and extracted the logic into a small library: versionName, availble on GitHub. What it does and how to use it is described in the second part of the post: Version names with Maven: Reading the version name.

Hopefully, this will be useful for someone else. Funny enough, in the new project I’m on, I’m about to reuse it once again. I’m glad I don’t have to write it again. Here’s to reusability 🍺