JAX - London - Whitepaper Java Fresh Brewed 2022
JAX - London - Whitepaper Java Fresh Brewed 2022
jaxlondon.com
© LoopAll/Shutterstock.com
DOSSIER Microservices
Contents
Editorial3
jaxlondon.com 2
Editorial
Sarah Schlothauer
@jaxlondon
jaxlondon.com
WHITEPAPER Java Core & JVM Languages
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?
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")
jaxlondon.com 6
WHITEPAPER Java Core & JVM Languages
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 }
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”.
jaxlondon.com 10
WHITEPAPER Java Core & JVM Languages
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
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.
jaxlondon.com 12
WHITEPAPER Java Core & JVM Languages
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:
jaxlondon.com 13
WHITEPAPER Java Core & JVM Languages
jaxlondon.com 14
WHITEPAPER Java Core & JVM Languages
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.
jaxlondon.com 15
WHITEPAPER Java Core & JVM Languages
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
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.
jaxlondon.com 17
WHITEPAPER Agile, People & Culture
jaxlondon.com 18
WHITEPAPER Agile, People & Culture
jaxlondon.com 19
WHITEPAPER Microservices & Service Mesh
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.
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.
jaxlondon.com 21
WHITEPAPER Microservices & Service Mesh
jaxlondon.com 22
WHITEPAPER Microservices & Service Mesh
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 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
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
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.
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
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.
jaxlondon.com 29
WHITEPAPER Software Architecture & Design
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
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
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.
jaxlondon.com 32