You are on page 1of 35

FACILITATING THE SPREAD OF KNOWLEDGE AND INNOVATION IN PROFESSIONAL SOFTWARE DEVELOPMENT

Java 9
and Beyond
eMag Issue 37 - January 2016

ARTICLE

ARTICLE

Programming with
modularity and
Project Jigsaw

Java 9s New HTTP/2


and REPL

ARTICLE

A Post-Apocalyptic
sun.misc.Unsafe
World
Java 9 and Beyond // eMag Issue 37 - Jan 2016
1

Java 9s New HTTP/2 and


REPL

Programming with
modularity and
Project Jigsaw
A Tutorial Using the Latest Release Candidate
Project Jigsaw is the hallmark feature of Java
9, the next major version release of Java, and is
destined to bring modular programming into the
Java mainstream. After years of negotiating and
myriad JSRs and JEPs, Jigsaw is starting to take
its final form. This tutorial considers all aspects of
programming and migration to Project Jigsaw.

Java 9 will not just be about modularity; it is targeting a large


number of additional pieces of functionality. In this article
Ben Evans dives into HTTP/2 support and the JShell REPL
(Read-Eval-Print-Loop) that brings shell-based interactive
Java development, two new JEPs that may well have the biggest impact on developers working lives during the lifetime
of Java 9.

Case for Defaulting to G1


Garbage Collector in Java 9
In this article, GC expert Monica Beckwith makes the case
for JEP 248, the proposal to make G1 the default garbage
collector in OpenJDK 9.

A Post-Apocalyptic sun.misc.
Unsafe World
The removal of sun.misc.Unsafe and other private APIs in
Java 9 has in recent weeks divided the Java community perhaps as never before in its 20 year history. Even though a
resolution has now been proposed and a migration path presented, the big question remains: What will a post sun.misc.
Unsafe world look like?

The OpenJDK Revised Java Memory Model


The existing Java Memory Model covers a lot in terms of Java language semantic guarantees. In this
article we will delve into a few of those semantics, and attempt to communicate the motivation for
an update to the existing Java Memory Model

FOLLOW US

CONTACT US
GENERAL FEEDBACK feedback@infoq.com
ADVERTISING sales@infoq.com
EDITORIAL editors@infoq.com

facebook.com
/InfoQ

@InfoQ

google.com
/+InfoQ

linkedin.com
company/infoq

the Java queue lead at InfoQ. Inducted as an


VICTOR isOracle
Java Champion in 2012, Victor works at
GRAZI Nomura Securities on building core tools, and

as a technical consultant and Java evangelist. He is also a frequent


presenter at technical conferences. Victor hosts the Java Concurrent
Animated open source project on SourceForge.

A LETTER FROM
THE EDITOR
If there were ever any question that Java was the
de facto standard for server side enterprise development, Java 8 has certainly quelled that one. The world
now anxiously awaits Java 9 and the innovations it
promises. Oracle has slated Java 9 for a March 2017
release.
In this eMag, we take a look at whats on the
scheduled horizon for Java 9 and beyond.
Project Jigsaw is the hallmark feature of Java 9
and is destined to bring modular programming into
the Java mainstream. After years of negotiating and
myriad JSRs and JEPs, Jigsaw is starting to take its final form. Nicolai Parlog gives us the definitive guide
to all aspects of programming and migration to Project Jigsaw.
Then Ben Evans takes a look at two long awaited
Java features, HTTP/2 and REPL. HTTP/2 addresses annoying problems coming from the rather rusty HTTP
support in Java. REPL is a shell scripted version of Java
that allows developers to quickly and interactively

test Java code snippets without having to deal with


class structures and compilers.
If Java didnt invent the science of Garbage collection, it has almost certainly contributed more than
any other language to that technology. Garbage First
(affectionately know as G1GC) is the latest offering in
that space, and promises to support huge heaps with
minimal stop-the-world pauses. In this piece, former
Oracle GC performance lead Monica Beckwith weighs
the benefits of making G1GC the default against protests that it might not be ready for prime time.
Then low latency expert Christoph Engelbert
looks at another controversial issue, the deprecation
of sun.misc.Unsafe, a widely-used little class that to
date has broken all of the rules of Java safety.
Finally, the Java Memory Model has served Java
well for all of these years but over time optimizations
and alternatives have been requested. Monica Beckwith looks at some of the modifications to the Java
Memory Model being discussed for Java 10.

Theres nothing about Java


that AppDynamics doesnt see.
AppDynamics gives you the visibility to take command
of your Java applications performance, no matter
how complicated or distributed your environment is.

Events
Health Rule Violations Started

IIS

Internet
Information
Services

Device

Overall Application Performance

AppDynamics Internal Diagnostics

Business Transaction Health

Java

1 critical, 0 warning, 36 normal


Server Health
0 critical, 5 warning, 1 normal

Java

Transaction Scorecard

Java

Normal

Java

83.1%

963

Slow

0.3%

Very Slow

1.3%

15

Stall
Errors

0.2%

15.1%

175

Shipments DB

Java

When your business runs on Java, count on AppDynamics to give you the complete visibility you need to be
sure they are delivering the performance and business results you need no matter how complex,
distributed or asynchronous your environment, live in production or during development.
See every line of code. Get a complete view of your environment with deep code diagnostics and
auto-discovery. Understand performance trends with dynamic baselining. And drastically reduce time
to root cause and remediation.
See why the worlds largest Java deployments rely on the AppDynamics Application Intelligence
Platform. Sign up for a FREE trial today at www.appdynamics.com/java.

appdynamics.com

Advertising Feature

Whats exciting about Java 9 and Application


Performance Monitoring

by Aakrit Prasad

Principal Product Manager of APM products at AppDynamics

Constant innovation in software is driving us toward a software revolution. That may be how the 21st century
will be best remembered. Among the popular software languages out there, however, Java continues to have
the largest industry footprint, running applications around the globe that produce a combined annual revenue
measuring trillions of dollars.
Thats why keeping up on the JDK is a high priority. Despite having a massive API to improve programming
productivity, Java has also grown due to its high-performance yet scalable JVM runtime, which ranks among
the fastest computing applications. As Javas footprint expands, JDK innovations continue to impact billions of
lines of code. As AppDynamics continues to grow, our focus towards supporting Java is only furthered by our
customer use and industry adoption of the JVM.
Discussion of Java 9 have been growing since the release of Java 8 in March 2014. The scope of various
JDK enhancements originally targeted for Java 9 has narrowed as the proposed release date of September 2016
has approached. Over 30 key enhancements, those with the potential for broadest impact, will be shared, and
discussion of some of these follows.

Project Jigsaw

Project Jigsaw contains some of the


JDK 9 enhancements with greatest
impact. Jigsaws primary goals are to
make the JDK more modular and to
enhance the build system. The needs
to make Java more scalable for smaller
computing devices, to make it secure,
and to improve performance and developer productivity have driven Jigsaw. With the advent of the Internet
of Things (IoT), enabling Java to run
on smaller devices is instrumental for
continued growth but as Javas footprint expands, the vast permutation
of computing services it runs on have
made it more prone to security targeting and performance lags. With a more
modular JDK, developers can significantly reduce the number of libraries
needed to build features, thereby reducing security risks and the size of
an application while increasing performance (e.g. improving code cache and
class-loader footprint, etc.).

HTTP/2 Client

Among the most popular Web protocols, HTTP has been getting its own
upgrade to HTTP/2 (with inspiration
from Googles SPDY/2), which boasts
significant network performance
gains. Java 9 will get its own HTTP
client API that implements HTTP/2
and WebSocket to replace the legacy
HttpURLConnection, which predates
HTTP/1.1 and has limitations such as
the one thread per request/response
behavior. Using HTTP/2 in Java 9, applications will perform and scale better with memory usage on par with
or lower than HttpURLConnection,
Apache HttpClient, and Netty.

jShell

In jShell, also referred to as Java REPL


(read-eval-print-loop), JDK 9 users will
find a shell-like interface to interactively evaluate declarations, statements,
and expressions in Java. Like when
they use Python or Ruby interpreters
or other JVM languages like Scala and
Groovy, Java users will be able to run
Java code without needing to wrap in
classes or methods, allowing for much
easier, faster learning and experimentation. Furthermore, as Java becomes
a less syntactically verbose language
with features like Lambda introduced
in JDK 8 (shared in our Java 8 blog last
year), having a shell-like interface becomes more practical for ad hoc testing.

Segmented Code Cache

The JVM codecache is critical to application performance and can be set


at startup time using the -XX:InitialCodeCacheSize=32m flag. When the
codecache memory is exhausted, the
JVM losses JIT and goes into interpreted mode, significantly affecting application runtime performance. In Java
9, this section of memory is getting
divided into the three distinct heap
segments in order to improve performance and enable future extensions:
JVM internal (non-method) code, profiled-code, and non-profiled code.

Other Notable mentions

Other notable changes in JDK 9 will


include making the G1 collector the
default, adding a Microbenchmark
testing suite that extends the current
JMH, and the removal of some aged
and unsupported performance tools
such as JVM TI hprof and jHat.

Summary

Although programming languages


tend to come and go, Java is here to
stay (least for the foreseeable decade)
as one of the most popular and widely adopted languages with its highly
performing, scalable runtime. JDK innovations have a large impact on the
worlds computing infrastructure. By
staying current with whats in the next
JDK, firms running JVM services can
intelligently plan and prioritize innovation initiatives that are complementary to language improvements. All
those excited yet impatient developers
looking to get to work on the future
can access the latest JDK 9 builds here:
https://jdk9.java.net/download/

Reference: http://openjdk.java.net/projects/jdk9/

Read online on InfoQ

Programming with modularity and Project Jigsaw.

A Tutorial Using the Latest Early Access Build

Nicolai Parlog is a software developer and Java enthusiast. He constantly reads, thinks and
writes about Java, and codes for a living as well as for fun. Hes a long tail contributor to several
open source projects and blogs about software development on CodeFX. You can follow Nicolai
on Twitter.

Software can be seen as a system of interacting parts and in Java it is


common to package each of those parts in its own JAR. Conceptually a
part consists of three properties: a name, a public API for the rest of the
world to use, and dependencies on other parts. This graph-like model
helps developers and tools dissect, analyse, and work with software
systems.
But none of those properties exist inside the Java
runtime, which uses the classpath to access a bunch
of JARs and simply rolls them all into one big ball of
mud. Any distinction between JARs is entirely lost
and only a flat set of packages remains, with no capability of further validation. So important questions
like are these all required JARs?, are these even the
correct JARs?, are there conflicts?, or are only public APIs used? cannot be answered by the running
JVM.
So on one hand there is a well-structured model of how a system is modularized and how its parts
6

depend on each other. And on the other hand there


is the runtime reality of a single, almost entirely unstructured namespace. This mismatch is the driving
force behind what is affectionately known as JAR
hell, and dependencies on internal APIs. It also causes bad start-up performance and weakens security.
Project Jigsaw will enhance the compiler and
runtime to come closer to the structured model. Its
main goals are reliable configuration (by declaring
dependencies) and strong encapsulation (by hiding
internals) and its agent for both is the concept of
modules.

Java 9 and Beyond // eMag Issue 37 - Jan 2016

Introducing Modules
Quoting from the highly recommended design overview State of the Module System by Oracle chief architect Mark Reinhold:
A module is a named, self-describing collection of
code and data. Its code is organized as a set of packages containing types, i.e., Java classes and interfaces; its
data includes resources and other kinds of static information.
To control how its code refers to types in other
modules, a module declares which other modules it requires in order to be compiled and run. To control how
code in other modules refers to types in its packages, a
module declares which of those packages it exports.
So in contrast to a JAR, a module has a name
that is recognized by the JVM, declares which other
modules it depends on, and defines which packages
are part of its public API.
Name
Module names can be arbitrary but must not conflict.
To that end it is recommended to use the standard
inverse-domain-name pattern of packages. While
this is not obligatory it will often mean that the module name is a prefix of the packages it contains.
Dependencies & Readability
A module lists the other modules it depends on to
compile and run. Again from the State of the Module System:
When one module depends directly upon another
[...] then code in the first module will be able to refer to
types in the second module. We therefore say that the
first module reads the second or, equivalently, that the
second module is readable by the first.
[]
The module system ensures that every dependence is fulfilled by precisely one other module, that no
two modules read each other, that every module reads
at most one module defining a given package, and that
modules defining identically-named packages do not
interfere with each other.
This concept of readability is the basis of reliable configuration: When any condition is violated,
the module system refuses to compile or launch
the code; an immense improvement over the brittle
classpath model.
Exports & Accessibility
A module lists the packages it exports. A type in one
module is only accessible by code in another module
if:
the type is public
the containing package is exported by the first
module
the second module reads the first

This means that public is no longer really public. A public type in a non-exported package is as
hidden from the outside world as a non-public type
in an exported package. So public is the new private, being even more hidden than package-private
types are today, because the module system does
not even permit access via reflection. As Jigsaw is
currently implemented, command line flags are the
only way around this.
So accessibility builds on top of readability and
the export clauses, creating the basis for strong encapsulation, where a module author can clearly express which parts of the modules API are public and
supported.

Example: Creating Our First Module


Say we have an application that monitors microservices running in our network. It periodically contacts
them and uses their responses to update a database
table as well as a nifty JavaFX UI. For the time being,
lets assume that the application is developed as a
single project without any dependencies.
Now lets switch to Java 9 with Jigsaw! (The
early access builds are available on java.net - the
code samples and commands presented in this article were created for build 96 from December 22nd.)
While jdeps, the Java dependency analyzer, already
exists in JDK 8, we need to use the JDK 9 version so
that it knows about modules.
The first thing to note is that we can simply
choose to ignore modules. Unless the code is relying
on internal APIs or some other JDK implementation
details (in which case things will break), the application can be compiled and executed exactly as with
Java 8. Simply add the artifact (and its dependencies
if it has any) to the classpath and call main. And voil,
it runs!
To move the code into a module we must create a module descriptor for it. This is a source code file
called module-info.java in the source directorys
root:
001 module com.infoq.monitor {
002 // add modules our application
requires
003 // add packages our application
exports
004 }
Our application is now a module with the name
com.infoq.monitor. To determine which modules

it depends on, we can use jdeps:

001 jdeps -module ServiceMonitor.jar


This will list the packages our application uses
and, more importantly, from which modules they
come: java.base, java.logging, java.sql,

Java 9 and Beyond // eMag Issue 37 - Jan 2016

javafx.base,
graphics.

javafx.controls,

javafx.

With our dependencies covered we can now


think about which packages we might export. Since
we are talking about a stand-alone application, we
wont export anything.
Together we get:
001 module com.infoq.monitor {
002 requires java.base; // see more
about that below
003 requires java.logging;
004 requires java.sql;
005 requires javafx.base;
006 requires javafx.controls;
007 requires javafx.graphics;
008 // no packages to export
009 }
Compiling is the same as without Jigsaw except
we have to include module-info.java in the list of
source files:
001 javac -d classes/com.infoq.monitor
${source files}
Now that all classes were compiled into classes/com.infoq.monitor, we can create a JAR from
them:

001 jar -c
002 --file=mods/com.infoq.monitor.jar \
003 --main-class=com.infoq.monitor.
Monitor \
004 ${compiled class files}
The new --main-class can be used to specify the class containing the applications entry point.
The result is a so-called modular JAR, which we will
discuss further below.
In stark contrast to the old model, there is a
whole new sequence to launch the application. We
use the new -mp switch to specify where to look for
modules, and -m to name the one we want to launch:
java -mp mods -m com.infoq.monitor
To understand this a little better, lets talk about
how the compiler and the virtual machine handle
modules.

Java And The Modules

Kinds Of Modules
The JDK itself was modularized and consists of about
80 platform modules (have a look at them with java
-listmods). The ones that will be standardized for
Java 9 SE are prefixed with java., the JDK-specific
ones with jdk..
Not all Java environments have to contain all
platform modules. On the contrary, one goal of Jigsaw is the scalable platform, which means that it is
8

easy to create a runtime with just the desired modules.


All Java code depends on Object and virtually
all code uses basic features like threading and collections. These types can be found in java.base,
which plays a special role; it is the only module that
the module system knows about, and since all code
depends on it, all modules automatically read it.
So in our example above, we would not need to
declare a dependency on java.base.
Non-platform modules are called application
modules and the module used to launch an application (the one containing main) is the initial module.
Modular JARs
As we have seen above, Jigsaw still creates JARs, albeit with the new semantics. If they contain a module-info.class they are called modular JARs,
about which State of the Module System says:
A modular JAR file is like an ordinary JAR file in all
possible ways, except that it also includes a module-info.class file in its root directory.
Modular JARs can be put on the classpath as
well as on the module path (see below). This allows
projects to release a single artifact and let its users
decide between the legacy or the modular approach
to application building.
Module Path
Platform modules are part of the currently used environment and hence are easily available. To let the
compiler or VM know about application modules, we
have to specify a module path with -mp (as we have
done above).
The platform modules in the current environment and the application modules from the module
path together comprise the universe of observable
modules. Given that set and an initial module contained therein the virtual machine can create a module graph.
Module Graph
Starting from the initial application module, the
module system resolves all of its transitive dependencies . The result is the module graph where modules are nodes and a dependency of one module on
another is a directed edge.
For our example, that looks like this: (Figure 1)
The platform modules are shown in blue, where
the brighter modules are the ones we depend on directly and the darker ones transitive dependencies.
The ubiquitous java.base is not shown; remember,
all modules implicitly depend on it.

Java 9 and Beyond // eMag Issue 37 - Jan 2016

Figure 1

Example: Splitting Modules


With this understanding of how modules are handled by the compiler and virtual machine, lets start
to think about how to divide our application into
modules.
Our architecture consists of the following parts:
contacting the microservices and creating statistics
updating the database
presenting the JavaFX user interface
wiring the pieces
Lets go ahead and create a module for each:
com.infoq.monitor.stats
com.infoq.monitor.db
com.infoq.monitor.ui
com.infoq.monitor
The Jigsaw Quick-Start Guide and the JDK itself
propose to have a folder for each module below the
projects root source folder. In our case this would
have the following structure: (Figure 2)

This tree is shown truncated here, but each


com directory represents the package of the same
name and would contain more subdirectories and
eventually the modules code.
The statistics module depends on java.base
(but as we learned, we dont have to list that) and
uses Javas built-in logging facilities. Its public API
allows to request aggregated and detailed statistics
and is contained in a single package.
001 module com.infoq.monitor.stats {
002 requires java.logging;
003 exports com.infoq.monitor.stats.get;
004 }
To reiterate the accessibility rules: non-public
types in com.infoq.monitor.stats.get and all
types in other packages are completely hidden from
all other modules. Even the exported package is only
visible to modules that read this one.
Our database module also logs and obviously
requires Javas SQL features. Its API consists of a simple writer.

Java 9 and Beyond // eMag Issue 37 - Jan 2016

Service Monitor
src

com.infoq.monitor

com ...

module-info.java

com.infoq.monitor.db

com ...

module-info.java

com.infoq.monitor.stats

com ...

module-info.java

com.infoq.monitor.ui

com ...

module-info.java

Figure 2

001
002
003
004
005

module com.infoq.monitor.db {
requires java.logging;
requires java.sql;
exports com.infoq.monitor.db.write;
}

The user interface obviously requires the platform modules that contain the employed JavaFX
features. Its API consists of the means to launch the
JavaFX UI. This will return a model that uses JavaFX
properties. The client can update the model, and the
UI will show the new state.
001
002
003
004
005
006
007

module com.infoq.monitor.ui {
requires javafx.base;
requires javafx.controls;
requires javafx.graphics;
exports com.infoq.monitor.ui.launch;
exports com.infoq.monitor.ui.show;
}

Now that we covered the actual functionality,


we can turn our attention to the module that wires
all of the parts together. This module requires each
of our three modules, plus Javas logging facilities.
Since the UI requires that module to work with JavaFX properties, we depend on it as well. Since the
main module is not used by anybody else, it has no
API to export.
001 module com.infoq.monitor {
002 requires com.infoq.monitor.stats;
003 requires com.infoq.monitor.db;
004 requires com.infoq.monitor.ui;
005 requires javafx.base; // to update
the UI model
006 requires java.logging;
007 // no packages to export
008 }

10

Its a little unwieldy that we have to explicitly require javafx.base, but if we dont, we couldnt call
any code from javafx.beans.property, which we
must do to work with the model. So in a way com.
infoq.monitor.ui is broken without javafx.
beans.property. For this case the Jigsaw prototype
provides the concept of implied readability, which we
will cover shortly.
Our modularization creates a very different
module graph: (Figure 3)
Now lets take a look at some of the commands
used to compile, package, and launch our freshly
modularized application. This is how we can compile
and package modules that have no dependencies
outside of the JDK itself:
001 javac -d classes/com.infoq.monitor.
stats ${source files}
002 jar -c
003 --file=mods/com.infoq.monitor.stats.
jar \
004 ${compiled class files}
Like before and exactly as with Java 8, we compile the modules source, write the resulting files into
a subfolder of classes with the modules name, and
create a JAR in mods. Its a modular JAR because the
class files include the compiled module descriptor
module-info.class.
More interesting is how we process our only
module with dependencies on other application
modules:
001
002
003
004
005
006
007
008

javac \
-mp mods \
-d classes/com.infoq.monitor \
${list of source files}
jar -c
--file=mods/com.infoq.monitor.jar \
--main-class=com.infoq.monitor.
Monitor \
${compiled class files}
java -mp mods -m com.infoq.monitor

The compiler needs the application modules


we created earlier, and we point it there by specifying the module path with -mp mods. Packaging and
launching is as before but now mods contains not
just a single module but four of them.
The JVM will start by looking for module com.
infoq.monitor because we specified that as our
initial module. When it finds that, it will try to transitively resolve all of its dependencies inside the universe of observable modules (in this case, our four
application modules and all platform modules).
If it can build a valid module graph, it will finally look up the main method specified with --mainclass=com.infoq.monitor.Monitor and launch
our application. Otherwise it will fail with an excep-

Java 9 and Beyond // eMag Issue 37 - Jan 2016

tion informing us of the violated condition, e.g. a


missing module or a cyclic dependency.

Implied Readability
A modules dependency on another module can take
two forms.
First, there are dependencies that are consumed internally without the outside world having
any knowledge of them. Take for example Guava,
where the code depending on a module does not
care at all whether it internally uses immutable lists
or not.

This is the most common case and covered by


readability as described above, where a module can
only access another modules API if it declares its dependency on it. So if a module depends on Guava,
other modules are left in blissful ignorance of that
fact and would not have access to Guava without declaring their own explicit dependencies on it.
But there is another use case where the dependency is not entirely encapsulated, but lives on the
boundary between modules. In that scenario one
module depends on another, and exposes types
from the depended-upon module in its own public

Java 9 and Beyond // eMag Issue 37 - Jan 2016

11

API. In the example of Guava a modules exposed


methods might expect or return immutable lists.
So code that wants to call the dependent module might have to use types from the depended-upon module. But it cant do that if it does not also
read the second module. Hence for the dependent
module to be usable, client modules would all have
to explicitly depend on that second module as well.
Identifying and manually resolving such hidden dependencies would be a tedious and error-prone task.
This is where implied readability comes in:
[We] extend module declarations so that one
module can grant readability to additional modules,
upon which it depends, to any module that depends
upon it. Such implied readability is expressed by including the public modifier in a requires clause.
In the example of a modules public API using
immutable lists, the module would grant its readability to Guava to all other modules depending on it by
requiring it publicly. In this way its API is immediately
usable.
Example: Implying Readability
Lets turn to our UI module, which exposes a model
that uses types from the module javafx.base in its
API. We can now change the module descriptor so
that it publicly requires that module:
001 module com.infoq.monitor.ui {
002 // expose javafx.base to modules
depending on this one
003 requires public javafx.base;
004 requires javafx.controls;
005 requires javafx.graphics;
006 exports com.infoq.monitor.ui.launch;
007 exports com.infoq.monitor.ui.show;
008 }
Our main module can now implicitly read javafx.base and no longer has to explicitly depend
on it, since its dependency com.infoq.monitor.ui
exports it:
001
002
003
004
005

module com.infoq.monitor {
requires com.infoq.monitor.stats;
requires com.infoq.monitor.db;
requires com.infoq.monitor.ui;
// we dont need javafx.base anymore
to update the UI model
006 requires java.logging;
007 // no packages to export
008 }

While this changes why com.infoq.monitor reads com.infoq.monitor.stats it does not


change the fact that it does read it. Consequently
this changes neither our module graph nor the com-

12

mands required to compile and launch the application.


Beyond Module Boundaries
To quote once again the design overview:
In general, if one module exports a package containing a type whose signature refers to a package in a
second module then the declaration of the first module
should include a requires public dependence upon
the second. This will ensure that other modules that depend upon the first module will automatically be able
to read the second module and, hence, access all the
types in that modules exported packages.
But how far should we take this? Look, for example, at the java.sql module. It exposes the interface Driver, which contains a public method getParentLogger() returning a Logger. Because of
that the module publicly requires java.logging. So
any module using Javas SQL features can also implicitly access the logging API.
With that in mind, lets have a second look at
our database module:
001
002
003
004
005

module com.infoq.monitor.db {
requires java.logging;
requires java.sql;
exports com.infoq.monitor.db.write;
}

Technically the declaration of requiring java.


logging is not needed and might seem redundant.

So should we drop it?


To answer this question we have to look at how
exactly com.infoq.monitor.db uses java.logging. Our
module might only need to read it so we are able
to call Driver.getParentLogger(), do something with
the logger (e.g. log a message) and be done with it.
In this case our codes interaction with java.logging
happens in the immediate vicinity of its interaction
with Driver from java.sql. Above we called this the
boundary between com.infoq.monitor.db and java.
sql.
Alternatively we might be using logging
throughout com.infoq.monitor.db. Then, types from
java.logging appear in many places independent of
Driver and can no longer be considered to be limited
to the boundary of com.infoq.monitor.db and java.
sql.
With Jigsaw being cutting edge, the community still has time to discuss such topics and agree on
recommended practices. My take is that if a module is used on more than just the boundary to another module it should be explicitly required. This
approach clarifies the systems structure and also future-proofs the module declaration for refactorings.
So as long as our database module uses logging independently of the SQL module I would keep it.

Java 9 and Beyond // eMag Issue 37 - Jan 2016

Aggregator Modules
Implied readability opens up the path to so-called
aggregator modules, which contain no code on their
own but aggregate a number of other APIs for easier
consumption. This is already being employed by the
Jigsaw JDK, which models compact profiles as modules that simply expose the very modules whose
packages are part of the profile.
In case of our microservice monitor we could
envision a single API module aggregating the modules for statistics, user interface and data, so that the
main module only has a single dependency:
001 module com.infoq.monitor.api {
002 requires public com.infoq.monitor.
stats;
003 requires public com.infoq.monitor.
db;
004 requires public com.infoq.monitor.ui;
005 // implied readability is not
transitive
006 // so we have to explicitly list
`javafx.base`
007 requires public javafx.base
008 }
009 module com.infoq.monitor {
010 requires com.infoq.monitor.api;
011 requires java.logging;
012 // no packages to export
013 }
This is useful in principal, but offers no particular advantage in this simple example.

Services
So far we have covered dependencies that are determined and declared at compile time. A looser
coupling can be achieved if a dependency takes
the form of a service, where one or more modules
provide a functionality, abstracted behind a single
type, and others consume instances of that type. The
module system can be used by the consumer to discover providers. This implements the service locator
pattern, where the module system itself acts as the
locator.
A service is a set of interfaces and (usually abstract) classes that provide a cohesive feature. All involved types must be accessible from a single type
(likely an interface) so that one can be used to load
the service.
A service provider module contains one or more
implementations of a service. For each it includes a
provides X with Y; clause in its module descriptor, where X is the fully qualified name of the service
interface and Y the fully qualified name of the implementing class. Y needs to have a public, parameterless constructor so that the module system can
instantiate it.

The service consumer module has to read the


service module and include a uses X; clause in its
descriptor. At runtime it can then call ServiceLoader.load(Class<X>) and get a loader for the service
interface. The loader is iterable and contains instances of all classes that implement X and were provided
by service provider modules.
When services are used as described here, the
coupling is not only loosened at compile time (because the consumer does not declare dependencies
on the providers). It is also loose at runtime because
the module system will create no read edge from
consumer to provider.
Another interesting aspect is that the set of
available providers for a service is defined by the
module path (i.e. usually at launch time). Exactly
those observable modules that provide implementations of a service will be available at runtime via the
service loader. So a systems behavior can be influenced by editing the content of its module path and
restarting it.
Example: Creating And Using Services
In our example we have a module com.infoq.monitor.stats, which we said contacts the services
running in our network and creates statistics. This
sounds like a lot of work for a single module, but we
can split it up.
Watching individual services is a uniform task
so we create an API for that and put it into the new
module com.infoq.monitor.watch. The service
interface is called com.infoq.monitor.watch.
Watcher.
We are now free to create one or more modules
with implementations for concrete microservices.
Lets call these modules com.infoq.monitor.
watch.login, com.infoq.monitor.watch.shipping and so forth. Their module descriptors are as
follows:
001 module com.infoq.monitor.watch.login
{
002 // we need the module defining the
service we are providing;
003 // we imply readability so this
module is usable on its own
004 requires public com.infoq.monitor.
watch;
005 provides com.infoq.monitor.watch.
Watcher
006
with com.infoq.monitor.watch.
login.LoginWatcher;
007 }
Note that they only provide implementations
of Watcher but export no packages.
With all the code that contacts microservices
carved out of com.infoq.monitor.stats, we now

Java 9 and Beyond // eMag Issue 37 - Jan 2016

13

Figure 4
have to make sure that it still has access to that functionality. Its new module-info.java:
001
002
003
004

module com.infoq.monitor.stats {
requires java.logging;
requires com.infoq.monitor.watch;
// we have to declare which service
we are depending on
005 uses com.infoq.monitor.watch.Watcher;
006 exports com.infoq.monitor.stats.get;
007 }

Somewhere in its code we can now do this:


001 List<Watcher> watchers = new
ArrayList<>();
002 ServiceLoader.load(Watcher.class).
forEach(watchers::add);
That produces a list containing one instance of
each Watcher implementation that was provided by
modules on the module path. From here on out the

14

code would be similar to before, i.e. contacting the


services and creating statistics.
Limiting our module graph to com.infoq.
monitor.stats and below (because everything
else is unchanged) our new version looks as follows:
(Figure 4)
Note how the arrows all point towards the new
module; a typical example for the dependency inversion principle.
Compilation, packaging and launching is like
before (except that now we have more modules).

Migration
So far we have discussed the scenario where a complete application including all its dependencies was
turned into modules. But when Jigsaw is first removed from its shiny new package, that will not be
very common; most projects will have dependencies
on libraries that were not yet adapted to work with
the module system, and over which they will have no
control.

Java 9 and Beyond // eMag Issue 37 - Jan 2016

The Jigsaw team has tackled this problem


head-on and provides a gradual migration path to
modularization. For this they introduced two kinds
of modules that we have not yet discussed.
Kinds Of Modules II
We already know about platform modules and application modules. They are fully aware of the module system, and their defining characteristic are
their module descriptors. Because these give them a
name, they are called named modules.
There are two other types of modules for artifacts that are not aware of the module system.
Before Jigsaw, all types loaded from the classpath ended up in the same space where they could
freely access each other. This unstructured space
continues to exist: Each class loader has a unique unnamed module, to which it assigns all types it loaded
from the classpath.
Unnamed modules read all other modules and
export all packages. Because a modularized application should not depend on the random content
of the classpath, named modules can not require
unnamed modules and are hence not able to read
them.
But an artifact without a module descriptor can
also be placed on the module path. In this case, the
module system will create a fully fledged module for
it, called an automatic module.
An automatic modules name is derived from
the artifacts file name, it can read all other modules
and exports all its packages. Because the module
system can easily check at launch time whether any
specific automatic module is present on the module path, named modules can depend on them and
hence read them.
So in the common case of a single application
class loader, the applications universe of observable
modules can consist of:
named platform modules as they are contained
in the run time
one named application module for each artifact
on the module path that has a module descriptor
one automatic module for each artifact on the
module path that does not have a module descriptor
a unique unnamed module composed of all artifacts on the classpath, regardless of whether
they have module descriptors or not (with several
application class loaders there would be several
unnamed modules)
Migration Strategies
These kinds of modules open up the path to a gradual migration to the module system. (Note that module relationships are not the only hurdle, though.)

As has been stated above, the whole application, including all of its dependencies, can simply be
put on the classpath. This is a crucial escape hatch in
case some problem prevents a migration.
We can now see why that approach works: All
artifacts on the classpath get rolled into the unnamed
module, where all types can freely access each other.
To use Javas public API they have to access the platform modules, which they can do since the unnamed
module reads all other observable modules.
A bottom-up migration starts with dependency-free artifacts, which can immediately be modularized. Building on that, other projects can move to
Jigsaw.
Clients can put modular JARs on the module
path and reference them by name if their projects
were migrated. Even if not and their code still comes
from the classpath, it can access the migrated artifacts because the unnamed module can read all
other modules. Or clients can decide to put modular
JARs on the classpath.
This approach works best for library projects
with few, well-maintained dependencies. But as the
number of dependencies grows, projects might not
be willing to wait for all of them to be modularized.
This is especially true of large Java applications,
which might prefer to opt for another approach.
A top-down migration starts with creating module descriptors for all artifacts of a project. They need
names and must specify which other internal artifacts they depend on and which packages they want
to export.
This process will naturally be confronted with
external dependencies. If Jigsaw-aware versions
exist for them and can be used, thats great. If not,
automatic modules are the way to go: The projects
artifacts require modules with the name that Jigsaw
derives from the artifact file names, and the artifacts
are placed on the module path.
It is sufficient to do this for direct dependencies
so that the new application modules can access them.
The dependencies likely bring transitive dependencies with them. But because the direct dependencies
were turned into automatic modules, which read all
other modules including the unnamed one, their dependencies can be put on the classpath.
For large projects this manual approach becomes unusable and build tools must help. Gradle
and Maven have already started to work on Jigsaw-related features.
More details about migration can be found in
the JavaOne talk Advanced Modular Development by
Alex Buckley and Alan Bateman, both members of
the Jigsaw team at Oracle.

Java 9 and Beyond // eMag Issue 37 - Jan 2016

15

Example: Migrating Dependencies


Lets say our database module uses Guava and we
have the artifact guava-19.0.jar in a directory
libs. We can not simply put it on the classpath because our application is already properly modularized and we discussed above that named modules
can not read the unnamed module. So we need an
automatic module.
From a file named guava-19.0.jar Java derives the module name guava. With this knowledge
we can update the database modules descriptor:
001
002
003
004
005
006
007
008
009
010
011

module com.infoq.monitor.db {
requires java.logging;
requires java.sql;
requires guava;
exports com.infoq.monitor.db.write;
}
To compile it, we need to add libs to
the compilers module path:
javac \
-mp libs \
-d classes/com.infoq.monitor.db \
${list of source files}

Packaging requires no changes. If we launch


our application as we did before, the JVM will complain that it couldnt find the module guava. To fix
that we need to add libs to the module path:
001 java -mp mods:libs -m com.infoq.
monitor
(Note that on Windows the separator between paths
is ; not :.)

Next Steps
We have explored the Jigsaw prototype and seen the
core features it has to offer. What else can we do besides waiting for Java 9?
Go deeper
It is always possible to learn more and there are a
couple of advanced topics we did not discuss:
The excellent State of the Module System
shows how modules can be used with reflection,
which includes adding read edges at run time and
the new concept of layers, as well as the interaction
with class loaders.
The new tool jlink can be used to create run
time images that only contain a specific set of platform modules; it is introduced in the Jigsaw QuickStart Guide, which is highly recommended.
These topics are also covered by talks the Jigsaw team gave at JavaOne 2015 and Devoxx BE 2015.
I summarized the former here.

16

Observe
All things Jigsaw should be discoverable from the
projects OpenJDK site. The main source for up-todate information on Project Jigsaw is the Jigsaw-Dev
mailing list. I will also continue to discuss this topic
on my blog.
Prepare
As has been hinted at, a migration to Jigsaw can be
a little rough. To prepare our projects we should examine whether they rely on anything that will be unavailable or removed in Java 9.
Dependencies on internal APIs, a crucial obstacle, can be analyzed with jdeps, the Java Dependency
Analysis Tool (introduction with some internal packages, official documentation for Windows and Unix),
which is already available in JDK 8. There are also
at least three jdeps-plugins for Maven: by Apache,
Philippe Marschall and myself. The latter enables a
project to gradually remove its dependencies on internal APIs while breaking the build on relapses.
If you are concerned about some specific API
that will be unavailable in Java 9, you could check
the mailing list of the corresponding OpenJDK project as these will be responsible for developing public
versions of them.
We should also identify the critical dependencies our projects rely on and check with those teams
how they are preparing for Java 9.
Adopt
Jigsaw early access builds are available and can be
used to tentatively compile and run existing projects. Unfortunately build system support is still incomplete, but its being worked on.
Information and problems gathered this way
can be returned to the project by posting on the
Jigsaw-Dev mailing list. To quote the (almost) final
words from one of the many involved JEPs:
It is impossible to determine the full impact of
these changes in the abstract. We must therefore rely
upon extensive internal andespeciallyexternal
testing. [] If some of these changes prove to be insurmountable hurdles for developers, deployers, or
end users then we will investigate ways to mitigate
their impact.
There is also the global Java User Group AdoptOpenJDK, which is a great contact for early adopters.

Java 9 and Beyond // eMag Issue 37 - Jan 2016

Read online on InfoQ

Java 9s New HTTP/2 and REPL


System.out.println("Hello, World");
for(int i = 0; i < count; i++){...}
if(hot) {wearSomethingCool();}
while(st.read() != null){...}

Ben Evansis the CEO of jClarity, a Java/JVM performance-analysis startup. In his spare time, he
is one of the leaders of the London Java Community and holds a seat on the Java Community
Process Executive Committee. His previous projects include performance testing the Google IPO,
financial trading systems, writing award-winning websites for some of the biggest films of the
1990s, and others.

Despite all the hype, Java9 will not just be about modularity. It is
targeting many additional pieces of functionality that are being
delivered as Java Enhancement Proposals (JEPs) implemented in
OpenJDK (the reference implementation for Java SE).
Some of the new JEPs may well
have a great impact on developers working lives during the
lifetime of Java 9. These include
HTTP/2 support and the JShell
REPL (read-eval-print loop) that
brings shell-based interactive
Java development and exploration of APIs.

HTTP/2
The HTTP/2 standard is a new
version of the HTTP protocol. The
existing version, HTTP/1.1, dates

from 1999 and has significant


problems.
Head-of-line blocking
HTTP/1.1 dictates that responses
are received in the same order
as the requests were sent. This
means that, for example, when
viewing a large HTML page that
contains several small images,
the images will have to queue
up behind the HTML and cant
be sent until the browser finishes completely downloading the
HTML. This is called head-of-line

blocking and can lead to a number of rendering problems.


In HTTP/2, responses can be
chunked and even interleaved,
to allow responses and requests
to be truly multiplexed.
Restricted connections to a
single site
The HTTP/1.1 standard states, A
single-user client SHOULD NOT
maintain more than 2 connections with any server or proxy.
Along with the head-of-line

Java 9 and Beyond // eMag Issue 37 - Jan 2016

17

problems, this has seriously limited page performance.


HTTP/2 tackles this by assuming that connections are
persistent and will only close after a user navigates away or in
the event of a technical failure.
With the use of multiplexing, this
should help to reduce page bottlenecks.
Overhead of control headers
Existing versions of HTTP use
simple, text-based headers to
control communication. This
has the advantage of being very
simple to understand and allows
debugging simply by connecting to a port and typing some
text. However, the use of a textbased protocol disproportionately inflates small responses.
Additionally, a large number of
HTTP responses have little or
no payload (e.g. HEAD requests
that simply seek to confirm that
a resource has not changed).
Paying the full cost of text-based
headers (~700 bytes that cant be
compressed in HTTP/1.1 despite
being easy to squeeze) for a response consisting of essentially
only a last-modified datetime is
an incredibly wasteful part of the
existing HTTP standard.
The alternative is to use binary encoding for headers. This
approach can greatly speed up
smaller requests and uses far less
bandwidth. It is the approach
that HTTP/2 has chosen to follow,
in the spirit of the principle that
standards should prefer textbased protocols, but use binary
for efficiency where compelling
reasons to do so exist.
What to expect from HTTP/2
The standard comes from
the IETF HTTP Working Group,
which comprised representatives and engineers from Mozilla, Google, Microsoft, Apple, and
others, and chaired by Mark Nottingham, a senior engineer from
the content-delivery network
18

001
002
003
004
005
006
007
008

HttpResponse response = HttpRequest


.create(new URI(http://www.infoq.com))
.body(noBody())
.GET().send();
int responseCode = response.responseCode();
String responseBody = response.body(asString());
System.out.println(responseBody);

Code 1
Akamai. HTTP/2 is therefore a
version optimized for the needs
of large, high-volume websites
and that places performance and
bandwidth consumption above
simplicity of implementation
and easy debugging.
The group chair summarizes some of thekey properties of
HTTP/2as follows:
the same HTTP APIs,
cheaper requests,
network friendly and server
friendly,
cache pushing,
being able to change your
mind, and
more encryption.
What does this mean for Java?
Java has supported HTTP since
version 1.0, but much of the code
comes from a very different era.
For example, Javas support is designed around a relatively protocol-agnostic framework (the URL
class) as it was not clear in the
late 1990s that the Web would
be the dominant force that it has
become.
The support was based on
best ideas at the time but the
world has experienced many
changes, not the least of which is
the fact that when Javas original
HTTP support shipped, HTTPS
didnt exist. So Javas APIs treat
HTTPS as an afterthought with
some irreducible complexity as
a result.
In the modern world, HTTPS
is becoming ubiquitous, with
HTTP moving towards becoming
a legacy technology. Even theUS
government has now adopted

Java 9 and Beyond // eMag Issue 37 - Jan 2016

a plan to move to aHTTPS-Only


Standard.
HTTP support in the core
JDK has not kept pace with the
real Web. In fact, even JDK8 still
only ships a client that supports
HTTP/1.0 and so almost all developers have switched to using
a client library, such as Apache
HttpComponents.
All of this means that support for HTTP/2 is a core piece
of Java functionality for the next
decade. It also allows us to revisit
our old assumptions, rewrite the
APIs, and provide a second bite
of the apple. HTTP/2 will be a
major API for every developer for
years to come.
The new API makes a clean
break with the past by abandoning any attempt to maintain
protocol independence. Instead,
the API focuses solely on HTTP,
but with the additional understanding that HTTP/2 does not
fundamentally change semantics. Therefore, the API can be
independent of HTTP version,
whilst still providing support for
the new framing and connection
handling parts of the protocol.
In the new API, a simple
HTTP request can be created and
handled like this (Code 1)
The fluent/builder style for
the API should feel much more
modern and comfortable to the
developer than the existing legacy API.
The current codebase contains a version with the new
API but currently supports only
HTTP/1.1. This allows developers
to experiment with and validate

the new API while the HTTP/2


support is being completed.
The code is available from
the OpenJDK sandbox repositoryand should be landing on the
JDK 9 mainline very soon. From
there, Oracle will start to automatically include it in its binary
beta builds. The HTTP/2 support
is currently being worked on,
and should arrive in the next few
months.
In the meantime, you can
experiment with the API by
checking out the source using
Mercurial and then following
the AdoptOpenJDK build instructionswith your checked-out
code.
One of the first features to
differ from existing capabilities
is the asynchronous API. This enables a long-running request to
be handed off to a background
VM-managed thread via sendAsync() (Code 2)
For the HTTP/1.1 implementation, this is more of
a developer convenience than
anything else, as HTTP/1.1 does
not offer a cancellation mechanism for requests that have already been sent to the server,
but HTTP/2 should allow for the
client to indicate cancellation of
requests that a server has already
started working on.

JShell
Many languages feature interactive environments for exploratory development. In some cases
(notably Clojure and other Lisps),
the interactive environment is
where developers spend a large
amount or even the majority
of their coding time. Other languages, such as Scala or JRuby,
also make extensive use of REPLs.
Of course, Java has previously had the BeanShell scripting language, but this never
achieved full standardisation
and the project has become dormant in recent years. The inclusion of the Nashorn JavaScript

001
002
003
004
005
006
007
008
009
010
011
012

HttpRequest req = HttpRequest


.create(new URI(http://www.infoq.com))
.body(noBody())
.GET();
CompletableFuture<HttpResponse> aResp = req.
sendAsync();
Thread.sleep(10);
if (!aResp.isDone()) {
aResp.cancel(true);
System.out.println(Failed to reply
quickly...);
return;
}
HttpResponse response = aResp.get();

Code 2
implementation in Java 8 (and
the jjs REPL) opened the door to
broader consideration of REPLs
and the possibility of interactive
development in Java.
An effort to bring a modern
REPL to Java 9 has commenced
as JEP 222 under Project Kulla,
also known as JShell, in OpenJDK. The name Kulla refers to the
ancient Babylonian god of bricks
and foundations. The project
aims to provide an experience
as close to full Java as possible.
The project does not introduce
new non-Java syntax but instead
disables some features of the
language that are not useful for
interactive development (such as
top-level access-control modifiers or synchronized).
Like all REPLs, JShell provides a command line rather than
an IDE-like experience. Statements and expressions are evaluated immediately in the context
of an execution state, rather than
having to be packaged into classes. Methods are also free floating,
and do not have to belong to a
particular class. Instead, JShell
uses snippets of code to provide
a top-level execution environment.
JShell has been developed
in a separate project, like the
HTTP/2 API, in order to avoid impacting the stability of mainline
builds during a period of rapid
development. JShell is expect-

ed to be merged into mainline


during August 2015.
For now, developers can
build Kulla from scratch (source
available from Mercurial) using
the AdoptOpenJDK instructions.
For some initial experimentation, the simplest route is probably to use a standalone tryout
jar. These are jars that the community have built specifically for
developers who dont want to do
a build from scratch.
The tryout jars can be found
on the AdoptOpenJDK Cloudbees instance where CI build artifacts are published.
To use them, you will need
to have a Java9 beta (or OpenJDK9 build) installed. Then download a jar file, rename it to kulla.
jar, and from a command line:
001 $ java -jar kulla.jar
002 | Welcome to JShell
-- Version 0.610
003 | Type /help for
help
004
005 ->
This is the standard interface for a REPL, and, as usual,
commands are issued by starting
them with a single / character.
JShell has a fairly complete
(but still evolving) help syntax,
which is easily accessed (Code 3)
JShell supports tab completion, so that we can easily find
println() or any other method
we want to use:

Java 9 and Beyond // eMag Issue 37 - Jan 2016

19

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016

-> /help
Type a Java language expression, statement, or declaration.
Or type one of the following commands:
/l

or /list [all]
/seteditor <executable>
/e or /edit <name or id>
/d or /drop <name or id>
/s or /save [all|history] <file>
/o or /open <file>
/v or /vars
/m or /methods
/c or /classes
/x or /exit
/r or /reset
/f or /feedback <level>
verbose, default, or ?
/p or /prompt
/cp or /classpath <path>
/h or /history
/setstart <file>
/savestart <file>
/? or /help
/!
/<n>
/-<n>

-- list the source you have typed


-- set the external editor command to use
-- edit a source entry referenced by name or id
-- delete a source entry referenced by name or id
-- save the source you have typed
-- open a file as source input
-- list the declared variables and their values
-- list the declared methods and their signatures
-- list the declared classes
-- exit the REPL
-- reset everything in the REPL
-- feedback information: off, concise, normal,

017
-- toggle display of a prompt
018
-- add a path to the classpath
019
-- history of what you have typed
020
-- read file and set as the new start-up definitions
021
-- save the default start-up definitions to the file
022
-- this help message
023
-- re-run last snippet
024
-- re-run n-th snippet
025
-- re-run n-th previous snippet
026
027 Supported shortcuts include:
028
-- show possible completions for the current text
029 Shift- -- for current method or constructor invocation, show a synopsis of the
method/constructor
Code 3
001 -> System.out.print
002 print(
printf(
println(
Traditional expression evaluation is also easy, although Javas statically typed nature makes
this a little more exacting than
in dynamically typed languages. JShell automatically creates
temporary variables to hold the
values of expressions and ensure
that they remain in scope for later use (Code 4).
We can also view the source
code of everything entered in
the session so far, with the /list
command:
001 -> /list
002
9 : 3 * (4 + 5)
003
004
10 : System.out.
println($1);
The
command
/vars
shows all of the variables (both
20

001
002
003
004
005
006

-> 3 * (4 + 5)
| Expression value is: 27
|
assigned to temporary variable $1 of type int
-> System.out.println($1);
27

Code 4

001 -> String s = Dydh da


002 | Added variable s of type String with initial
value Dydh da
003
004 -> /vars
005 |
int $1 = 27
006
|
String s = Dydh da
Code 5
Code 5

Java 9 and Beyond // eMag Issue 37 - Jan 2016

001
002
003
004
005
006
007
008
009
010
011
012

-> Pet[] pets = new Pet[1]


| Added variable pets of type Pet[] with initial value [LPet;@2be94b0f
-> Cat[] cats = new Cat[1]
| Added variable cats of type Cat[] with initial value [LCat;@3ac42916
-> pets = cats
| Variable pets has been assigned the value [LCat;@3ac42916
-> pets[0] = new Pet()
| java.lang.ArrayStoreException thrown: REPL.$REPL13$Pet
|
at (#20:1)

Code 6
explicitly defined and temporaries) and the values they currently
hold (Code 5).
The REPL allows the simple
creation of classes and other user-defined types as well as small
bits of code. For example, classes
can be created in just one line,
like this (note that the starting
and closing braces are required):
001 -> class Pet {}
002 | Added class Pet
003
004 -> class Cat extends
Pet {}
005 | Added class Cat
The concise, free-flowing
nature of code in JShell means
that we can use the REPL to
demonstrate Java language features very simply. For example,
lets look at the well-known type
problem that Java arrays have
due to array covariance (Code 6).
This makes JShell a great
teaching or exploration tool, and
is closest in experience to the
Scala REPL. With the /classpath switch, additional jars can
be loaded to allow interactive
exploration of APIs directly from
the REPL.

Getting involved
Major IDEs are beginning to provide builds that support early
JDK9 includingNetBeansand
Eclipse. IntelliJ 14.1 reportedly
supports JDK 9, but it is unclear
how far the support for the new
modular JDK extends.

These IDE builds do not,


for now, support either HTTP/2
or JShell, as these features have
yet to land on the OpenJDK
mainline, but developers should
expect them to appear as part
of the standard JDK beta builds
soon, with IDE plugins following
closely behind. The APIs are still
under development, and the
project leads are actively seeking
end-user participation.
The JDK 9 Outreach programme encourages developers
to test their code and applications on JDK9 before it arrives.
HTTP/2 and JShell arent the
only new features being worked
on - other new JDK9 functionality under development includes:
JEP 102: Process API Updates;

JEP 165: Compiler Control;


JEP 227: Unicode 7.0;
JEP 245: Validate JVM Command-Line Flag Arguments;
JEP 248: Make G1 the Default
Garbage Collector;
TLS Updates (JEPs 219, 244,
and 249).
A complete list of all the
JEPs currently under consideration (and the Java versions
they are intended for) can be
foundhere.

Managed garbage collection.


Because JVM environments
hate hoarders.
appdynamics.com/java

Java 9 and Beyond // eMag Issue 37 - Jan 2016

21

Read online on InfoQ

Case for Defaulting to


G1 Garbage Collector in Java 9

Monica Beckwithis a Java-performance consultant. Her past experiences include working with
Oracle/Sun and AMD to optimize the JVM for server-class systems. Monica was voted a Rock Star
speaker @JavaOne 2013 and was the performance lead for Garbage-First Garbage Collector (G1
GC). You can follow Monica on Twitter: @mon_beck

JEP 248 proposes to make Garbage-First (G1) the default garbage


collector (GC) in Java, targeted for OpenJDK 9.
As of OpenJDK 8, the throughput GC (also known
as parallel GC) and the more recent parallel old GC
(parallel old means that both -XX:+UseParallelGC and -XX:+UseParallelOldGC are enabled) have
been the default GCs. Anyone wanting to use a different GC algorithm would have to explicitly enable
it on the command line. For example, if you wanted
to employ G1 GC, you would need to select it on the
command line using -XX:+UseG1GC.
The proposal to set G1 GC as the default GC for
OpenJDK 9 has been a major source of community
concern, which gave rise to a few amazing discussions and eventually led to an update of the original
proposal in order to incorporate the ability to revert
to using parallel GC as the default.
22

So, why G1 GC?


You may be familiar with the software-optimization tradeoff: you can optimize software for latency,
throughput, or footprint. The same is true for GC optimizations, and is reflected in the various popular
GCs. You could also focus on two of those three, but
trying to optimize for all three is enormously difficult.
OpenJDK HotSpot GC algorithms are geared towards
optimizing one of the three for example, Serial GC
is optimized to have minimal footprint, parallel GC is
optimized for throughput, and (mostly) concurrent
mark and sweep (CMS) GC is optimized to minimize
GC-induced latencies for improved response times.
So, why do we need G1?

Java 9 and Beyond // eMag Issue 37 - Jan 2016

G1 GC comes in as a long-term replacement for


CMS. CMS in its current state has a pathological issue
that will lead it to concurrent-mode failures, eventually leading to a full-heap compacting collection.
You can tune CMS to postpone the currently single-threaded full-heap compacting collection, but
ultimately it cant be avoided. In the future, the fallback collection could be improved to employ multiple GC threads for faster execution but, again, a full
compacting collection cant be avoided.
Another important point is that maintenance of
CMS has proven challenging even for the well-seasoned GC engineer; one of the goals for the active
HotSpot GC maintainers has been to keep CMS stable.
Also, CMS GC, parallel GC, and G1 GC all are implemented with different GC frameworks. The cost of
maintaining three different GCs, each using its own
distinct GC framework, is high. G1 GCs regionalized
heap framework, where the unit of collection is a region and various such regions can make up the generations within the contiguous Java heap, is where
the future is heading IBM has their Balanced GC,
Azul has C4, and there is the OpenJDK proposal
called Shenandoah. It wouldnt be surprising to see a
similar regionalized heap-based implementation of
a throughput GC, which could offer the throughput
and adaptive-sizing benefits of parallel GC. The number of GC frameworks used in HotSpot could drop,
thereby reducing the cost of maintenance, which
in turn enables more rapid development of new GC
features and capabilities.
G1 GC became fully supported in OpenJDK 7
update 4, and since then has been getting better and
more robust with massive help from the OpenJDK
community. To learn more about G1, I highly recommend my G1: One Garbage Collector to Rule Them
All and Tips for Tuning the Garbage-First Garbage
Collector InfoQ articles, but let me summarize a few
key takeaways:
G1 GC provides a regionalized heap framework.
This helps make the generations immensely
tunable since the unit of collection (a region)
is now smaller than the generation itself. And
increasing/decreasing the generation size is
as simple as adding/removing a region from
the list of free regions. Note that even though
the entire heap is contiguous, the regions in
a particular generation dont have to be contiguous.
G1 GC is designed on the principle of collecting the most garbage first.
G1 has distinct collection sets for young and
mixed collections. (For more information,
please refer to the Tips article.) For mixed

collections, the collection set is comprised of


all the young regions and a few candidate old
regions. The concurrent marking cycle helps
identify these candidate old regions, which
are effectively added to the mixed collection
set. The tuning switches available for the old
generation in G1 GC are more direct, many
more in number, and provide more control
than the limited-size tuning offered in parallel GC or the size and initiation of marking
threshold settings offered in CMS. The future
that I envision here is an adaptive G1 GC that
can predictively optimize the collection set
and the marking threshold based on the stats
gathered during the marking and collection
cycles.
An evacuation failure in G1 GC is also, so to
speak, tunable. Unlike CMS, G1 does not accumulate fragmentation over time doing
so leads to expensive collection and concurrent-mode failures. In G1, fragmentation is
minimal and may be tuned. Very large objects
that that dont follow the normal allocation
path can introduce fragmentation. These very
large objects (also known as humongous
objects) are allocated directly out of the old
generation into regions known as humongous regions. (To learn more about humongous objects and humongous allocations,
please readthe Tips article.) But when these
humongous objects die, they are collected
and the fragmentation dies with them. In the
current state, it can at times still be a bit of a
heap-region and heap-occupancy tuning
nightmare, especially when you are trying to
work with restricted resources but, again,
making the G1 algorithm more adaptive
would prevent the end user from encountering failures.
G1 GC is scalable!
The G1 GC algorithm is designed with scalability in mind. Compare this with parallel GC
you have something that scales with your
heap size and load without much of a compromise in your applications throughput.

Why now?
Oracle is targeting OpenJDK 9 general availability
for September 2016. The hope is that the OpenJDK
community members that choose to work with early-access builds and release candidates will test the
feasibility of G1 GC as the default GC and provide
timely feedback and even code changes.
The only end users that will be impacted are
those who do not set an explicit GC today. These users will use G1 GC instead of the parallel GC they use

Java 9 and Beyond // eMag Issue 37 - Jan 2016

23

now, and if they want to continue to use parallel GC,


they merely have to set -XX:+UseParallelGC (the
current default that enables parallel GC threads for
young collection) on their JVM command line.
(With the introduction of -XX:+UseParallelOldGC in JDK 5 update 6, you will find that if you
set -XX:+UseParallelGC on the JVM command
line, you will also enable -XX:+UseParallelOldGC,
employing parallel GC threads for full collections.
Hence, if you are working with builds of JDK 6 or later, setting either of these command-line options will
offer the same GC behavior you had previously.)

When would you choose G1 GC over


parallel GC?
Parallel GC doesnt do incremental collection so it
sacrifices latency for throughput. For larger heaps
as the load increases, the GC pause times will often
increase as well, possibly compromising your latency-related system-level agreements (SLAs).
G1 may help deliver your response-time SLAs
with a smaller heap footprint, since G1s mixed collection pauses should be considerably shorter than
the full collections in parallel GC.

When would you choose G1 GC over


CMS GC?
In its current state, a tuned G1 can and will meet the
latency SLAs that a CMS GC cant due to fragmentation and concurrent-mode failures. G1s worst-case
pause times with mixed collections are expected to
be better than the worst-case full-compaction pauses that CMS will encounter. As mentioned earlier,
one can postpone but not prevent the fragmentation of a CMS heap. Some developers working with
CMS have come up with workarounds to combat
the fragmentation issue by allocating objects in similarly sized chunks. But those are workarounds that
are built aroundCMS; the inherent nature of CMS is
that it is prone to fragmentation and will need a fully
compacting collection. Some companies like Google
build their own private JDK from OpenJDK sources
with specific source-code changes for their needs.
One Google engineer has mentioned that the company has added a form of incremental compaction
to its private CMS GCs remark phase in an effort to
reduce fragmentation and have also made their CMS
GC more stable (see this link).
Incremental compaction comes with its own
costs. Google probably added incremental compaction after weighing the benefits to its specific use
case.

24

Why did the JEP become such a hot


topic?
Many OpenJDK community members have remarked on their experience with G1 in the field and
have voiced concern over whether G1 is ready for
prime time. Ever since G1 was fully supported, it has
been touted as a CMS replacement. But the community is concerned that with this JEP it now feels like
G1 is in fact replacing parallel GC, not CMS. It is widely believed that while there may be data comparing
CMS to G1 (due to businesses migrating from CMS to
G1), there is insufficient data comparing parallel to
G1 GC. Also, field data seems to indicate that most
businesses use the default GC, and so will definitely
observe a change in behavior when G1 becomes the
default GC.
Some users have claimed that G1 has expressed
some important (albeit hard to reproduce) issues of
index corruption, and such issues need to be studied
and rectified before G1 is made the default.
Others ask whether we still need a single default GC that is not based on ergonomics. (For example, since Java 5, the launcher can identify your
system as a server-class system and so use the server VM instead of the client VM. See this link)

Summary
After much back and forth, Charlie Hunt, performance architect at Oracle, finally proposed the following steps in June 2015 (see this link):
Make G1 the default collector in JDK 9, continue
to evaluate G1, and enhance G1 in JDK 9.
Mitigate risk by reverting back to parallel GC before JDK 9 goes becomes generally available in
September 2016 if warranted by continuing to
monitor observations and experiences with G1 in
both JDK 9 pre-releases and the latest JDK 8 update releases.
Address enhancing ergonomics for selecting a
default GC as a separate JEP if future observations
suggest its needed.
Staffan Friberg of the Java SE Performance team
at Oracle urged the community to help gather data
points for the following key metrics (see this link):
Ensure that the G1 infrastructural complexity
doesnt introduce much delay at the JVM initialization.
G1 is going head to head with the throughput
GC. G1 also has pre and post write barriers. The
throughput metric is the key to understanding
how much of an overload the barriers impose on
the application.
G1 has remembered sets and collection sets that
increase the footprint. Data gathered from the
field should provide enough information to understand the impact of this increased footprint.

Java 9 and Beyond // eMag Issue 37 - Jan 2016

Businesses that go with the default GC often


also go with the out-of-box performance
provided by that GC so it is important to
understand the out-of-box performance of
G1. Here, the GC ergonomics and how well it
adapts play an important part.
Friberg also identified business applications that currently employ the default GC algorithm the ones that will feel the impact of the
change in the default GC. Similarly, the changeover will also affect scripts that dont specify a
GC or interfaces that specify just the Java heap
and generation sizes on the command line.

Acknowledgement
I would like to extend my gratitude to Charlie
Hunt for his review of this article.

Java Application
Performance
Monitoring
End-to-end transaction tracing
Code level visiblity
Dynamic baselining and alerting
Data rentention
Scalability
Supports all common
Java frameworks including:
Spring
Play
Grails
Resin
Apache CXF
Jetty
Tomcat
Glassfish
JBoss
WebLogic
WebSphere
Struts
Apache TomEE
Akka
For full list, go to:
AppDynamics.com/Java

Read online on InfoQ

A Post-Apocalyptic sun.misc.Unsafe World

Christoph Engelbertis technical evangelist at Hazelcast. He is a passionate Java developer


with a deep commitment for open-source software. He mostly is interested in performance
optimizations and understanding the internals of the JVM and the garbage collector. He loves to
bring software to its limits by looking into profilers and finding problems inside the codebase.

Java as a language and the JVM as a platform just celebrated their


20th birthday. With its noble origins, on set-top boxes, mobiles, and
Java-cards, as well as all kinds of server systems Java is emerging as
the lingua franca ofthe Internet of Things. Java is everywhere!
Less obvious is that Java is also heavily immersed
in all sorts of low-latency applications such as
game servers and high-frequency trading applications.This was only possible thanks to a propitious
deficiency in the Java visibility rules for classes and
packages, offering access to a controversial littleclass
calledsun.misc.Unsafe. This class was and still is a
divider. Some love it, others hate it with a passion
the essential part is it helped the JVM and the Java
ecosystem to evolve to where it is today. The Unsafe
class basically compromised on some of Javas hallmark strict safety standards in favor of speed.
Passionate discussions like those at JCrete, our
What to Do About sun.misc.Unsafe and Pals?mission paper, and blog posts such asthis oneon DripStat created awareness of what might happen in the
26

Java world if sun.misc.Unsafe (along with some


smaller private APIs) were to just disappear without
a sufficient API replacement. The final proposal (JEP
260) from Oracle solves the problem by offering a
nice migration path. But the question remains:how
will this Java world look once the Unsafe dust has
settled?

Organization
A glance at the sun.misc.Unsafe feature set leads
to the unsettling realization that it was used as a
dumping ground for all kinds of features.
An attempt to categorize these features produces the followingfive sets of use cases:
atomic access to variables and array content, custom memory fences,

Java 9 and Beyond // eMag Issue 37 - Jan 2016

serialization support,
custom memory management and efficient
memory layout,
interoperability with native code or other JVMs,
and
advanced locking support.
In our quest for a replacement for all of this
functionality, wecan at least declare victory on the
last one; Java has had a powerful (and frankly very
nice) official API for this for quite some time, java.
util.concurrent.LockSupport.

Atomic access
Atomic access is one of the heavily used features
of sun.misc.Unsafe, featuring basic put and get
(with or without volatile semantics) as well as compare and swap (CAS) operations.
001 public long update() {
002 for(;;) {
003
long version = this.version;
004
long newVersion = version + 1;
005
if (UNSAFE.
compareAndSwapLong(this, VERSION_
OFFSET, version, newVersion)) {
006
return newVersion;
007
}
008
}
009 }
But doesnt Java support this through some official APIs? Absolutely, through the Atomic classes
and those are as ugly as the APIs based on sun.
misc.Unsafe and actually worse for other reasons.
AtomicX classes are real objects. Imagine that
we are maintaining a record inside a storage system
and we want to keep track of certain statistics or
metadata like version counters:
001 public class Record {
002 private final AtomicLong version =
new AtomicLong(0);
003
004 public long update() {
005
return version.incrementAndGet();
006 }
007 }
While the code is fairly readable, it is polluting our heap with two objects per data record instead of one, namely the Atomic instance as well as
the actual record itself. The problem is not only the
extraneous garbage generation, but also the larger
memory footprint and additional dereferences of the
Atomic instances.
We can do better with another API, the java.
util.concurrent.atomic.AtomicXFieldUpdater classes.
AtomicXFieldUpdaters are memory-optimized versions of the normal Atomic classes that
trade memory footprint for API simplicity. Using this
component, a single instance can support multiple

instances of a class, in our case Records, and can update volatile fields.
001 public class Record {
002 private static final
AtomicLongFieldUpdater<Record>
VERSION =
003
AtomicLongFieldUpdater.
newUpdater(Record.class,
version);
004
005 private volatile long version = 0;
006
007 public long update() {
008
return VERSION.
incrementAndGet(this);
009 }
010 }
This approach produces more efficient code for
object creation. Also, the updater is a static final field,
only a single updater is necessary for any number
of records, and most importantly it is available today. Additionally, it is a supported public API, which
should almost always be your preferred strategy. On
the other hand, looking at the creation and usage of
the updater, it is still rather ugly, not very readable,
and, frankly, counterintuitive.
But can we do even better? Yes, variable handles (affectionately called VarHandle) are on the
drawing board and offer a more attractiveAPI.
Variable handles are an abstraction over data
behavior. They provide volatile-like access, not only
over fields but also on elements inside arrays or buffers.
It might seem odd at first glance, so lets see
what is going on.
001 public class Record {
002 private static final VarHandle
VERSION;
003
004 static {
005
try {
006
VERSION = MethodHandles.
lookup().findFieldVarHandle
007
(Record.class, version,
long.class);
008
} catch (Exception e) {
009
throw new Error(e);
010
}
011 }
012
013 private volatile long version = 0;
014
015 public long update() {
016
return (long) VERSION.
addAndGet(this, 1);
017 }
018 }

Java 9 and Beyond // eMag Issue 37 - Jan 2016

27

Use the MethodHandles API, a direct entry


point into the JVM internal linkage behavior, to create VarHandle. We use a MethodHandles-Lookup,
passing in the containing class, field name, and field
type, or we unreflect an instance of java.lang.
reflect.Field.
Why is this better than the AtomicXFieldUpdater API? VarHandle is a general abstraction over
all types of variables, arrays, and even byte buffers
with just have one abstraction over all of these different types. That sounds super nice in theory, but it
is still somewhat wanting in the current prototypes.
The explicit cast of the returned value is necessary
since the compiler is not yet able to automatically figure it out. In addition, there are some oddities as a result of the young prototyping state of the implementation. I hope those problems will disappear in the
future as more people get involved with VarHandle,
andas some of the related language enhancements
proposed inProject Valhallastart to materialize.

being instantiated in an unsafe manner. Another interesting proposal isfrozen arrays, which might also
help serialization frameworks in the future.
It might look like the following snippet, whichis
totally my concoctionas there is no proposal yetbut
is based on the currently availablesun.reflect.ReflectionFactory API.

Serialization

This would call a special deserialization constructor that accepts a frozen char[]. The default
constructor of String creates a duplicate of the
passed char[] to prohibit external mutation. This
special deserialization constructor could prevent
copying the given char[] since it is a frozen array
(more on frozen arrays later). Again, remember this is
just my artificial rendition and will probably be different in the real draft.

Another important use case nowadays is serialization. Whether you are designing a distributed system,
you want to store serialized elements into a database, or you want to go off-heap, Java objects somehow need to be serialized and deserialized quickly.
The faster the better is the motto and to get there,
a lot of serialization frameworks use Unsafe::allocateInstance, which instantiates objects while
preventing constructors from being called, which is
useful in deserialization. This saves a lot of time and is
still safe since the previous object-state is recreated
through the deserialization process.
001 public String deserializeString()
throws Exception {
002 char[] chars =
readCharsFromStream();
003 String allocated = (String) UNSAFE.
allocateInstance(String.class);
004 UNSAFE.putObjectVolatile(allocated,
VALUE_OFFSET, chars);
005 return allocated;
006 }
(Please note that this code fragment might still
break in Java 9, even thoughsun.misc.Unsafewill
remain available, because theres an effort to optimize the memory footprint of a String. This will remove the char[] value in Java 9 and replace it with
a byte[]. Please refer to thedraft JEPon improving
memory efficiency in String for more details.)
There is not yet a replacement proposal forUnsafe::allocateInstance but the jdk9-dev mailing listis discussing certain solutions. One idea is to
move the private class sun.reflect.ReflectionFactory::newConstructorForSerialization into a
supported place that will prevent core classes from
28

001 public String deserializeString()


throws Exception {
002 char[] chars =
readCharsFromStream().freeze();
003 ReflectionFactory reflectionFactory =
004
ReflectionFactory.
getReflectionFactory();
005 Constructor<String> constructor =
reflectionFactory
006 .newConstructorForSerialization
(String.class, char[].class);
007 return constructor.
newInstance(chars);
008 }

Memory management
Possibly the most important usages for sun.misc.
Unsafe are reading and writing, not only to the heap,
as seen in the first section, but especially writing to
regions outside the normal Java heap. In this idiom,
native memory is acquired (represented through an
address/pointer) and offsets are calculated manually.
For example:
001 public long memory() {
002 long address = UNSAFE.
allocateMemory(8);
003 UNSAFE.putLong(address, Long.MAX_
VALUE);
004 return UNSAFE.getLong(address);
005 }
006 Some might jump in and say that the
same is possible using direct byte
buffers:
007 public long memory() {
008 ByteBuffer byteBuffer = ByteBuffer.
allocateDirect(8);
009 byteBuffer.putLong(0, Long.MAX_
VALUE);
010 return byteBuffer.getLong(0);
011 }

On the surface, this approach might seem more


appealing butunfortunately byte buffers are limited

Java 9 and Beyond // eMag Issue 37 - Jan 2016

to roughly 2 GB of data since a DirectByteBuffer


can only be created with an int (ByteBuffer::allocateDirect(int)). Additionally, all indexes on
the ByteBuffer API are only 32-bit. Was it Bill Gates
who once asked, Who will ever need more than 32
bits?
Retrofitting the API to use long-type will break
compatibility, so VarHandle rides to the rescue.
001 public long memory() {
002 ByteBuffer byteBuffer = ByteBuffer.
allocateDirect(8);
003 VarHandle bufferView =
004
MethodHandles.
byteBufferViewVarHandle(long[].
class, true);
005 bufferView.set(byteBuffer, 0, Long.
MAX_VALUE);
006 return bufferView.get(byteBuffer,
0);
007 }
Is the VarHandle API in this case really better? At the moment we are constrained by the same
limitations; we can only create a ByteBuffer with
about 2 GB, and the internal VarHandle implementation for the views over ByteBuffer is also based
on ints. Although this latter issue might be fixable,
at present there is no real solution to this problem.
The nice thing here though is that the API is again
the same VarHandle API as in the first example.
Some more options are under discussion. Paul
Sandoz, the Oracle engineer who is project owner
of JEP 193: Variable Handles, talked about a concept
of a memory region on Twitter and, although still
nebulous, the approach looks promising. A clean
API might look like something like the following
snippet.
001 public long memory() {
002 MemoryRegion region = MemoryRegion
003
.allocateNative(myname,
MemoryRegion.UNALIGNED, Long.MAX_
VALUE);
004
005 VarHandle regionView =
006
MethodHandles.
memoryRegionViewVarHandle(long[].
class, true);
007 regionView.set(region, 0, Long.MAX_
VALUE);
008 return regionView.get(region, 0);
009 }
This is only an idea, and hopefullyProject Panama, the native-code OpenJDK project, will present
a proposal for those abstractions in the near future.
Project Panama is actually the right place for this,
since those memory regions will also need to work
with native libraries that expect a memory address
(pointer) passed into its calls.

Interoperability

Interoperability is not limited to efficient transfer of


data between different JVMs (perhaps via shared
memory, which could also be a type of a memory
region, and which would avoid slow socket communication). It also covers communication and information exchange with native code.
Project Panama hoisted the sails to supersede
JNI in a more Java-like and efficient way. People following JRuby might know Charles Nutter for his efforts on the Java Native Runtime (JNR), and especially
thejnr-ffiimplementation. The FFI stands for foreign
function interface and is a typical term for people
working with other languages like Ruby, Python, etc.
The FFI basically builds an abstraction layer to
call C (and, depending on the implementation, C++)
directly from the current language without the need
to create glue code as in Java.
As an example, to get a pid via Java requires all
of the following C code:
001 extern c {
002
JNIEXPORT int JNICALL
003
Java_ProcessIdentifier_
getProcessId(JNIEnv *, jobject);
004 }
005
006 JNIEXPORT int JNICALL
007
Java_ProcessIdentifier_
getProcessId(JNIEnv *env, jobject
thisObj) {
008 return getpid();
009 }
010
011 public class ProcessIdentifier {
012 static {
013
System.
loadLibrary(processidentifier);
014 }
015
016 public native void talk();
017 }
Using JNR, we could simplify this to a pure Java
interface that would be bound to the native call by
the JNR implementation.
001 interface LibC {
002
void getpid();
003 }
004
005 public int call() {
006 LibC c = LibraryLoader.create(LibC.
class).load(c);
007 return c.getpid();
008 }
JNR internally spins the binding codes and injects those into the JVM. Since Charles Nutter is one
of the main developers of JNR and also works on

Java 9 and Beyond // eMag Issue 37 - Jan 2016

29

Project Panama, we might expect something quite


similar to come up.
From looking at the OpenJDK mailing list, it
feels like we will soon see another incarnation of
MethodHandles that binds to native code. A possible binding might look like the following snippet:
001 public void call() {
002 MethodHandle handle = MethodHandles
003
.findNative(null,
getpid, MethodType.
methodType(int.class));
004 return (int) handle.invokeExact();
005 }
This may look strange if you havent seen
MethodHandles before, but it is obviously more

concise and expressive than the JNI version. The


great thing here is that, just like the reflective Method instances, MethodHandles can be (and generally
should be) cached, to be called over and over again.
You can also get a direct inlining of the native call
into the jitted Java code.
However, I still slightly prefer the JNR interface
as it is cleaner. On the other hand, Im pretty sure we
will get direct interface binding as a nice language
abstraction over the MethodHandles API if not
from the specification, then from some benevolent
open-source committer.

What else?
A few more things are floating around Project Valhalla and Project Panama. Some of those are not directly
related to sun.misc.Unsafe but are still worth mentioning.
Value types
Probably the hottest topic in these discussions isvalue types. These are lightweight wrappers that behave like Java primitives. As the name suggests, the
JVM is able to treat them like simple values, and can
do special optimizations that are not possible on
normal objects. You can think of those as user-definable primitive types.
001
002
003
004
005
006
007

value class Point {


final int x;
final int y;
}
// Create a Point instance
Point point = makeValue(1, 2);

This also is still a draft API and it is unlikely that


we would get a new value keyword, as it would
break user code that might already use that keyword
as an identifier.

30

What is really nice about value types is that the


JVM can treat those types as primitive values that, for
example, offer the option to flatten the layout into
an array:
001 int[] values = new int[2];
002 int x = values[0];
003 int y = values[1];
They might also be passed around in CPU registers and most probably wouldnt need to be allocated on the heap. This actually would save a lot of
pointer dereferences and will offer the CPU a much
better option to prefetch data and do logical branch
prediction.
A similar technique is already used to analyze data in a huge array. Cliff Clicks H2O architecturedoes exactly that, to offer extremely fast map-reduce operations over uniform, primitive data.
In addition, value types can have constructors,
methods, and generics. As Oracle Java language architect Brian Goetz so eloquently declares, it codes
like a class, behaves like an int.
Another related feature is the anticipated specialized generics or, more broadly, type specialization. The idea is simple: extend the generics system
to support not only objects and value types but
also primitives. Using this approach the ubiquitous
String class would be a candidate for a rewrite using value types.
Specialized generics
To bring this to life (and to keep it backwards compatible), the generics system would needto be retrofitted, and some new, special wildcards will bring
salvation.
001 class Box<any T> {
002
void set(T element) { };
003
T get() { ... };
004 }
005
006 public void generics() {
007 Box<int> intBox = new Box<>();
008 intBox.set(1);
009 int intValue = intBox.get();
010
011 Box<String> stringBox = new Box<>();
012 stringBox.set(hello);
013 String stringValue = stringBox.
get();
014
015 Box<RandomClass> box = new Box<>();
016 box.set(new RandomClass());
017 RandomClass value = box.get();
018 }
In this example, the designed Box interface features the new wildcardin contrast to the known. It is

Java 9 and Beyond // eMag Issue 37 - Jan 2016

the description for the JVM internal type specializer


to accept any type, whether an object, a wrapper, a
value type, or a primitive.
An amazing talk about type specialization
byBrian Goetzhimself is available from 2015s JVM
Language Summit (JVMLS).
Arrays 2.0
The proposal for Arrays 2.0 has been around for quite
some time, as is evident from John Roses talk at JVMLS 2012. One of the most prominent features will be
the disappearance of the 32-bit index limitation of
the current arrays. Currently, an array in Java cannot
exceed Integer.MAX_VALUE. The new arrays are expected to accept a 64-bit index.
Another nice feature is the ability to freeze arrays (as we saw in the serialization examples above),
allowing you to create immutable arrays that can be
passed around without having their contents mutated.
And since great things come in pairs, we can expectArrays 2.0 to support specialized generics!

Conclusion
Overall Im happy with the direction and accelerated
development of the JVM and Java as a language. A
lot of interesting and necessary solutions are underway and Java is converging on a modern state while
the JVM is providing new efficiencies and improvements.
From my perspective, people are definitely advised to invest in the genius piece of technology that
we call the JVM, and I expect that all JVM languages
will benefit from the newly integrated features.
In general, I highly recommend theJVMLS talks
from 2015 for more information on most of these
topics, and I suggest you read a summary of Brian
Goetzs talk aboutProject Valhalla.

ClassDynamic
One more interesting proposal floating around is
the so-calledClassDynamic. This proposal is probably in an earlier state than any Ive mentioned so far,
solittle information is currently available. But lets try
to anticipate whatit will look like.
A dynamic class brings the same generalization
concept as specialized generics but on a broader
scope. It provides some kind of template mechanism
to typical coding patterns. Imagine the returned collection fromCollections::synchronizedMapas a
pattern in which every method call is simply a synchronized version of the original
call:
001 R methodName(ARGS) {
002
synchronized (this)
{
003
underlying.
methodName(ARGS);
004
}
005 }
Using dynamic classes and
pattern templates supplied to
the specializer will dramatically
simplify the implementation of
recurring patterns. There is not
much available as I write thisbut
I hope to see more in the near
future, most probably as part of
Project Valhalla.

Managed garbage collection.


Because JVM environments
hate hoarders.
appdynamics.com/java

Java 9 and Beyond // eMag Issue 37 - Jan 2016

31

Read online on InfoQ

The OpenJDK Revised Java Memory Model

by Monica Beckwith

The traditional Java memory model (JMM) offers a lot of semantic


guarantees in Java language.
The existing JMM, as defined in
JSR 133 (henceforth referred to
as JMM-JSR133), specifies consistency models for shared memory
and provides definitions so that
developers can be consistent in
representing the JMM-JSR133.
The goal of the JMM-JSR133
specification was to refine the
definitions of the semantics for
threads that interact through
memory to permit optimizations
and provide a clear programming model. The JMM-JSR133
provided definitions and semantics not only to ensure that multithreaded programs would operate correctly but also efficiently
with minimal impact on an existing codebase.
With this in mind, I would
like to walk through certain semantic guarantees that were
either overspecified or underspecified in JMM-JSR133, while
32

highlighting the community-wide discussion related to


how we can improve them in a
future version of the JMM, which
I will call JMM9.

Sequential consistency
and data races
JMM-JSR133 talked about the
execution of a program with
respect to actions. Such an execution combines actions with
orders to describe the relationship of those actions. I would like
to expand on a few of the orders
and relationships and discuss
what constitutes a sequentially
consistent execution.
Lets start with program
order. A program order for each
thread is a total order that specifies the order in which the
thread would perform all actions. Sometimes, not all actions
need to be ordered, so we have

Java 9 and Beyond // eMag Issue 37 - Jan 2016

some relationships that are only


partially ordered. For example,
happens-before and synchronized-with are partially ordered
relationships. When one action
happens-before another action, the first action is not only
ordered before the second action, it is also visible to the second action. Some special actions
need to be ordered and these are
called synchronization actions.
Volatile reads and writes, monitor locks and unlocks, etc. are
all examples of synchronization
actions. A synchronization action
induces the synchronized-with
relation with that action. A synchronized-with relationship is a
partial order, which means that
not all pairs of synchronization
actions are included. The total
order that spans all the synchronization actions is called a synchronization order, and every

execution has a synchronization


order.
An execution that seems to
occur in a total order over all its
read and write actions is said to
be sequentially consistent (SC).
In a SC execution, the reads will
always see the value the last write
wrote to that particular variable.
When a SC execution exhibits no
data race, the program is said to
be data-race free (DRF). Data races
happen when a program has two
accesses that are not ordered by
the happens-before relation, the
two accesses are accessing the
same variable, and at least one of
those is a write access. SC for DRF
means that DRF programs behave as if they are SC. But strictly
supporting SC comes at a cost of
performance: most systems will
reorder memory operations to
improve execution speed while
hiding the latency of expensive
operations. At the same time,
even the compilers could reorder code to optimize execution.
In an effort to guarantee strict
sequential consistency, all such
reordering of memory operations
or code optimization cant be
carried out and so performance
suffers. JMM-JSR133 already incorporates relaxed ordering restrictions, and a program will not
see any reordering by the underlying compiler, cache-memory interactions, and the JIT itself.
Performance is an important consideration for JMM9, and
moreover any programming languages memory model should
allow all developers to take advantage of architectural memory
models that are weakly ordered.
(Weak ordering refers to architectures that can reorder reads and
writes and would need explicit
memory barriers to curb such
reordering.) There are successful
implementations and examples
that relax strict ordering especially on weakly ordered architectures.

Out of thin air (OoTA)


problem
Another major JMM-JSR133 semantic is the prohibition on out
of thin air (OoTA) values. The
happens-before model can sometimes allow the out of thin air
creation and reading of variable
values since it doesnt require
causality. An important point to
note is that cause by itself doesnt
employ the notion of data and
control dependencies as we will
see in the following correctly synchronized code example in which
the illegal writes are caused by
the writes themselves.
(Note: x and y are initialized
to 0)
Thread a

Thread b

r1 = x;

r2 = y;

if (r1 != 0)

if (r2 != 0)

y = 42;
x = 42;
This code is happens-before consistent but not really sequentially
consistent. For example, if r1 sees
the write of x = 42 and r2 sees the
write of y = 42, both x and y can
have a value of 42, which is the result of a data-race condition.
r1 = x;
y = 42;
r2 = y;
x = 42;
Here, both writes were committed before the read of their variables and the reads would see
the respective writes, and that
would lead to OoTA result.
In order to prohibit OoTA
values, some writes need to wait
for their reads to avoid data races.
The JMM-JSR133 OoTA prohibition formalized the disallowance
of OoTA reads. This formal definition consisted of executions and
causality requirements of the
memory model. Basically, a wellformed execution satisfies the
causality requirements if all of the
program actions could be committed. (A well-formed execution
happens in an intra-thread that
consistently obeys happens-before and synchronization-order

execution when every read can


see the write to the same variable.)
A data race may happen as
a result of speculation, and can
eventually turn into self-fulfilling
prophecy. OoTA guarantees are
about adhering to causality rules.
The current thinking is that causality can break with speculative
writes. JMM9 aims to find the
cause of OoTA and to refine ways
to avoid OoTA.
As you can probably already
tell, JMM-JSR133 definitions were
tightened to prevent OoTA values
from creeping in. JMM9 aims to
identify and correct the formal
definition to allow for some common optimizations.

Volatile actions on nonvolatile variables


A volatile in Java guarantees an
interaction between threads such
that when one thread writes to a
volatile variable, that write is not
the only thing visible to other
threads: the other threads can
see all the writes visible to the
thread that wrote to the volatile
variable.
Non-volatile variables dont
have the benefit of the interaction guaranteed by the volatile
keyword. The compiler can use
a cached value of the non-volatile variable instead of the volatile guarantee that the volatile
variable will always be read from
memory. The happens-before
model can be used to tie synchronized access to the non-volatile
variables.
Declaring any field as volatile doesnt mean that locking
is involved, so volatiles are less
expensive than synchronizations
that use locks. But its important
to note that having multiple volatile fields inside your methods
could make them more expensive than locking those methods.

Java 9 and Beyond // eMag Issue 37 - Jan 2016

33

Read and write atomicity


and word tearing
JMM-JSR133 also guaranteed
(with exceptions) read and write
atomicity for shared-memory
concurrent algorithms. The exceptions were for non-volatile
long and double values where
a write to either was treated as
two separate writes. Thus a single
64-bit value could be written by
two separate 32-bit writes, and a
thread that is reading while one
of those writes is still outstanding may see only half the correct
value and lose atomicity. This is
an example of how the atomicity
guarantee relies on underlying
hardware and the memory subsystem. The underlying assembly
instruction should be able handle
the size of operands to guarantee
atomicity; a read or write operation that has to be split into more
than one operation breaks atomicity (as is the case of non-volatile long and double values).
Similarly, if the implementation
causes more than one memory
subsystem transaction then that
too breaks atomicity. (Volatile
long and double fields and references are always guaranteed for
read and write atomicity.)
The favoring of one bit-ness
over the other isnt an ideal solution because if the exception for
64-bit-ness is removed then 32bit architectures suffer. If the 64bit architectures are penalized
then you have to introduce volatiles for longs and doubles whenever atomicity is desired even
though the underlying hardware
may guarantee atomic operations anyway for example, volatiles are not needed with double
fields since the underlying architecture or ISA or floating-point
unit would take care of the atomicity needs of the 64-bit-wide
field. JMM9 aims at identifying
the atomicity guarantee provided
by the hardware.
JMM-JSR133 was written
more than a decade ago; processor bit-ness has since evolved and
34

64-bit processing has become the


mainstream. This highlights the
compromise that JMM-JSR133
made with respect to 64-bit read
and writes: although 64-bit values can be made atomic on any
architecture, there is still a need
to acquire locks on some architectures. That makes 64-bit reads
and writes expensive on those architectures. If a reasonable implementation of atomic 64-bit operations on 32-bit x86 architecture
cant be found then the atomicity
will not be changed.
An underlying issue in language design is that the volatile keyword is overloaded with
meanings. It is difficult for the
runtime to figure out if the user
put volatile to regain atomicity
(meaning that it can be stripped
out on 64-bit platforms) or for
memory-ordering purposes.
When talking about access
atomicity, the independence of
read and write operations is an
important consideration. A write
to a particular field should not interact with a read from or write to
any other field. This JMM-JSR133
guarantee means that synchronization should not be needed to
provide sequential consistency.
The JMM-JSR133 guarantee prohibits a problem known as word
tearing, which happens, basically, when an update to an operand
wants to operate at a lower granularity than the underlying architecture makes available for its
operands. An important point to
remember is that the word-tearing problem is one of the reasons
that 64-bit longs and doubles
are not given an atomicity guarantee. Word tearing is forbidden
in JMM-JSR133 and will stay that
way in JMM9 as well.

The final-field problem


Final fields are different than other fields. For example, a thread
reading a completely initialized
(meaning that the objects constructor has finished) object with
a final field x is guaranteed to

Java 9 and Beyond // eMag Issue 37 - Jan 2016

read the final fields initialized


value of y. The same cant be
guaranteed of a normal, non-final
field.
In light of the above, there
are some simple things that can
be fixed in JMM9. For example, a
volatile field initialized in a constructor is not guaranteed to be
visible even if the instance itself
is visible. Should the final-field
guarantees be extended to all
field initializations including volatiles? And if the value of a normal,
non-final field of a completely
initialized object doesnt change,
can we extend the final-field
guarantees to this normal field?

Bibliography
I have learned a lot from these
websites, which provide great
sample code sequences. My article should be considered an introductory article look at the
following for a deeper grasp of
the Java memory model.
JSR 133: JavaTM Memory
Model and Thread Specification Revision
The Java Memory Model
Java Concurrency (&C) blog
The jmm-dev Archives
The Java Language Specification, Ch. 17: Threads and Locks
Synchronization and the Java
Memory Model
All Accesses Are Atomic
Java Memory Model Pragmatics (transcript)
Memory Barriers: A Hardware
View for Software Hackers

Special thanks
I would like to thank Jeremy Manson for helping me correct my
various misunderstandings and
providing cleaner definitions
for terms that were new to me. I
would also like to thank Aleksey
Shipilev for helping with reducing the conceptual complexities
that were present in the draft version of this article. Aleksey also
guided me to his JMM pragmatics
transcript for deeper understanding, clarifications, and examples.

PREVIOUS ISSUES

35

iOS9 for Developers

This eMag provides a concise review of all that is essential for developers to know for building apps for the latest release of Apples mobile OS. This eMag is essentially
based on the video sessions from WWDC that Apple
made available to developers and tries to enrich them
with links to reference material that has become meanwhile available online.

34

Graph Databases

36

Patterns of DevOps
Culture

In this e-mag, we explore some of those patterns through


testimonies from their practitioners and through analysis by
consultants in the field who have been exposed to multiple
DevOps adoption initiatives.

This eMag focuses on the graph database landscape


and the real world use cases of graph databases. It includes articles and interviews covering topics like data
modeling in graph databases and how companies use
graph databases in their application. It also includes an
article on full stack web development using a graph database.

33

Cloud Migration

In this eMag, youll find practical advice from leading


practitioners in cloud. Discover new ideas and considerations for planning out workload migrations.

You might also like