0% found this document useful (0 votes)
1 views32 pages

JAX - London - Whitepaper Java Fresh Brewed 2022

The JAX London Whitepaper explores the evolution of Java in a cloud-centric world, focusing on topics such as Kotlin's advantages over Java, app testing, garbage collection, and modern Java runtimes. It features articles from various experts discussing the latest Java features, microservices, and DevOps practices. The document serves as a resource for developers to enhance their Java knowledge and prepare for the JAX London 2022 conference.

Uploaded by

htdvul
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views32 pages

JAX - London - Whitepaper Java Fresh Brewed 2022

The JAX London Whitepaper explores the evolution of Java in a cloud-centric world, focusing on topics such as Kotlin's advantages over Java, app testing, garbage collection, and modern Java runtimes. It features articles from various experts discussing the latest Java features, microservices, and DevOps practices. The document serves as a resource for developers to enhance their Java knowledge and prepare for the JAX London 2022 conference.

Uploaded by

htdvul
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

Evolving Java:

New powers, freshly brewed

JAX London Whitepaper


Learn all about Java for a cloud-centric
world, app testing, garbage collection,
and how Kotlin compares.

jaxlondon JAX London JAXLondonConference

jaxlondon.com
© LoopAll/Shutterstock.com
DOSSIER Microservices

Contents

Editorial3

Java Core & JVM Languages


Kotlin – the better Java?  4
By Moritz Kammerer
Getting Started with the DataStax Astra Java SDK  11
By Cédrick Lunven
Unleashing new Java powers  15
By Michael Simons

Agile, People & Culture


No Honeycomb Testing and Mocks?
You’re Probably Getting App Testing Wrong  17
By Nate Lee

Microservices & Service Mesh


An introduction to JobRunr, a distributed background job
scheduler  20
By Ronald Dehuysser

Cloud, Kubernetes, Serverless


Evolving Java Runtimes for a Cloud-Centric World  24
By Gil Tene

DevOps & Continious Delivery


Time to Modernize Ops  27
By Lori MacVittie

Software Architecture & Design


Garbage Collection tuning success story –
reducing young gen size  29
By Ram Lakshmanan

jaxlondon.com 2
Editorial

Let’s have another cup of


Java!
Just like developers after a cup of freshly brewed coffee, Java is
energetic, bold, and still going strong. The excitement is ramping
up as the date gets closer and closer; are you ready for JAX London
2022? Get prepared for your visit (either remotely from your home
or on-site) and brush up your Java knowledge with these articles
from Java experts about the JDK, software architecture, DevOps,
Java runtimes on the cloud, and more.
Will relative newcomer Kotlin replace Java anytime soon, or will
the old workhorse endure? Moritz Kammerer discusses some dif-
ferences between the languages, their advantages, and pain points
with examples in his article “Kotlin - the Better Java?”. Learn all
Sarah Schlothauer about the latest Java features with Michael Simons and discover
Editor how to utilize their powers in your next project. Continue your
Java journey with an introduction to JobRunr from Ronald De-
huysser, where you’ll learn all about this distributed background
job scheduler. Keep your projects nice and tidy by learning about
Garbage Collection in Java with Ram Lakshmanan in “Garbage
Collection Tuning Success Story – Reducing Young Gen Size”.
All this and more in this issue of JAX London Whitepaper. It’s
good to the last drop!
Happy reading!

Sarah Schlothauer

@jaxlondon

jaxlondon.com
WHITEPAPER Java Core & JVM Languages

An introduction to the modern programming language Kotlin

Kotlin –
the better Java?
The Kotlin programming language saw the light of day in February 2016 with version 1.0.
In 2019, Google declared Kotlin the “first-class citizen“ of Android development, helping
it achieve a breakthrough. But what makes Kotlin special? Why is it worth taking a look at
even for Java veterans who have nothing to do with Android? This article will cover this
and other questions.

By Moritz Kammerer Java. The Kotlin compiler generates bytecode for the
JVM (Java Virtual Machine). So, programs written in
First off: I am not a Kotlin fanboy and I think Java Kotlin can be executed with a standard Java installa-
is a very successful programming language. My dai- tion. The only requirement is a JVM that is at least
ly work revolves around backend development on the version 1.6.
JVM, mainly in Java. However, I think it’s fine to think In comparison to Java, Kotlin markets itself as being
outside the box more often and look at newer langua- “concise”, without much boilerplate code. Kotlin code
ges on the JVM. This article assumes that you already is around 40 percent shorter than comparable Java code
“speak” Java, and shows some interesting Kotlin fea- and is much more expressive [1]. Kotlin also has an im-
tures from this point of view. I will focus on what I proved type system, which is mainly aimed at avoiding
consider to be the most important features of Kotlin: NullPointerExceptions. But let’s take a closer look at
functions, variables, null safety, object-oriented pro- these promises.
gramming, functional programming, and interopera- We start with a classic “Hello World”:
bility with Java.
Kotlin is developed as open source software by Jet- package javamagazine
Brains under the Apache 2.0 license. JetBrains also dis-
tributes the well-known IDE IntelliJ IDEA, which has fun main(args: Array<String>) {
good support for Kotlin. There are also plug-ins for Ec- print("Hello world")
lipse and NetBeans. Kotlin has been under development }
since 2010, but only gained some popularity in 2016
with version 1.0. Just like Java, Kotlin code is managed in packages. In
The final breakthrough, at least in Android develop- the above example, you will immediately notice that it
ment, came in 2019 when Google declared Android de- isn’t necessary to create a class to define the main func-
velopment “Kotlin-first” at Google I/O. tion.
Kotlin is a modern, statically typed programming Functions are declared with the keyword fun (short
language that combines concepts from object-oriented for “function”). For the parameters, first the name of
and functional programming. Special attention is paid the parameter (args), then its type (Array<String>) is
to compatibility with Java code – this is also one of specified. It’s exactly the opposite of Java. Arrays are
the differentiating features between Kotlin and Scala. expressed as generic types and not with square brackets
Developers can easily use Java libraries in Kotlin and after the type (for example: String[]), as it is in Java.
do not have to convert data types, such as lists, for ex- You don’t need semicolons after statements in the
ample. It’s also possible to use Kotlin code from within function body. They are optional in Kotlin. The func-

jaxlondon.com 4
WHITEPAPER Java Core & JVM Languages

tion contains a function call of print(...) without object Type inference also works when several variables are
instance. So, it is possible to call functions without an used together. In the example, the result type of the +
associated object instance in Kotlin. There are several operator determines the type of the variable sum (Int).
functions in the standard library that do not belong to In the print(...) statement I used another feature of
any class. Here, print(...) is an abbreviation for System. Kotlin, called string interpolation. It embeds the varia-
out.print(...), which probably looks familiar. If you exe- bles operand1, operand2, and sum into a string. When
cute this code, “Hello World” appears on the console, the program is executed, 1 + 2 = 3 appears on the con-
as expected. sole.
The first line in Listing 2 declares a function named
Type interference and functions sum. The modifier private indicates that the function
In Listing 1, variables are declared with the keyword can only be used in the same file. The return type of the
val. Kotlin can determine the type of the variable auto- function is also specified, here it is Int. The return type
matically by type inference (in this case Int is the Kotlin is specified with a colon after the parameter declaration.
equivalent of Java’s int). But if you don’t like this, you In the example, the short notation for functions is also
can explicitly specify the type separated by a colon: val used, which doesn’t use curly brackets. It is introduced
operand1: Int = 1. Variables defined with val are au- directly with = after the signature. This notation can be
tomatically immutable, similar to final in Java. Further used for all functions consisting of only one line of code.
assignments would trigger a compile error. You should The operand2 parameter is also set to 0 by default, me-
make as much as you can immutable: This is an impor- aning the caller does not have to specify it explicitly.
tant concept in Kotlin. Optional parameters are a feature many Java developers
have always wanted.
In the main function, you see the call to sum first with
arguments 1 and 2 are explicitly set. The second call
Listing 1
to the sum function omits the second argument so that
fun main(args: Array<String>) { the default value of the parameter (0) is used. When the
val operand1 = 1 code runs, the console shows:
val operand2 = 2
val sum = operand1 + operand2 1+2=3
1+0=1
print("$operand1 + $operand2 = $sum")
} Null Safety
In my opinion, the best Kotlin feature is the improved
null handling. A common error in (Java) programs is the
NullPointerException. This happens when a variable
Listing 2 contains null, but the developer did not handle the case
private fun sum(operand1: Int, operand2: Int = 0): Int = operand1 + and accessed the variable anyway. Kotlin prevents this
operand2 by extending the type system: nullable variables have a
different type than variables that cannot be null. This
fun main(args: Array<String>) { example illustrates this more clearly:
val result1 = sum(1, 2) Listing 3 declares a function that takes three parame-
println("1 + 2 = $result1") ters: firstName of type String, midName of type String?

val result2 = sum(1)


println("1 + 0 = $result2")
}

Every performance feature since


Listing 3
Java 11
fun formatName(firstName: String, midName: String?, lastName: String): Jack Shirazi (Elastic)
 String { In my talk, I’ll cover all the performance
var result = firstName.toLowerCase() and memory-related changes since
result += midName.toLowerCase() Java 11, now available in Java 17, and
result += lastName.toLowerCase() how to use those features. I’ve chosen
these two release points because Java 17 is the
recently released LTS (long term support) version, and
return result
Java 11 was the previous LTS version.
}

jaxlondon.com 5
WHITEPAPER Java Core & JVM Languages

and lastName of type String. The type String? is not a String? (nullable) to String (non-nullable). This concept
typo. It’s Kotlin’s syntax for a nullable string. When a is what Kotlin calls Smart Casts. It can be found in other
type ends with a question mark, it means that null is al- places, such as Typecasts. The call to the function can
lowed as a value. If there is no question mark at the end now take place like this:
of the type, then null is not a valid value for it.
The variable result was declared with the keyword var val name = formatName("Moritz", null, "Kammerer")
– this means that the variable is mutable (the opposite val name2 = formatName("Moritz", "Matthias", "Kammerer")
of immutable). val name3 = formatName(null, "Matthias", "Kammerer")
Listing 3 also contains an error that Kotlin detects,
preventing a NullPointerException. If the midName is Line 1 sets the midName to null, which is allowed by
null, calling the toLowerCase() function will cause a the type String? Line 2 sets the midName to Matthias.
NullPointerException. Line 3 does not compile because the type of the first
Since Kotlin knows that midName can be null (by parameter is String - and null is not allowed as a value
type String?), the error is detected at compile time and for String.
compilation is aborted. Kotlin’s null handling is not just allowed for reference
In order to be able to compile the code, you will need types, but also for primitive types such as int, boolean
the change contained in Listing 4. etc. Unlike Java, Kotlin does not distinguish between
The if now “proves” to Kotlin that the developer has primitive and reference types - so it is also possible to
handled the null case, and that the call toLowerCase() call functions on int, boolean functions, etc. (Listing 5).
function is possible within the if. In the type system, the By the way, the types of the variables in the example
variable midName in the if block has changed type from are Int, Boolean and Double - there are no lowercase
variants like int, boolean, or double like there is in Java.
If necessary, the compiler takes care of autoboxing.
Now, let’s take a look at what Kotlin has to offer in
Listing 4 terms of object orientation.
fun formatName(firstName: String, midName: String?, lastName: String):
 String { Object-oriented programming in Kotlin
var result = firstName.toLowerCase() Listing 6 defines a new class called Square. This class
if (midName != null) { has a property length of type Int, which is immutable.
result += midName.toLowerCase() A property is the combination of a field and its access
} functions. Kotlin automatically generates a getter func-
result += lastName.toLowerCase() tion and a constructor parameter for length. If you used
a var instead of val, then Kotlin would generate a setter
return result function, too. The area() function is also defined, which
} uses the length property to calculate the area.
Interestingly, this class is automatically public, so a
missing modifier means public, and not package protec-
ted as it does in Java. Additionally, the class is automati-
Listing 5 Listing 6 cally marked as not inheritable (final in Java). If you do
val count = 1 class Square(val length: Int) { want this, then you can use the keyword open. A caller
val enabled = true fun area(): Int = length * can now use the class like this:
val percentage = 0.2 length
} val square = Square(4)
println(count.toString()) val length = square.length
println(enabled.toString()) val area = square.area()
println(percentage.toString()) println("Length: $length, Area: $area")

Line 1 creates a new instance of the Square class with


length = 4. Kotlin doesn’t have a new keyword, which I
Listing 7 think is a bit of a shame. I’ve often searched Java code
abstract class Shape { for new to find object instantiations. Of course, an IDE
abstract fun area(): Int would also help out here. But with code reviews on Git-
} Hub or GitLab, for example, you don’t necessarily have
that.
class Square(val length: Int): Shape() { Properties are simply accessed using the dot operator,
override fun area(): Int = length * length analogous to field access in Java. Under the hood, the
} getter function is called. Calls to functions look exactly
like they do in Java.

jaxlondon.com 6
WHITEPAPER Java Core & JVM Languages

Listing 7 shows an inheritance hierarchy: the Square companion object {


class inherits from the abstract Shape class, which defi- fun create() : Square = Square(5)
nes an abstract function called area() that is implemen- }
ted in Square. }
In Kotlin, there is no extends keyword; you use a co-
lon. Additionally, override is a keyword, instead of an The static functions of the class, in this case, create(), are
annotation as it is in Java. It is also possible to define in a companion object. The method of calling it looks
several public classes in a file and give the file a random like static in Java.
name. In some situations, this has its advantages, but it
can also lead to disadvantages, like more difficult code val area = Square.create()
navigation. Kotlin’s coding conventions recommend
that if the classes semantically belong together and the Personally, I think the solution with the companion ob-
file does not have too many lines, then it is okay to write ject is a bit strange, and I’m not alone in this [3]. The
the classes in one file [2]. designers’ justification for this decision is that there are
Interestingly, Kotlin does not know the keyword sta- top-level functions and you hardly need static functions
tic. So, no static functions can be defined, and instead, anymore. A companion object is a full-fledged object,
the two concepts of singletons and companion objects so it can also implement interfaces and be stored in a
take their place. A singleton, called an object in Kotlin, reference, for example.
is a class that cannot be instantiated and exactly one On the other hand, I think the behavior of if, try, etc
instance always exists: is solved excellently. These control structures are state-
ments in Java, not expressions. The difference is that
object FixedSquare: Shape() { a statement is a piece of code that has no return type,
override fun area(): Int = 25 while an expression returns a value. How many times
} have we written code like this in Java:

Singletons are defined with the keyword object and boolean green = true;
callers do not need to (and cannot) create instances of String hex;
them. The function call looks like a call to a static func- if (green) {
tion in Java: hex = "#00FF00";
} else {
val area = FixedSquare.area() hex = "#FF0000";
Now, If you want to equip a class with a "static" function, it looks like: }
class Square(val length: Int): Shape() {
override fun area(): Int = length * length The problem here is that in Java an if cannot return a
value. Java solves this problem, but only for if, with the
ternary operator ? (e.g. String hex = green ? “#00FF00”
: “#FF0000”). In Kotlin, this operator is not needed
(Listing 8).
The concept is not limited to if, it also works with try-
catch (Listing 9).
Here the function toInt() is called on the string input.
Cool New Java Features Workshop:
If input is not a valid Integer, then the function throws a
Best of Java 17 with a Java 19 Update
NumberFormatException. The exception is caught with
Michael Inden (Adcubum AG) the enclosing try-catch, which returns -1 in the event of
Michael Inden is an Oracle-certified
Java developer who holds a degree in
computer science. After completing his
studies in Oldenburg, he worked as a Listing 8
software developer and architect for various inter-
national companies and currently works as Head of val green = true
Development for Adcubum in Zurich. Michael Inden val hex = if (green) {
has over 20 years of experience in designing complex "#00FF00"
software systems and has participated in various train- } else {
ing courses and Java One conferences in San Fran- "#FF0000"
cisco. He likes to pass on his knowledge as a trainer in
}
training courses and at conferences. He is particularly
interested in the design of high-quality applications
with ergonomic, graphical user interfaces as well as in // Or shorter:
coaching colleagues. val hex = if (green) "#00FF00" else "#FF0000"

jaxlondon.com 7
WHITEPAPER Java Core & JVM Languages

an error. Since try-catch is an expression, it returns a va- this example, the string that is transformed), then the
lue. So, the value (either the integer value of the string or name of the parameter is not necessary. In this case, if
-1 in case of an error) is assigned to the variable result. you want to access the parameter, you can use the vari-
I miss this feature a lot in Java. In fact, Java 12 brought able named it.
something similar with switch expressions. Speaking of After the map function, the filter function will only
exceptions, unlike Java, Kotlin does not have checked select the strings beginning with an S. The result of this
exceptions. whole pipeline is stored in the variable namesWithS. The
In Listing 9, the toInt() function is called on a string. type of this variable is also List<String>. Unlike Java,
This function does not exist in the JDK on the String the functional operators work directly on lists, sets, etc.,
class. So where does it come from? The solution to our and not on streams, which then have to be converted
mystery is called extension functions. to lists, sets, etc. If you want the same behavior as Java
streams, especially the lazy evaluation, then Sequences
Extension Functions are available.
In Kotlin, you can extend functions to any types, even if In the last line, a Lambda is defined with an explicit
they are not defined in your own code. parameter name of name. The names are output on the
console:
private fun String.isPalindrome(): Boolean {
return this.reversed() == this sebastian
} stephan

In the above example, the isPalindrome() function is de- Other functional constructs such as zip, reduce, and
fined on the String type. This function returns true if the foldLeft can also be used with Kotlin via predefined
string is a palindrome. A palindrome is a word that can functions (Listing 11).
be read both from the front and the back, for example: Listing 11 creates a list of type List<Pair<String,
“Anna” or “Otto”. String>> from two lists (Type List<String>) using the
The string to be checked can be found in the reference zip function. Kotlin already brings along a few ge-
this. Unlike Java, in Kotlin, strings (and all other ob- neric container types such as Pair, Triple, etc. If you
jects) can be compared using the == operator. In Kotlin,
the == operator calls equals() and does not compare the
references of the objects, as it does in Java. If you need
the reference comparison in Kotlin, the === operator
Listing 9
exists. The function in the example above is written in val input = "house"
the longer notation, with curly braces and an explicit
return. Since the function only consists of one line, you val result = try {
could also use the short notation. Now, you can call the input.toInt()
extension function as follows: } catch (e: NumberFormatException) {
-1
import javamagazin.isPalindrome }

val palindrom = "anna".isPalindrome()


println(palindrom)
Listing 10
It looks like String has another function called isPa- val names = listOf("Moritz", "Sebastian", "Stephan")
lindrome(). Extension Functions are a useful tool for val namesWithS = names
adding further functions to specified types, making .map { it.toLowerCase() }
the code more readable. By the way: The caller has to .filter { it.startsWith("s") }
import the extension function explicitly via an import namesWithS.forEach { name -> println(name) }
statement in order to use it.

Functional Programming
Functional concepts arrived with the streams in Java 8. Listing 11
Kotlin also allows you to use a functional programming val firstNames = listOf("Moritz", "Sebastian", "Stephan")
style (Listing 10). val lastNames = listOf("Kammerer", "Weber", "Schmidt")
The first line of Listing 10 creates a new list with three
strings. Kotlin infers the type of the list as List<String>. firstNames
The map function transforms each element into a .zip(lastNames)
string with lowercase letters. Lambdas are specified with .forEach { pair -> println(pair.first + " " + pair.second) }
braces. If the Lambda receives only one parameter (in

jaxlondon.com 8
WHITEPAPER Java Core & JVM Languages

prefer to use meaningful names instead of pair.first val person = Person("Moritz", "Kammerer", LocalDate.of(1986, 1, 2))
and pair.second, this is also possible, but it’s a little
more work: println(
person.firstName + " " + person.lastName + " was on " +
data class Person( person.birthday + " born"
val firstName: String, )
val lastName: String
) The getFirstName() function in Java is available as a
firstName property in Kotlin. Types from the Java libra-
In this example, we use another great Kotlin feature: ry, such as LocalDate in the example, are supported, in
Data Classes. These classes automatically generate addition to custom code written in Java. You can even
getter (and setter, if needed), hashCode(), equals(), mix Kotlin and Java together in one project. This feature
and toString() functions. A very useful copy() function is great because it allows you to convert existing projects
is also created, which can be used to make a copy of to Kotlin little by little (if you want to) instead of one big
the data class and change individual properties. Data bang migration. You could also get to know Kotlin a bit
Classes are comparable to Records, which found their by continuing to write your production code in Java,
way into Java 14 [5]. A Data Class can now be used while testing it in Kotlin. IntelliJ also offers an automa-
as follows: tic Java-to-Kotlin converter. It doesn’t produce optimal
Kotlin code, but it’s quite useful.
firstNames The null handling is also very interesting when mi-
.zip(lastNames) xing Kotlin and Java code. Kotlin interprets the various
.map { Person(it.first, it.second) } nullability annotations (@Nullable, @NotNull, etc.) of
.forEach { person -> println(person.firstName + " " + person.lastName) } Java. But if these annotations are missing, then Kotlin’s
null safety will fail. In this case, Kotlin introduces plat-
The map function transforms the Pair<String, String> form types for Java code, such as String!. The exclama-
into a Person instance, and in the forEach function, tion mark means that Kotlin cannot detect whether the
now you can use the meaningful names. Data Classes type can be null or not. Then, the Kotlin programmer
are useful for more than just functional programming. can pretend that variables of this type are not nullable
For example, I use them often for DTOs (Data Transfer and should expect NullPointerExceptions at runtime.
Objects), classes that consist only of fields and access Let’s look at an example to make this clearer:
functions.
Kotlin designers have also fixed an oversight of Java public class Person {
developers: lists, maps, sets, etc. are all immutable by private String firstName;
default in Kotlin, so they have no add-, remove-, set- private String middleName; // Nullable!
, etc. functions. Kotlin still shows its pragmatic core private String lastName;
here, because there are also mutable lists in the form // Constructor, Getter and Setter
of MutableList, MutableSet, MutableMap, etc. These }
mutable variants inherit from their immutable counter-
part. In this class, defined in Java, middleName is nullable
by domain definition. If you use this class in Kotlin,
Interoperability with Java
One important point about Kotlin is its cooperation
with existing Java code. For example, Kotlin does not
introduce its own collection framework, so Java func-
tions that expect lists can also be called with “Kotlin
lists”. In general, calling Java code from Kotlin is not a
problem. In some places, the compiler performs some Integration Testing with Spring
magic. For example, the getters and setters of Java clas- Dr. Catalin Tudose (Luxoft Romania)
ses can be used as properties in Kotlin: Are you interested in developing safe
software and exploring different au-
public class Person { tomated testing possibilities? Are you
looking for efficient ways to test your
private String firstName;
Spring application? The talk will demonstrate effective
private String lastName; integration testing with Spring, using the TestContext
private LocalDate birthday; Framework and its annotations, managing dirties con-
// Constructor, Getter and Setter texts and transactions for testing, differentiating the
} contexts depending on profiles, working with test ex-
ecution listeners and testing with mock Spring MVCs.
Written in Java, this class is easy to use in Kotlin:

jaxlondon.com 9
WHITEPAPER Java Core & JVM Languages

the Kotlin compiler will first look for nullability anno- care of many of the smaller “problems" that Java has.
tations. Since this class has no such annotations, then However, in all fairness, Java either has good worka-
the type of firstName, middleName, and lastName is rounds for these “problems” (such as code generation
String!. via the IDE or Lombok) or the language developers have
That means that these variables could be null or not. already created solutions for them (Switch Expression,
When using this Java class in Kotlin, NullPointerExcep- Multiline Strings, Records, helpful NullPointerExcep-
tions are possible again: tions).
One big advantage of Kotlin that is not found in Java
val person = Person("Moritz", null, "Kammerer") is the null handling. In my opinion, Kotlin created a per-
println(person.middleName.toLowerCase()) fect solution for this, as long as you have pure Kotlin
code. If you need Java interoperability, to call your own
The listing above calls the function toLowerCase() on Java code, or to use one of the many great libraries from
the variable middleName. This code compiles and exe- the Java environment (like Spring Boot), this also works
cutes, but at runtime, it throws a NullPointerException: well. But you have to be careful with the platform types.
As a backend developer, I’ve implemented several
java.lang.NullPointerException: person.middleName must not be null projects using Spring Boot and Kotlin, and it’s been a
lot of fun. Kotlin is by no means limited to Android de-
The NullPointerException has a meaningful error velopment. In Kotlin, you will feel at least as productive
message and shows exactly what is null. Once again, as you do in Java. The standard library has many use-
Kotlin’s pragmatic nature is evident in the platform ful little helpers. Granted, the Kotlin compiler is slower
types. Its designers could have assumed that all types than Java’s, but its features make up for it. From a soft-
whose nullability is not known to be nullable. But this ware engineering perspective, the language also does a
would have led to lots of (most likely, unnecessary) null lot right. It has excellent IDE support and can use the
checks if you wanted to use Java code in Kotlin. Intero- Java-standard build tools Maven and Gradle. However,
perability with Java would be a lot more difficult. I think support for static code analysis tools like SonarQube
the current solution is a suitable trade-off. Many Java still leaves a lot to be desired.
libraries and frameworks also already use the nullability Kotlin has a few more great features to offer that I
annotations, such as Spring. When working with these didn’t describe here due to lack of space. If you want to
libraries in Kotlin, you don’t notice that they are written learn more, I recommend the Kotlin Koans [6]. You can
in Java, and null safety is given again. learn Kotlin through small problems, without having to
leave the browser.
Conclusion And to answer the question in the article’s headline:
I think Kotlin is a great programming language. As a Java is a great programming language and has recently
Java developer, you will immediately feel at home. turned on the feature tap properly. However, don’t turn
Many problems are solved pragmatically. Kotlin takes your nose up at Kotlin. It will please users with well-
thought-out features oriented towards real-world pro-
blems. So: Kotlin or Java? The answer is, as always in
software engineering: “It depends”.

Moritz Kammerer works as an Expert Software Engi-


neer at QAware GmbH in Munich. He is an enthusias-
Dependency Injection: Refactoring from tic backend developer, especially on the JVM. Besides
Spring to Kotlin Java, he is fond of the programming language Kotlin.
He is also the author of various open source projects.
Dmitry Kandalov (Code Mine),
Duncan McGregor (Software
Developer)
Dependency injection libraries and
frameworks seem to be so common
these days that even the simplest pro-
jects start with introducing a DI frame- Links & Literature
work. There are some good reasons to
use DI frameworks, but in general, they
[1] https://kotlinlang.org/docs/faq.html
can be less useful than expected. In
this live coding session, I will take you on a refactoring [2] https://kotlinlang.org/docs/coding-conventions.html
journey moving a small web application from Spring to [3] https://discuss.kotlinlang.org/t/what-is-the-advantage-of-
pure Kotlin. You will see how using modern language companion-object-vs-static-keyword/4034
constructs can help achieve most benefits of DI
[4] https://openjdk.java.net/jeps/361
frameworks without the need for reflection or compiler
plugin magic. [5] https://openjdk.java.net/jeps/359
[6] https://play.kotlinlang.org/koans/overview

jaxlondon.com 10
WHITEPAPER Java Core & JVM Languages

Whats in the Software Development Kit?

Getting Started
with the DataStax
Astra Java SDK
For the uninitiated, a Software Development Kit (SDK) is a set of software-building
tools that streamline development for a specific platform. This article focuses on an
SDK for Java in particular, which consists of three libraries: Stargate SDK, Astra SDK,
and Spring Boot SDK.

By Cédrick Lunven keep digging to learn more. That said, let’s kick things
off with the library that complements one of our favori-
Stargate [1] and DataStax Astra DB are open source te open source projects: Stargate.
projects designed to make it easier than ever to interact
with your cloud-native databases. Although to provide Stargate SDK
all the useful features developers need, these technolo- Stargate is an open source gateway that shields develo-
gies bundle up several APIs that could make it overwhel- pers from the complexities of Apache Cassandra® [2] so
ming for newcomers to get started. you can easily bridge your app’s data with your databa-
For the uninitiated, a Software Development Kit ses – no matter what format your data is in.
(SDK) is a set of software-building tools that streamline
development for a specific platform. It includes building
blocks, debuggers and, often, a framework or libraries
so you don’t have to code from scratch.
Think of it this way: if you wanted to make a cho-
colate cake, using an SDK is like being handed a box
of chocolate cake mix. Not using an SDK is more like Pattern Matching for Java
being given the recipe and having to figure out the pre- Neha Sardana (Morgan Stanley)
paration yourself (with the help of online tutorials and
Pattern matching is already known to
too much caffeine). Java Developers. Over time, the Java
We provide an SDK for Java, JavaScript, and Python. language has expanded its pattern
This post focuses on Java in particular, which consists matching capabilities from just match-
of three libraries: ing strings to matching object types. The introduc-
tion of Records and Sealed Classes in previous Java
• Stargate SDK versions is just part of the story. In this talk, we will
discuss the need and usage of pattern matching. We
• Astra SDK
will uncover this feature, which is going to be most
• Spring Boot SDK helpful for developers going forward. We will discuss
the origin of this feature from Project Amber and learn
This post will briefly go over each of them to give you a about the new features introduced so far.
better understanding of what they are and when to use
them. We’ll also pepper in useful resources so you can

jaxlondon.com 11
WHITEPAPER Java Core & JVM Languages

Figure 1: Stargate SDK architecture overview.

Now let’s get into the SDKs. The Stargate SDK em- • CQL API [6] lets you use the same CQL syntax,
beds three useful components: HTTP, Cassandra-nati- tools, and native language drivers as with any Cas-
ve drivers, and a gRPC client. Take a look at Figure 1 sandra deployment
below for an overview of the architecture. • gRPC API [7] is built on the Google RPC framework
As a brief introduction, the Stargate SDK covers the (hence the name “gRPC”) and enables you to call any
following APIs: microservice in any cloud using Java, Rust, Go, or
Node.js
• REST API [3] provides CRUD operations on top of
Cassandra objects (tables, UDT, records) While Stargate is the official data API for DataStax
• Document API [4] allows you to save and search Astra DB, you can use the SDK with either standalone
JSON documents like a document-oriented noSQL Stargate installations or Stargate deployed in Astra. To
database start coding with Stargate SDK, follow the Stargate SDK
• GraphQL API [5] makes it easy to modify and query quickstart guide [8].
your table data using GraphQL types, mutations, and
queries Astra SDK
Astra is the cloud platform of DataStax providing two
main services: Astra DB and Astra Streaming.

• Astra DB [9] is a database-as-a-service for Apache


Cassandra that handles the complexities of installing,
managing, and scaling it. With multi-cloud compa-
Efficient Spring Data REST tibility, one-click clusters, and the freedom of open
Development source, Astra DB is the fastest, easiest, and most flexi-
Dr. Catalin Tudose (Luxoft Romania) ble way to build cloud-first apps on Cassandra.
You may have already used Spring Data • Astra Streaming [10] is a streaming-as-a-service
REST, but how do you make it perform platform powered by Apache Pulsar for cloud-native
faster and better interact with the messaging and event streaming. It’s a natural fit with
user? From its initial creation, you may Astra DB, allowing you to build real-time data pipe-
introduce the usage of ETags to optimize the server lines in and out of Astra DB instances.
access through caching and conditional requests, limit
the access to repositories/methods/records, work with
paging and with REST events to manage side actions,
As you can see in Figure 2, Astra exposes no less than
customize the default view through projections and eight APIs. But don’t get overwhelmed, because the As-
excerpts to nicely interact with the end user. This ses- tra Java SDK helpfully wraps them all so you can easily
sion will demonstrate how to efficiently build such a leverage the APIs you need, when you need them.
Spring Data REST application. Now let’s take a closer look at the architecture. In Figure
3 below, you’ll notice that the Astra SDK not only handles

jaxlondon.com 12
WHITEPAPER Java Core & JVM Languages

Figure 2: Astra platform APIs

Stargate APIs (CQL, HTTP, GraphQL, gRPC), but also Spring Boot SDK
adds HTTP clients for the DevOps APIs (databases, IAM, Lastly, we have the integration with Spring. The Spring
streaming). Plus, it sets up the connection with Apache Framework [11] provides a modular architecture so you
Pulsar, which you need to interact with Astra Streaming. can flexibly build a Java-based enterprise app that can
The Astra DevOps APIs are essentially REST APIs run on any deployment platform.
that perform the following functions: Spring Boot [12] is, of course, based on this frame-
work and provides a quick start for building and run-
• DB interacts with Astra databases ning standalone, production-ready Spring applications
• IAM stands for Identity and Access Management [13] with minimal configuration.
(IAM), and interacts with the underlying platform Naturally, we built a Java SDK to give the developers
user management (Roles, Users, Token, Access List) using this popular framework a leg up. Here’s a look at
• STREAM interacts with Astra Streaming Pulsar in- the architecture:
stances Aside from the same APIs as in the previous SDKs,
this one features integrations with some select Spring
Quite the all-in-one cake mix, right? services:

Figure 3: Astra SDK architecture overview

jaxlondon.com 13
WHITEPAPER Java Core & JVM Languages

Figure 4: Spring Boot SDK architecture overview

• Spring Boot Starter [14] makes it simple to manage [8] https://github.com/datastax/astra-sdk-java/wiki/Stargate-


dependencies by providing over 30 dependency de- SDK-Quickstart
scriptors that you can add to your project [9] https://www.datastax.com/products/datastax-astra
• Spring Data Cassandra [15] provides a familiar inter- [10] https://www.datastax.com/products/astra-streaming
face to bridge your Java code with Apache Cassandra
[11] https://spring.io/projects/spring-framework
(without dealing with CQL)
[12] https://spring.io/projects/spring-boot
• Spring Boot Actuator [16] exposes metrics so you can
monitor and manage your app [13] https://medium.com/building-the-open-data-stack/
building-microservices-with-spring-data-cassandra-and-
Dig into Astra Java SDK – the official Astra SDK for stargate-io-613f0aff8188
Java [14] https://github.com/datastax/astra-sdk-java/wiki/Spring-
Now that you’re familiar with Java SDKs and their Boot-Starter-Quickstart
(many) APIs, you’re better equipped to choose the right [15] https://github.com/datastax/astra-sdk-java/wiki/Spring-
one for your next Cassandra project. Boot-Starter-Quickstart#5-spring-data-cassandra
We hope this post encourages you to get started with [16] https://github.com/datastax/astra-sdk-java/wiki/Spring-
the Astra Java SDK so you can deploy in days, not Boot-Starter-Quickstart#6-spring-actuator-integration
weeks, and truly get the most out of your Cassandra-
based applications.

Cédrick is Director of Development Relations at Da-


taStax. For the last four years, he has supported the
Cassandra developer community with hands-on work-
shops and video content, and supported the develop-
ment of content with DataStax Academy, all with the
aim of making it easier for developers to use Cassandra in their
applications. Cedrick has more than 15 years of experience with
the technology industry. Before joining DataStax Cedrick was
Technical Leader at Logica, as well as the creator of Feature
flipping for Java (FF4J) for the open source community. Refactoring Gilded Rose Kata
Dmitry Kandalov (Code Mine),
Duncan McGregor (Software
Links & Literature Developer)
Dependency injection libraries and
[1] https://stargate.io/ frameworks seem to be so common
[2] https://cassandra.apache.org/_/index.html these days that even the simplest pro-
jects start with introducing a DI frame-
[3] https://github.com/datastax/astra-sdk-java/wiki/Rest-API work. There are some good reasons to
[4] https://github.com/datastax/astra-sdk-java/wiki/Document- use DI frameworks, but in general, they
API can be less useful than expected. In
[5] https://github.com/datastax/astra-sdk-java/wiki/GraphQL- this live coding session, I will take you on a refactoring
API journey moving a small web application from Spring to
pure Kotlin. You will see how using modern language
[6] https://stargate.io/docs/stargate/1.0/developers-guide/ constructs can help achieve most benefits of DI frame­
cql-using.html works without the need for reflection or compiler
[7] https://stargate.io/docs/stargate/1.0/developers-guide/ plugin magic.
gRPC-using.html

jaxlondon.com 14
WHITEPAPER Java Core & JVM Languages

JBang: a versatile tool

Unleashing new
Java powers
This article is part of a series about tools that might be widely known or used, or
have a rather unexpected use. A good example of this is JBang.

By Michael Simons download the appropriate JDKs and dependencies and


can compile Java sources.
I first heard about JBang [1] in October 2020 on Twitter If a Shebang line is added to the appropriate source,
[2] – where else? It was about “XXX in one tweet”, in then it is directly executable in most shells.
this case, it was polyglot programming (Listing 1). So, what does this look like with polyglot Java in a
It is directly executable on the GraalVM, thanks to tweet? I have two choices here: I could instruct JBang
JEP 330 “Launch Single-File Source-Code Programs” to always use the GraalVM version of Java. Or, I can
and gives us 42 as an output. Why do I need yet another simply specify Graal’s polyglot dependencies and add
tool in my portfolio? Let JBang itself have a chance to Listing 1 in the first lines, as shown in Listing 2.
speak: These comments show nearly everything that I gain
“Lets Students, Educators and Professional Develo- with JBang: an executable file, control over the Java ver-
pers create, edit and run self-contained source-only Java
programs with unprecedented ease.”
The keyword here is “self-contained”, and a screen
later, “embedded dependencies”. That means, once in-
stalled (e.g. with JBang itself, SDKMan, Chocolatey/
Windows, or Homebrew/macOS, [3]) JBang is able to
You might be wasting millions of dollars
in garbage Collection
Listing 1: Polyglot Java 11 in one tweet Ram Lakshmanan (yCrash)
Enterprises are wasting millions of
class P { dollars in garbage collection. They are
public static void main(String[] args) { wasting these many millions without
var result = org.graalvm.polyglot.Context.create() even knowing that they are wasting it.
.eval("js", "[11,11,20].reduce((a,v) => a +v)") In this talk, we would like to bring to your attention
.asInt(); how several millions of dollars are wasted and what
System.out.println(result); you can do to save money. Optimizing garbage col-
lection performance not only saves money, but also
}
improves the overall customer experience as well.
}

jaxlondon.com 15
WHITEPAPER Java Core & JVM Languages

„Java as a scripting language sounds


strange at first, but I think it‘s super.“

sion, a dependency management, and control of Java Michael Simons is a father, husband, and athlete (the
(and Javac) options. The program can be executed as latter, perhaps only in his imagination). He is a Java
shown in Listing 3. Champion, co-founder, and current director of Eure-
gio JUG (http://euregjug.eu/). Michael is very involved
On the first call, JBang will create and cache a JAR with the Spring ecosystem both in Germany through
file and then execute it. This will then allow the comple- his German-language Spring Boot book, and also internatio-
te Java ecosystem to be used for developing Java-based nally. Spring is a recurring topic on his blog. This won’t change
anytime soon, because Michael works as a software engineer
scripts. JBang was born in early 2020 with this goal in at Neo4j and deals with the Spring Data Module for the Neo4j
mind, driven by Max Rydahl Andersen. graph database of the same name.
What’s possible with it? Among other things, I use
JBang to productively test packaged libraries under Links & Literature
different JDKs: I use org.junit.platform:junit-platform-
console-standalone as a dependency and point to my [1] https://twitter.com/rotnroll666/
test JARs. This lets me reliably test multi-release JARs. status/1321540184849190913
It can be used for fast database queries: Define JDBC [2] https://www.jbang.dev
or Neo4j driver as a dependency, and databases can be
[3] https://www.jbang.dev/documentation/guide/latest/
used easily in tests. installation.html
With JBang, I implemented a minimal image manage-
[4] https://github.com/michael-simons/biking2/blob/
ment [4]. Along with Java 17 text blocks as HTML tem-
b777adc65b2497635737c05526b8c55b7f658db2/src/cli/
plate and program arguments, I use with PicoCLI [5], CreateGalleries.java
I have a fast script for generating HTML pages. Here
[5] https://picocli.info
I could still use JSoup to parse existing pages, for in-
[6] https://www.testcontainers.org
stance.
In relation with Testcontainers [6], containers can be
orchestrated and used for testing or demo purposes.
Java as a scripting language sounds strange at first,
but I think it's super. Instead of having to switch bet-
ween JVM-based languages and scripting languages in
my daily work, I can save myself the cognitive overhead
of having to do repetitive tasks that I could shorten with
small programs.
Flutter for Java Developers: Mobile,
Web, and Desktop with One Codebase?
Listing 2: Adding JBang: Shebang, Java Karsten Silz (Better Projects Faster
Ltd.)
Version, Options and Dependencies Enterprise users are increasingly ac-
///usr/bin/env jbang "$0" "$@" ; exit $? cessing our Java applications with
//JAVA 17 mobile devices. Native applications
often provide a better user experience on mobile
//JAVA_OPTIONS -Dpolyglot.engine.WarnInterpreterOnly=false
devices than web applications. But developing two
//DEPS org.graalvm.sdk:graal-sdk:21.3.0
different applications for iOS and Android is expen-
//DEPS org.graalvm.js:js:21.3.0 sive and time-consuming. Cross-platform frameworks
promise salvation: Mobile, web, and desktop front-
ends with one codebase. I think Google’s Flutter is the
best cross-platform option for Java developers. But
Listing 3: Execution can Flutter deliver? I’ve developed native applications
for iOS and Android with Flutter and put them in the
jbang P.java app stores. Based on my experience, I describe the
> 42 advantages of Flutter for Java developers, but also
// Or directly typical problems and their solutions. With an exam-
chmod +x P.java ple application, I demonstrate how mobile, web, and
./P.java desktop front-ends can succeed with one codebase—
> 42 and what the limitations are.

jaxlondon.com 16
WHITEPAPER Agile, People & Culture

The state of testing today

No Honeycomb
Testing and Mocks?
You’re Probably
Getting App
Testing Wrong
An ideal testing solution should model and then replay all associated inbound and
outbound traffic. Essentially, the traffic would be realistically “mocked” without
interrupting the developer team’s workflow as the code is created, from the very be-
ginning of and through the entire development process.

By Nate Lee nary testing by DevOps teams, productivity is further


sapped as the testing and debugging process might only
Many organizations are learning the hard way: Traditi- really begin once the application is in production for
onal testing processes for virtual machine-based applica- many organizations.
tions have largely proven to be unviable for Kubernetes An ideal testing solution should model and then
environments. replay all associated inbound and outbound traffic
In non-Kubernetes applications, end-to-end user in- (Fig. 1). Essentially, the traffic would be realistically
terface (UI) testing is a crucial component of code tes- “mocked” without interrupting the developer team’s
ting. UI testing involves mimicking the actual UI changes workflow as the code is created, from the very begin-
and flows that end-users will experience as they use key ning of and through the entire development process
features of the app, and ensures that the application – this process also results in a honeycomb-shaped tes-
provides the desired interaction and functionality to the ting pattern, as we detail below. Testing, in this way,
user. This type of testing can be done both manually and also auto-identifies dependencies in the Kubernetes
through automated test suites. production environment in which the app will be de-
However, a UI test does not typically provide a com- ployed throughout the testing process. In other words,
plete picture of how an application or microservice will there is a viable shift left for testing in Kubernetes
perform once deployed in a Kubernetes environment. environments without slowing down development –
Additionally, UI testing often requires manually clicking while also reducing the failure rate once applications
through screens and verifying correctness, leading to are deployed.
slowdowns in production-release cadences. Again, these benefits are achieved by testing with so-
Automated UI test suites exist, but can often be hard phisticated mocks throughout the entire development
to maintain and debug for QA and DevOps departments and deployment process, which also results in a honey-
for microservices. Relegated to an over reliance on ca- comb-shaped testing pattern.

jaxlondon.com 17
WHITEPAPER Agile, People & Culture

However, the caveat of the unit-test


definition is hidden in the clause “inde-
pendently tested.” Modern microservices
architectures often have high levels of cou-
pling (dependencies) between components.
This means components cannot be cleanly
and independently tested – their output is
too dependent on the output of other sub-
sequent components. The line between
what is a unit test and an integration test
consequently becomes blurry. Rather than
attempting to overcome this flaw, many
testing evangelists now propose that engi-
Fig. 1: Testing apps in a real-world environment with mocks (in blue) neering departments accept it as a natural
evolution of software architecture. They shift the em-
The State of Testing Today phasis to better and more comprehensive integration
The differences between unit, integration and user-inter- testing or, more likely, testing-in-production.
face testing can vary from one organization to another.
Unit testing has traditionally been defined as testing the Ice-Cream Cone Testing: The Reality
smallest unit of functionality that can be independent- Many organizations end up doing what’s called “ice
ly tested, consisting of individual methods or API end- cream cone testing” (Fig. 3) for applications running in
points. Kubernetes environments. They end up mostly doing
Integration tests (Fig. 2) should test how individu- end-to-end testing of code through a UI. It’s critical to
al components – which have already been unit-tested understand that this is a major flaw in testing – a UI test
– function together. These tests identify bugs between does not provide a complete picture of how an appli-
components, such as issues with the way components cation or microservice will perform once deployed in a
talk to each other and pass data back and forth. Kubernetes environment. It’s like looking at an iceberg
UI testing, as described above, is testing from the per- only above water. Moreover, provisioning complete
spective of the end-user. UI testing identifies the screens end-to-end environments with proper versions of the
and flows that the user will interact with, and ensures APIs and accurate test data is also one of the most ex-
they are both correct and provide a good experience. pensive – slowest – parts of the testing process.
Both unit-testing and UI testing are also still essential The remedy is to implement true application integra-
to K8s applications, as they ensure the correctness of tion testing that replicates the production environment’s
microservices at the most fundamental level, as well as dependencies and potential failures or unusual behavi-
the best UX for the user. ors among them.

Fig. 2: Proper integration testing

jaxlondon.com 18
WHITEPAPER Agile, People & Culture

Enter the Honeycomb upstream and downstream dependencies. Identifying the


State of Testing root cause of test failures in end-to-end testing is like se-
A structure emphasizing arching for a needle in a haystack. Honeycomb testing, by
integration testing appli- contrast, gives a much clearer picture of the system under
cations for Kubernetes test by focusing explicitly on interaction points between
environments can be imple- microservices, rather than both connections and imple-
mented by applying a ho- mentation details at once. Honeycomb testing can also
neycomb-shaped structure reveal application deficiencies – such as high latency or
to the process. A honey- API incompatibility – before the canary release. The ca-
comb structure means that nary release process will consequently be smoother, since
integration testing in mock the probability that the application or update will fail is
environments represents the reduced. In the event of a failure, remediations can start
bulk of testing for Kuberne- immediately once unexpected behavior is identified based
tes. Spotify’s honeycomb- on prior integration-testing baselines, such as total time
shaped testing methodology to serve a request or to load a component on the page.
Fig. 3: Ice cream cone testing and testing semantics prob- This approach provides substantial benefits, especially
lems are described in this recent Martin Fowler blog post: in accelerating development cadence, and can alleviate
“When I read advocates of honeycomb and similar huge liabilities in mission-critical software. In sectors
shapes, I usually hear them criticize the excessive use of such as fin- or healthtech, even limited software failures
mocks and talk about the various problems that leads to. can cause chaos for users and multi-million-dollar losses
From this I infer that their definition of ‘unit test’ is spe- for companies. It is not viable, for example, for a user to
cifically what I would call a solitary unit test.” – Martin get a 404 message after depositing an electronic check,
Fowler, “On the Diverse And Fantastical Shapes of Tes- or a hospital to have no trace of an emergency medical
ting.”[1] scan transfer that timed out when submitted.
According to Fowler, the contrast to a “solitary test” While the honeycomb paradigm was developed long
in this context is the “sociable test.” Solitary tests allow ago, improvements in containerized platforms and ser-
for testing without an overreliance on mocks. Sociable vice mesh have allowed modern testing suites to be see-
tests on the other hand are the most reliable way to va- ded with tools that monitor real-life API traffic and create
lidate distributed microservice behavior, and the appli- mocks based on real-world conditions. This is a signifi-
cation code should be tested in a simulated production cant change over the previous generation of simulators,
environment. The application runs during the testing which required API responses to be initiated manually.
phase as if it were deployed, with all the microservices The manual development of API responses slow down
neighbors connected to mocked pods, containers and development cadences significantly, and the resulting
APIs – both upstream and downstream. test suites are incredibly brittle and vulnerable to change.
Even a minor update to an API can cause tests to break
The Honeycomb and Mock Testing: Fundamental and the entire development life cycle to grind to a halt
To Engineering while the corresponding mocks are updated by hand.
Proper honeycomb testing has a faster mean time to re- By contrast, modern tools like Speedscale’s Traffic Re-
solution (MTTR) because it more cleanly simulates the play allow for observability and reproducibility in API re-
sponses by using real-world traffic to model how tests and
mocks should behave. Speedscale’s mock suite also toke-
nizes data, such as unique IDs and timestamps, which can
be replaced in real time as the configuration of the working
production environment changes. This dramatically shor-
tens the time it takes to build out mocks. QA engineers
can build more thorough test suites in less time, leading to
more accurate testing and faster development timelines.
Ensuring thorough integration testing of Kubernetes-
deployed applications and microservices, in this way, can
help ensure software services stay healthy and robust.

Nate Lee is the Founder of Speedscale. Experienced


API and Automation expert with 12 years of back-
ground in the DevOps Testing space.

Links & Literature

Fig. 4: Image source. Martin Fowler. [1] https://martinfowler.com/articles/2021-test-shapes.html

jaxlondon.com 19
WHITEPAPER Microservices & Service Mesh

Taking a look at JobRunr

An introduction to
JobRunr, a distri-
buted background
job scheduler
JobRunr analyzes and serializes all your jobs as readable JSON to either a SQL or
NoSQL database. If too many background jobs are created, you can scale hori-
zontally by spinning up more instances of your application. As the jobs are stored
as JSON in a central database, the workload can be spread over multiple JVM’s.

By Ronald Dehuysser Sometimes you don’t want to run a job immediately


– you need it to run tomorrow (e.g. a day after a user
About JobRunr registered) or you might want to run a recurring job. All
JobRunr is a library that you can embed in your exis- of this is supported out-of-the-box.
ting application to enable the scheduling of background Life doesn’t always go perfect and things go down – if
jobs. A job can be a short or long-lived process that runs a background job fails (e.g. due to a dependent API that
in a background thread. A typical use case is to offload is down), it is automatically retried by means of a smart
a long-running process from a web request to a back- backoff policy.
ground thread resulting in a better experience for the
end user.

Some JobRunr features


JobRunr analyzes and serializes all your jobs as readable
JSON to either a SQL or NoSQL database. If too many
MicroProfile: Current and Future
background jobs are created, you can scale horizontally
by spinning up more instances of your application. As Emily Jiang (IBM)
the jobs are stored as JSON in a central database, the MicroProfile 5.0 aligns with the latest
workload can be spread over multiple JVM’s. As soon Jakarta EE release, Jakarta EE 9.1. With
this release, you will be able to use
as a new instance of your application is started, JobRunr
jakarta.* namespaces in your applica-
automatically starts processing jobs. To make sure that tions. Afterwards, MicroProfile 6.0 is being worked on.
the same job is not being processed multiple times, it This session will bring you up to date with the latest
makes use of optimistic locking. Nobody likes cleaning, release of MicroProfile with a live demo on Open
that’s why JobRunr is also self-maintaining – all succee- Liberty. Finally, Emily will discuss the future direction of
ded jobs will automatically be deleted after a configura- MicroProfile.
ble amount of time.

jaxlondon.com 20
WHITEPAPER Microservices & Service Mesh

JobRunr also comes with a built-in dashboard that In this article, you will learn how to schedule a simple
allows you to monitor all jobs. background job by means of a Java 8 lambda and a Job-
Request.
How to create a job
You can create background jobs easily: Setup
To use JobRunr in Spring, you first need to add the de-
• by means of a Java 8 lambda where you can reuse pendency to the `jobrunr-spring-boot-starter` in the Ma-
any of your existing services ven pom.xml (Listing 1).
• or by means of a JobRequest and a JobRequestHand- Here, you’re adding 3 dependencies:
ler
• the `jobrunr-spring-boot-starter` that enables the
integration between JobRunr and Spring Boot.
• the `spring-boot-starter-data-jpa` is not really neces-
sary, but it helps as it automatically creates a Data-
Listing 1: Maven dependency Source for you.
<dependency> • the `h2` database that you will be using to store all
<groupId>org.jobrunr</groupId> the job state.
<artifactId>jobrunr-spring-boot-starter</artifactId>
<version>4.0.8</version> JobRunr configuration
</dependency> JobRunr by defaults only enables the job scheduler. As
<dependency> the background job server and the dashboard are opt-
<groupId>org.springframework.boot</groupId> in only, you need to add some properties to the Spring
<artifactId>spring-boot-starter-data-jpa</artifactId> `application.properties`:
<version>2.6.1</version>
</dependency> org.jobrunr.background-job-server.enabled=true
<dependency> org.jobrunr.dashboard.enabled=true
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId> The first property tells JobRunr to enable the back-
<version>2.1.210</version> ground job server so that jobs will actually be processed.
</dependency> The second property enables the JobRunr dashboard.

Job Storage
By default, JobRunr will try to use your existing `javax.
Listing 2: Creation with JobRequest and sql.DataSource` or any of the supported NoSQL clients
JobRequestHandler to store all job-related information. As you’ve added
public class SampleJobRequest implements JobRequest { the dependency to `spring-boot-starter-data-jpa`, a Da-
taSource has been automatically created, so you’re all
private final String input; set.

// needed for deserialization by Jackson


protected TestJobRequest() {
this(null);
}

public TestJobRequest(String input) { Cloud Native Application Development


this(input); and Deployment Workshop:
} MicroProfile, Jakarta EE, Open Liberty,
OpenShift and Istio
@Override Emily Jiang (IBM)
public Class<SampleJobRequestHandler> getJobRequestHandler() { What is the modern and open way to
return SampleJobRequestHandler.class; build cloud-native microservices? Are
} there any programming models avail-
able? You might have heard about Mi-
public String getInput() { croProfile. If you are wondering about the why, what,
return input; and how aspects of MicroProfile, this workshop is for
you. In this workshop, you’ll learn everything you need
}
about MicroProfile with an explanation and demo.
}

jaxlondon.com 21
WHITEPAPER Microservices & Service Mesh

Fig. 1: Enqueued jobs

Usage The <code>`JobScheduler`</code> is a bean provided by


JobRunr and allows you to enqueue or schedule new jobs.
By means of a Job Lambda The <code>`SampleJobService`</code> can be any
To use JobRunr with a Job Lambda, you first need to Spring bean on which you want to invoke a method that
inject some Spring Beans: can take some time to process. It can also be a method
where you want to add some extra resilience as JobRunr
@Inject will automatically retry the method in case of an excep-
private JobScheduler jobScheduler; tion.
Now, you can easily create a job:
@Inject
private SampleJobService sampleJobService; jobScheduler.enqueue(() -> sampleJobService.executeSampleJob());

Fig. 2: Failed jobs

jaxlondon.com 22
WHITEPAPER Microservices & Service Mesh

Passing arguments is also possible: @Service


public static class SampleJobRequestHandler implements JobRequestHandler<
jobScheduler.enqueue(() -> sampleJobService.executeSampleJob("Hello! I will SampleJobRequest> {
be executed in a Back
@Override
The above two calls will make sure that JobRunr ana- public void run(SampleJobRequest jobRequest) {
lyses the given lambda, it will be stored in the database System.out.println("Running sample job request in background: " +
and the next available dedicated worker will process it. jobRequest.getInput());
}
By means of a JobRequest and a JobRequestHandler }
You can also create a job by means of a JobRequest. This
will involve the creation of a `JobRequest` a `JobRequest- Now there is only one thing left: enqueueing the job.
Handler` and enqueueing the actual job (Listing 2). You can do this as follows:
Here, you first create a `SampleJobRequest` that can
take arguments you have available when you create the @Inject
job. The `JobRequest` also needs to implement one me- private JobRequestScheduler jobRequestScheduler;
thod called `getJobRequestHandler`. This method must
return the class that will contain your actual business ...
logic / background job.
Next, you need to create a `SampleJobRequestHand- jobRequestScheduler.enqueue(new SampleJobRequest("Hello"));
ler` that will contain your actual background job and
business logic. To do so, one `run` method must be im-
plemented. When the background job runs, it is provi- Dashboard
ded with the input you created above. JobRunr comes with a built-in dashboard (Fig. 1) that
allows you to monitor all your jobs (Fig. 2).

Conclusion
After completing this article, you have created your
first background job using Spring Boot and JobRunr.
The important detail here is that you can create a back-
Testing Java Microservices Apps ground job with a minimal amount of code that can
Without Cooking Your Laptop: even run in a different JVM than where you scheduled
Using Docker & Telepresence it. Here, we only briefly touched one feature of JobRunr,
Dr. Daniel Bryant (Ambassador Labs) however, it offers a lot more, like scheduled jobs, recur-
When enterprise organizations adopt ring jobs, and more.
microservices, containers, and cloud The complete source code for this article is available
native development, the technologies on Github [1].
and architectures may change, but the To learn more, visit JobRunr [2] on Github.
fact remains that we all still add the occasional bug
to our code. The main challenge you now face is how
to perform integration or end-to-end testing with- Ronald Dehuysser is a software architect and devel-
oper in Belgium with experience in designing and re-
out spinning up all of your microservices locally and alizing innovative and user-friendly web-based
driving your laptop fans into high speed! Join me for enterprise applications. He has more than 15 years of
a tour of testing microservices using a series of Java experience in IT as a developer, analyst, and coach.
applications as a case study. You will learn everything Follow him @rdehuyss
about effective unit testing with mocks, using TestCon-
tainers for dependency testing, and using Telepres-
ence to extend your local testing environment into
the cloud. Learn when to use each type of test and
tooling based on your use case and requirements for
realism, speed, and practicality. We will discuss how
to utilize containerized dependencies and Docker for
testing, including both apps and services you own
and those you don’t. We’ll also go over the challenges
with scaling container-based application development
(you can only run so many microservices locally before
minikube melts your laptop). Finally, you’ll see how
Telepresence can “intercept” or reroute traffic from a Links & Literature
specified service in a remote K8s cluster to your local
dev machine. [1] https://github.com/jobrunr/example-jaxenter
[2] https://github.com/jobrunr

jaxlondon.com 23
WHITEPAPER Cloud, Kubernetes, Serverless

Evolving from a pre-cloud mindset

Evolving Java
Runtimes for a
Cloud-Centric
World
Java runtimes currently operate with a pre-cloud mindset that does not leverage
or take advantage of modern cloud environments. Java Virtual Machines (JVMs)
can be modernized with new approaches that assume the presence of a “magic
cloud.” Cloud-native compilation is a key example of this new approach, with pro-
duction-ready implementations already producing highly efficient and affordable
code optimization.

By Gil Tene ducting whatever functions the JVM must perform. This
approach necessarily involves tradeoffs. Resources used
Java Runtimes Evolve from a Pre-Cloud Mindset to run a given application compete with resources used
Java Virtual Machines (JVMs) were created in a pre- to perform internal JVM functions designed to support
cloud world and have continued to operate with a the execution and improve application performance and
pre-cloud mindset: They are isolated, self-reliant units efficiency over time.
constrained to limited local resources, compute capacity
and analytical capabilities. This approach has worked
for decades, as evidenced by Java’s ubiquitous presence
and adoption, but is now showing its age. Java runti-
mes now have the opportunity to thrive in modern cloud
environments by casting off the legacy limitations and
tradeoffs that were inherent in a pre-cloud world, but Service Mesh Workshop:
which are now unnecessary. Create, Manage, and Test a Java
Today’s JVMs are isolated; they are built to run wor- Service Mesh with Istio
kloads using their own functionality. They are unaware
Michael Hofmann
of anything outside of themselves; JVMs have no me- (Hofmann IT-Consulting)
mory of what happened before they started, they lea-
In this workshop, you will learn how
ve nothing behind for future runs, they are ignorant of to master the challenges of a service
what their neighbors or peers are doing, and they do not mesh. To demonstrate this, multiple
leverage intelligence or capabilities that their environ- MicroProfile and Spring Boot-based microservices
ment may have. will be combined together with Istio to form a service
JVMs are also religiously self-reliant. Only local re- mesh.
sources are used in running an application and in con-

jaxlondon.com 24
WHITEPAPER Cloud, Kubernetes, Serverless

“Cloud-native compilation enables application


developers to do more with less, and can do
so in today’s cloud native environments.“
“Magic clouds” didn’t exist in the 1990s, when ze the execution of the application, virtually unlimited
today’s JVM architectures were solidified. At the time, compute power, storage, memory and experience is
JVMs were painfully aware that compute power was a available for them to access and leverage. Today, cloud-
highly limited resource, as were storage and memory. centric Java runtimes are both practical and real, and
Nor was there external functionality for them to rely they are available now.
on; analytical capability and knowledge were limited
to what a JVM could do on its own, and to informa- A Cloud-Centric Approach to Java Code
tion gathered since it started. JVMs could study be- Optimization with Cloud Native Compilation
havior and code, analyze and optimize it, but only in The assumption of elastic and abundant cloud resources
the context of what the JVM itself had seen within a allows us to re-evaluate which functions must be per-
given run. formed in isolation by the JVM and which can be out-
But these limitations are not inherent to JVMs. We sourced to external resources. While various elements
live in the 2020s and can make assumptions that were within the JVM lend themselves well to an outsourced
not available to JVMs when they were originally de- approach, JIT (just in time) compilation is an obvious
signed: reliable connectivity to vast networks and the choice.
availability of massive external resources and functio- JIT compilers perform the heavy lifting of translating
nality. JVMs now can assume the ability to analyze Java bytecode to optimized machines’ code. To do that,
and apply experience from the past and can leverage an optimization conversation between the JVM and the
such external experience – both to benefit themselves JIT occurs for every “hot” method within the Java run-
and to contribute experience so other JVMs can benefit time. The conversation starts with the JVM asking the
in turn. JIT compiler to optimize a method. The JIT compiler
Today, the “magic cloud” exists. When JVMs need to then interrogates the JVM about the code, iteratively
perform work beyond the actual execution of an appli- asking questions about various facts and profiles, and
cation, such as activities designed to support or optimi- requesting additional code for called methods so they
might be analyzed and optimized together. The JIT com-
piler eventually produces code that it thinks best suited
to the current situation – optimized code that is hopeful-
ly better, faster and more efficient. Today, production
JVM performs these optimizations using in-JVM JIT
compilers.
Secret Management – The Soft Way Better JIT’ing can and does produce faster code; and
Lian Li (Tilt Dev) results from Azul’s highly optimizing JIT compilers
ecrets. Security best practices mandate
demonstrate just how much faster workloads can run.
that they stay away from the code—or When we turn powerful optimizations on in our Azul
else! And that’s what we did for a long Platform Prime [1] environment, we often produce code
time. But as CI/CD practices evolved, that is 50 to 200 percent faster for individual methods.
for a myriad of reasons, we now want to ship the code, This in turn translates into seriously faster speeds for
the environment, and the secrets, all in one lump. So applications – such as 20 and 30 percent faster perfor-
we can’t hide the secrets anymore…unless? Tools like
mance for Cassandra and Kafka.
HashiCorp Vault attempt to address this by managing
secrets outside the delivery chain. Great! But you can’t
However, there is an inherent tradeoff between how
use those inside local dev environments. But when optimized the code is and the cost of performing the op-
that’s precisely what you need to do, then what? In timizations. Better JIT’ing and powerful optimizations
this talk, Lian will show the audience how to manage can get us much faster code, but it comes at the cost of
secrets the GitOps way, so you can maintain security increased CPU usage and memory requirements, as well
best practices while also being able to use them in as increased time for performing the optimizations. In a
your local environment for development. Sounds like
constrained environment, such as a container environ-
magic? That’s because it is. After this talk, the audi-
ence will be able to understand secret management
ment where only a few cores are available and memory
solutions that work seamlessly in a variety of environ- is limited, some levels of optimization may not be practi-
ments. cal. The resources needed for producing more powerful
optimizations may not be affordable, and the prolonged

jaxlondon.com 25
WHITEPAPER Cloud, Kubernetes, Serverless

warmup performance drawbacks may be prohibitive. previous assumptions are satisfied, the same (cached)
Such resource constrained environments often choose to optimized code can be provided without having to re-
forgo more powerful optimizations, leaving speed and compute the optimization. Therefore, further efficiency
efficiency on the table. comes from reusing the work itself, and not just the
That is the inherent tradeoff facing pre-cloud, self- resources needed to produce it. When an optimization
reliant JVMs. But a cloud-centric approach to Java can be reused across many JVMs, the cost of producing
runtimes can eliminate the tradeoff, by taking the JIT each optimization is dramatically reduced to what pre-
compiler out of the JVM and serving its functionality cloud JVMs would need to pay to achieve the same
from a cloud-native compilation service. A service that optimization levels.
elastically scales up and down, and is available to and
shared by a multitude of JVMs. A service that can ap- A Cloud-Centric Mindset
ply more resources to optimization than a single JVM Cloud-native compilation takes Java runtimes from a
ever could. Such a Cloud Native Compiler is ideal for pre-cloud mindset into a cloud-centric one. It produces
efficiently and effectively producing highly optimized more powerful optimizations with greater efficiency. It
code. produces faster code because it can afford to do so –
using less local resources: less CPU, less memory, and
Cloud Native Compiler: Optimization, less time. Cloud-native compilation enables application
Performance, Efficiency, and Cost Reduction developers to do more with less, and can do so in today’s
By shifting the heavy lifting of optimization to a scala- cloud native environments, whether on the cloud itself
ble and efficient resource, a cloud-native compiler or in a customer managed environment involving Ku-
makes powerful optimizations both practical and af- bernetes.
fordable. These optimizations result in faster applica-
tion code and improved JVM performance, which in Gil Tene (Twitter: @giltene) is CTO and co-founder of
turn translate to more efficient application execution Azul. He has been involved with virtual machine tech-
nologies for the past 20 years and has been building
and reduced cloud infrastructure costs for running a Java technology-based products since 1995. Gil pio-
given workload. neered Azul’s Continuously Concurrent Compacting
A JVM instance will usually run for many hours, but Collector (C4), Java Virtualization, Elastic Memory, and various
managed runtime and systems stack technologies that combine
it only needs its full optimization capabilities for minu- to deliver the industry’s most scalable and robust Java platforms.
tes at a time. A JVM instance using constrained local Gil also represents Azul on the JCP (Java Community Process)
resources for optimization must carry around the re- executive committee. Gil holds a BSEE from The Technion Isra-
el Institute of Technology, and has been awarded over 40 pa-
sources needed to perform these optimizations for its tents in computer-related technologies.
entire lifetime, and with it the cost of those resources
even when they are not in use. In contrast, when a cloud-
Links & Literature
centric JVM uses a cloud-native compiler, that compiler
can amortize the same resources, sharing and reusing [1] https://www.azul.com/products/prime/
them as it performs optimizations for many different
JVM instances. It can shrink its resources when not in
use, dramatically reducing their costs, and can grow
them on demand, even to massive amounts. The reuse
efficiency, scale, and elasticity of a cloud-native compi-
ler mean that resources can easily and economically be
brought to bear to perform powerful optimizations wit-
hout the warmup or cost concerns that contained JVMs
would encounter.
In addition, cloud-native compilation can leverage a
key efficiency benefit not available to individual JVMs:
The vast majority of code today executes more than Serverless beyond functions
once, runs many times across many devices, and tends Mete Atamel (Google)
to repeat the same tasks and profiles. In today’s pre- Serverless is much more than simple
cloud JVMs, these common characteristics go unused HTTP triggered functions. You can run
because each JVM performs local, ephemeral optimiza- containers and whole apps serverlessly,
group functions behind an API gate-
tions that are then forgotten. A cloud-native compiler
way, coordinate services with a central orchestrator or
environment such as Azul Intelligence Cloud can reuse let them communicate indirectly via events. Serverless
the optimizations themselves. When a JVM asks for services can be scheduled or made more resilient with
an optimization of code that the cloud native compiler task queues. You can even combine serverless with
has optimized in the past, the compiler can check to serverful services. In this talk, we’ll look at the server-
see if the JVM’s environment and reality match satis- less landscape beyond simple functions.
fy assumptions made in previous optimizations. If the

jaxlondon.com 26
WHITEPAPER DevOps & Continious Delivery

The digital transformation journey

Time to Modernize
Ops
Digital transformation is not simply a linear path. It is a journey made of many smaller
journeys. In this article, Lori MacVittie, Principle Technical Evangelist, Office of the
CTO at F5, takes a look at research from the annual State of Application Strategy Re-
port and digital transformation.

By Lori MacVittie to thrive in this digital as default world. Expanding to


cloud – the rate of SaaS adoption continues unabated and
As organizations accelerate their journey to become a there are signs Everything-as-a-Service (XaaS) will play
digital business, CIOs are taking the wheel and kicking a significant role in the future – introduces technology
the technology engine into high gear to power organiza- challenges that can only be answered by IT.
tions through the second phase of digital transformation
with a shift in focus from modernizing apps to moder- Modernizing Apps
nizing ops. Business processes necessarily span many lines of busi-
The ability of organizations to sustain their acce- ness and cross organizational boundaries into less men-
lerated rate of digitization is about to face its biggest tioned areas such as legal, HR, and finance. A telling
challenge – IT. While we’ve seen great strides in the result in this year’s research is significant growth in the
transformation of customer-facing experiences, motiva- focus on digitizing these functions.
ted by necessity [1], businesses are beginning to realize Customer-facing experiences are still a priority, but
that becoming a fully digital business means transfor- organizations are facing the reality of cross-functional
mation of the entire business. That yellow flag on the processes: traditional (manual) steps in a process are
race to dominate in a digital economy is causing a shift disruptive, slow, and prone to degrade the digital expe-
in focus toward business functions and IT operations, rience for customers, partners, and employees.
putting CIOs in the driver’s seat. A focus on business functions necessarily means a re-
newed focus on applications. That’s sent some back to
Digital transformation is a journey made of many phase one – task automation – to focus on modernizing
smaller journeys apps and building (or subscribing) to new apps to di-
For the past three years, we’ve analyzed research from gitize those functions that remain manual and paper-
our annual State of Application Strategy Report through based. A significant majority – 88% – are modernizing
the lens of the digital transformation journey. applications and 17% of the average app portfolio is
While the journey takes organizations through three SaaS today.
distinct phases, the reality is that most organizations – But it’s not just modernization of the apps themselves
63% – are operating in multiple phases at the same time. that is driving organizations to look inward to maintain
Just over one in three is currently focused on a single momentum. More than eight in ten (84%) organizations
phase. Almost one in five – 18% – are currently opera- plan to deploy workloads at the edge. That should be
ting in all three phases. unsurprising, as many of those workloads are traditio-
In the past, we’ve focused primarily on the business side nally deployed at the edge such as performance and mo-
of digital transformation. But this year [2] we see serious nitoring related services like caching, CDNs, and health
attention now being paid to the other side of the equation: monitoring. What is surprising is the number of organi-
technology. That’s likely due to roadblocks and potholes zations who plan to deploy application (42%) and data
organizations have encountered as they focus on moder- workloads (42%) at the edge. That demand means the
nizing apps to support the digital experiences necessary rate at which the shift in the edge ecosystem [3] must

jaxlondon.com 27
WHITEPAPER DevOps & Continious Delivery

occur to accommodate these workloads must accelerate. tion-related skillset deficits cited by every organization.
Dramatically. While AIOps is certainly not being left behind, CIOs
It also means IT will face even greater challenges as and technology leaders recognize that technology alone
workloads distribute even further from the data center is never enough. The purpose of technology is to impro-
core. Multi-cloud will expand to include edge and mag- ve the human capacity to manage, analyze, and make
nify existing challenges with operations. decisions at scale. In the case of AIOps, that means two
things. First, offloading mundane operational decisions
Modernizing Ops to automation. This includes actions like auto-scaling
The answer is not more ops. Even if organizations and failover. Operational tasks that are well-understood
weren’t faced with a highly competitive market for tech- and well-defined. Second, AIOps can increase the speed
nology professionals, throwing more people at a problem with which information is delivered to the right people.
tends to produce greater delays and confusion, not faster And the ‘right people’ increasingly appears to be site
execution. That’s because more people increase commu- reliability engineering (SRE) resources. More than three-
nication channels and, ultimately, cause confusion that quarters of organizations have adopted or plan to adopt
translates into delays that impact delivery, deployment, SRE operations. And when we look at plans for AIOps
and resolution when incidents inevitably occur. through that lens we find a clear connection: those who
Automation is generally accepted as the path to more have adopted or plan to adopt SRE are five times as like-
efficient operations and leads to the conclusion that ly to use or plan to use AI in an operational capacity.
AIOps is inevitable. The impact on the automation skills deficit is staggering.
While AIOps is the least likely to be in use or planned Organizations that have or plan to adopt SRE opera-
use with respect to operations, it is still on the radar for tions cited skills deficits at nearly half the rate of those
more than half (52%) of all respondents this year. who are sticking with traditional operational models.
Given the significant challenges faced by IT today
with respect to automation, AIOps is an option that Conclusion
cannot be ignored, especially given the rise in automa- The conclusion of our 2022 research is clear: CIOs and
technology leaders need to focus on modernizing ope-
rations in order to maintain the pace of digital transfor-
mation – or risk the consequences of falling behind more
digitally mature competitors.
Without a strong, flexible, and modern operational
practice, IT will struggle to maintain progress toward
Test-driven development of CI/CD a fully digital business powered by AI, data, and auto-
pipelines mation. This will become even more clear in subsequent
Lukas Pradel (Conciso GmbH) blogs as we explore results related to insights (spoiler:
CI/CD pipelines are becoming more still a significant problem) and enterprise initiatives and
popular as organizations begin to projects around data, security, and edge computing.
adopt Continuous Deployment and
therefore, they require deployments as Lori Mac Vittie is a strategic technologist with an em-
part of their pipelines. Hence, it is with good reason phasis on emerging architectures and technologies
that the DevOps community has been advocating including cloud and edge computing, digital transfor-
for treating CI/CD pipelines with the same diligence mation, and application delivery. Mac Vittie has over
as the application code itself, for example, when it twenty-five years of industry experience spanning ap-
plication development, IT architecture, and network and sys-
comes to security aspects, namely “DevSecOps”. A
tems’ operation. Prior to joining F5, Mac Vittie was an
key principle of this is that everyone is responsible award-winning technology editor at Network Computing Ma-
for the security of pipelines and that security aspects gazine. As an enterprise architect, she helped lead a global
are taken into consideration from the very beginning. transportation and logistics firm into the Internet age, and has
Another important lesson from software development developed software for Nokia phones, Autodesk, and regional
is consistently assuring that software quality pays off telecommunications firms. MacVittie is a prolific author on to-
pics spanning security, cloud, and enterprise architecture. She
in the long run. Therefore, state-of-the-art software
holds an M.S. in Computer Science from Nova Southeastern
development involves test-driven development. If the University.
same holds true for security, then why should pipelines
not be developed test-driven as well? After all, they
control the crucial deployment step of our applications Links & Literature
and faulty deployments will impact our users! In this
live-coding session, we will write a Jenkins pipeline [1] https://www.f5.com/company/blog/the-state-of-
from scratch in an entirely test-driven way and demon- application-strategy-2021-necessity-mother-of-motivation
strate how we can apply test-driven development to
CI/CD pipelines and employ the tools of test-driven [2] https://www.f5.com/company/news/press-releases/f5-
development such as unit testing, mocks, and asser- research-tradeoffs-of-accelerating-digital-transformation
tions to verify that our pipeline works correctly. [3] https://www.f5.com/company/blog/edge-2-0-manifesto-
redefining-edge-computing

jaxlondon.com 28
WHITEPAPER Software Architecture & Design

Three Key Performance Indicators

Garbage Collection
tuning success
story – reducing
young gen size
This article will take a look at a successful garbage collection tuning case study.
Simply by making a minor change, it resulted in a dramatic improvement in garba-
ge collection behavior for a popular application. Additionally, you will learn what
Key Performance Indicators (KPIs) you should be focusing on.

By Ram Lakshmanan tions vs the total amount of time it spends in processing


garbage collection activity. This metric is studied in Per-
When you tune garbage collection performance, you are centage. For example, if someone says his application’s
not only improving garbage collection pause time but GC throughput is 98%, it indicates the application is
also the overall application’s response time and reducing spending 98% of its time processing customer activity
cloud computing costs. Recently, we helped to tune the and the remaining 2% of the time processing Garbage
garbage collection behavior of a popular application. Collection activity.
Just by making a minor change, it resulted in a dramatic
improvement. Let’s discuss this garbage collection tu-
ning success story in this post.

Garbage Collection KPIs


There is a famous saying that “you can’t optimize so-
mething that you can’t measure“. When it comes to Is The 12 Factor App right about logs?
garbage collection tuning, there are only 3 primary Key Phil Wilkins (Capgemini UK))
Performance Indicators (KPIs) that you should be focu-
The 12 Factor Apps methodology
sing upon: states that we should treat logs as an
event stream and send all events to
• GC Pause Time stdout. But is this right? What are the
• GC Throughput implications of this? Is there an alternative that stays
• CPU Consumption true to this in spirit but offers more? In this session,
we’ll explore what the 12 Factor App says about logs
and the pros and cons of what it outlines as a meth-
When garbage collection runs, it pauses your applica-
odology. We will then look at some possible alternate
tion. ‘GC Pause time’ indicates the time your application options and how they could meet the spirit of the 12
is pausing during a garbage collection event. This metric Factor App Methodology but provide an easier path.
is studied in seconds or milliseconds. This session will include looking at Fluentd as men-
‘GC Throughput’ indicates the total amount of time tioned in the 12 Factor App methodology.
your application spends in processing customer transac-

jaxlondon.com 29
WHITEPAPER Software Architecture & Design

Fig 1: Baseline GC KPIs (generated by GCeasy)

Modern applications tend to create thousands of ob- How to source these KPIs?
jects to process even a simple request. Due to this, garba- Garbage collection logs are your best friend when it
ge collectors have to run constantly in the background comes to tuning garbage collection performance. You
to evict these thousands of objects that are created for can enable garbage collection logs on your application
every request. Thus, garbage collection tends to consu- by passing the JVM arguments given here [2]. I would
me a heavy amount of CPU. So, when you tune Garbage recommend enabling garbage collection logs always be
Collection performance, you should also study the CPU ON, as it provides rich information which can facilitate
consumption. To learn more about these KPIs, you can you to predict outages, troubleshoot production pro-
refer to this post [1]. blems, and help with capacity planning. Besides that,
enabling garbage collection doesn’t add any noticeable
overhead to your application [3].
Once the garbage collection log is enabled, you can
use free Garbage collection log analysis tools like GCea-
sy [4], IBM GC & Memory visualizer [5], HP Jmeter
[6], or Garbage Cat [7] to see the above-mentioned
Your tests are trying to tell you KPIs.
something Here is a post [8] that walks you through, how to do
Dr. Victor Rentea (Independent GC log analysis.
Trainer)
The old saying goes—tests are hard to Baseline garbage collection behavior:
write if the production design is crappy. Enough of the introduction. Let’s get back to the original
Indeed, writing unit tests gives you theme of this article. We enabled the garbage collection
one of the most comprehensive, yet brutal, feedback log on this popular application. We let the application
about the design of your production code, but if it run for a 24-hour period. Then we uploaded the gene-
comes too late, many developers can’t take it and they
rated GC log file to the GCeasy tool. The tool provided
will either stop testing or test superficially. At the other
end, others struggle to write contrived, fragile tests full insightful graphs and GC KPIs. This application’s GC
of mocks that end up frustrating them more than they throughput was 96.176% and the average pause time
help them. This talk reviews the main hints that unit was 12.429 seconds (Fig. 1).
tests provide you, from the most obvious improve- Basically, these GC KPIs are not good enough for high
ments to some of the most subtle design principles. throughput, low latency types of applications. This ap-
plication was running with the ‘Parallel GC’ algorithm.

jaxlondon.com 30
WHITEPAPER Software Architecture & Design

Fig 2: GC causes table (generated by GCeasy)

Fig 3: Benchmark GC KPIs (generated by GCeasy)

This application was configured to run with a 40GB young generation’s size, the larger the pause time. Thus,
heap size (i.e. -Xmx). In this 40GB heap size, 20GB the team decided to reduce the young generation size
(i.e50%) was allocated to the young generation and the
remaining 20GB to the old generation.
The above table (Fig. 2) from the GCeasy tool shows
the causes that were triggering the GC events. You can
notice that a significant amount of GC events were trig-
gered because of the ‘Allocation Failure’. This type of Deep Learning Fundamentals
‘Allocation failure’ GC events are triggered when the- Workshop
re is not sufficient memory to create new objects in the Leonardo De Marchi (idea.io)
young generation. You can notice that ‘Allocation Fai- Deep learning is becoming an indispen-
lure’ GC events alone cumulatively triggered 55 minutes sable tool, not only for data scientists
& 16 seconds of pause time. This is a very large amount but also for engineers and analysts. The
of pause time for a 24-hour period. applications of neural networks and
their impact keep increasing relentlessly: from com-
Reducing Young Generation size puter vision, to time series and NLP, it seems neural
networks are able to outperform all previous state of
If you notice the young generation size of this appli-
the art algorithms. We will go through the main DL
cation, it is quite large (i.e.20GB). Since the young topics such as activation functions, image argumenta-
generation’s size is very large, a lot of objects in this tion, different types of gradients, and neural network
generation have to be scanned and unreferenced objects architecture, all through clean and practical examples.
from this region have to be evicted. Thus, the larger the

jaxlondon.com 31
WHITEPAPER Software Architecture & Design

Fig 4: GC causes table (generated by GCeasy)

from 20GB to 1GB. The rationale is: If the young ge- You can notice that the ‘Allocation Failure’ GC events
neration size is small, then a smaller number of objects count has significantly increased from 259 to 3976.
needs to be scanned and evicted, thus the garbage coll- Since the young generation size has become small, the
ection pause times would be less. number of occurrences of ‘Allocation Failure’ GC events
increased. Even though the number of occurrences of
Benchmark Garbage collection behavior: ‘Allocation Failure’ increased, cumulatively pause time
After dropping the young gen size from 20GB to 1GB, reduced from ’55 minutes and 16 seconds’ to ‘8 minutes
we ran the application for the same 24-hour period in and 56 seconds’. It’s because the region size is small, so
the production environment. When we uploaded the ge- fewer number of objects have to be evicted from the me-
nerated Garbage collection log file in the GCeasy tool, it mory. Thus, as per our expectation, reducing young ge-
generated the below KPIs (Fig. 3): neration size improved the garbage collection behavior.
GC Throughput improved from 96.176% to 99.36%. WARNING: Reducing the young generation size won’t
Average GC pause time improved from 12.429 seconds always reduce the GC pause time. It depends on your
to 139ms. This is a phenomenal improvement. Eureka traffic volume, object type creation (i.e., short-lived or
moment. Below is how the GC causes table started to long-lived objects) of your application, and GC algorithm
look (Fig 4): configuration. Thus, don’t reduce your young generati-
on size based on this article, do your own proper due-
diligence and testing before changing the generation size.

Every single day, millions & millions of people in North


America – bank, travel, and commerce – use the ap-
plications that Ram Lakshmanan has architected. Ram
is an acclaimed speaker in major conferences on sca-
Modern Web Apps with Angular and lability, availability, and performance topics. Recently,
Spring Boot Workshop he has founded a startup, which specializes in troubleshooting
performance problems.
Kai Tödter (Siemens AG)
In this workshop, we will develop a
small but complete (client/server-
based) web application. The client Links & Literature
part is implemented with Angular,
TypeScript, and Bootstrap. The server part is based on [1] https://blog.gceasy.io/2016/10/01/garbage-collection-kpi/
Spring Boot, and we will also use Spring Data/REST/ [2] https://blog.gceasy.io/2017/10/17/what-is-garbage-
HATEOAS. We will develop a RESTful Web Service, collection-log-how-to-enable-analyze/
which is enriched with hypermedia. Kai will explain
[3] https://blog.gceasy.io/2021/08/17/overhead-added-by-
the basics of Spring Boot and the used frameworks, as
garbage-collection-logging/
well as the general principles of REST and HATEOAS
(Hypermedia As The Engine Of Application State, [4] https://gceasy.io/
an important REST architecture principle). For client [5] https://www.ibm.com/support/pages/java-sdk-monitoring-
development, Kai will give a brief introduction of and-post-mortem
TypeScript, Angular (the latest version), Bootstrap, and
[6] https://myenterpriselicense.hpe.com/cwp-ui/free-software/
the standard JavaScript development tools like npm,
Jasmine, Webpack, etc. At the end of the day, we will [7] https://code.google.com/archive/a/eclipselabs.org/p/
have developed a complete web application using all garbagecat
those technologies. [8] https://blog.gceasy.io/2022/02/07/how-to-do-gc-log-
analysis/

jaxlondon.com 32

You might also like