0% found this document useful (0 votes)
161 views46 pages

InfoQ - Java8 PDF

Uploaded by

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

InfoQ - Java8 PDF

Uploaded by

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

FACILITATING THE SPREAD OF KNOWLEDGE AND INNOVATION IN ENTERPRISE SOFTWARE DEVELOPMENT

Java 8
eMag Issue 15 - July 2014

Clarifying Lambdas in Java 8 PAGE 11


Simon Ritter discusses the syntax and use of Lambda expressions, focusing on using
Streams to greatly simplify the way bulk and aggregate operations are handled in Java.

JAVA 7 FEATURES THAT ENABLE JAVA 8 P. 4


HOW FUNCTIONAL IS JAVA 8? P. 7
INTUITIVE, ROBUST DATE AND TIME HANDLING FINALLY COMES TO JAVA P. 18
TYPE ANNOTATIONS IN JAVA 8: TOOLS AND OPPORTUNITIES P. 25
WHERE HAS THE JAVA PERMGEN GONE? P. 31
NASHORN: THE COMBINED POWER OF JAVA AND JAVASCRIPT IN JDK 8 P. 37
GREAT JAVA 8 FEATURES NO ONE’S TALKING ABOUT P. 43
Contents

Java 7 Features That Enable Java 8 Page 4


In this article, Ben Evans explores some features in Java 7 which lay the groundwork for the new features in
Java 8.

How Functional Is Java 8? Page 7


By looking at the evolution of Java - particularly its type system, we can see how the new features of Java
8, especially lambda expressions, change the landscape, and provide some key benefits of the functional
programming style.

Clarifying Lambdas in Java 8 Page 11


Simon Ritter discusses the syntax and use of Lambda expressions, focusing on using Streams to greatly
simplify the way bulk and aggregate operations are handled in Java.

Intuitive, Robust Date and Time Handling Finally Comes to Java Page 18
Date and time are fundamental concepts to many applications, yet Java SE had no good API to handle them;
until now!

Type Annotations in Java 8: Tools and Opportunities Page 25


This article introduces the new type annotation syntax and practical tools to boost productivity and build
higher-quality software.

Where Has the Java PermGen Gone? Page 31


Prior to JDK8 class metadata and constants would live in an area called the “permanent generation”. In JDK8
PermGen has now moved to native memory, to an area known as the “Metaspace”.

Nashorn: The Combined Power of Java and JavaScript in JDK 8 Page 37


With JDK 8, Nashorn replaces Rhino as Java’s standard JavaScript engine for the benefit of improved
performance and compatibility.

Great Java 8 Features No One’s Talking about Page 43


In this article Tal Weiss focuses on some lesser known API’s in the new Java 8.
Java 8 / eMag Issue 14 - July 2014

A Letter from the Editor

Victor Grazi is the Java queue lead at InfoQ. Inducted as an Oracle Java
Champion in 2012, Victor works at Nomura Securities on platform
architecture, 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.

After all the well deserved fanfare, Java 8 was on the new Java Date Time APIs, does a deep dive
released this year and is now planting deep roots in into this revolutionary addition to the core Java 8
the development mainstream. distribution.

The syntax, API’s and plumbing have changed With the advent of annotations in Java, and their
substantially, perhaps more than in any version of fortification in Java 8, developers can annotate their
Java since 1.0, topping even Java 5 in impact. code with intent, creating an opportunity for tooling
to help eliminate bugs by verfiying usage against
In this eMag, InfoQ takes practitioners on a visit with intent. Financial technology consultant Todd Schiller
Java 8, exploring how we got here and how we should explores the usage patterns and existing tooling.
be moving forward with it.
Next up, performance guru Monica Beckwith does
Java 8 was not just a quantum release. There was a deep dive into the removal of Perm Gen from
some evolution in prior versions, especially Java 7. the Java runtime, and how to make sense of what
So our eMag begins with a piece on “Java 7 Features replaces it.
that Enable Java 8” by Ben Evans.
Project Rhino brought first class JavaScript support
With the introduction of lambda expressions and the to the Java language, compiling JavaScript into
new Collection and Stream APIs, Java steps into the bytecode, and allowing teams to leverage their client
functional arena. Ben Evans explores this in a feature side developers to build server side code. In his piece
entitled “How Functional is Java 8”. entitled “Nashorn: The Combined Power of Java and
JavaScript in JDK 8” consultant Oliver Zeigermann
Oracle evangelist Simon Ritter did a presentation at explores ways to work with JavaScript in Java 8.
QCon San Francisco 2014 clarifying Lambdas and
Streams. InfoQ distills the lessons learned into a Finally Takipi’s Tal Weiss has some fun exploring “8
visceral enlightenment on how to think in terms of Great Java 8 Features No One’s Talking About.
these important new APIs.
This is an important eMag about one of the most
Time and date handling in Java has until now been important language releases in history. I hope you
somewhat of a sore spot for Java developers. “Joda” enjoy it.
Stephen Colebourn, who introduced the ever
popular Joda Time framework and led the spec

CONTENTS Page 3
Java 8 / eMag Issue 14 - July 2014

Java 7 Features That Enable Java 8


by Ben Evans

It’s a truism of the tech industry that developers are never happier than when
there’s free beer or an opportunity to complain about something on offer.
So despite the efforts of Mark Reinhold and the Java The keyword val indicates that this variable may
team to involve the community in the roadmap after not be reassigned to (like the keyword final for Java
the Oracle acquisition (the Plan A/Plan B decision), variables). No type information is specified about the
many Java developers feel that Java 7 was not much variable at all - instead the Scala compiler examines
of a release. the right side of the assignment and determines the
correct type for the variable by looking at which
In this article, I’ll try to refute this thesis, by exploring value is being assigned.
the features in Java 7 that lay the groundwork for the
new features in Java 8. Java 7 introduced some limited type-inference
capabilities, and assignment statements can now be
Diamond operator written like this:
Java has often been criticised for being overly
verbose. One of the most common areas where this Map<String, String> m = new HashMap<>();
complaint is expressed is in assignment. In Java 6, we
are forced to write assignment statements like this: The key differences between this and the Scala form
is that in Scala, values have explicit types, and it is the
Map<String, String> m = new type of variables that is inferred. In Java 7, the type
HashMap<String, String>(); of variables is explicit, and type information about
values is what is inferred.
This statement contains a lot of redundant
information. We should be able to somehow have Some developers have complained that they would
the compiler figure out more of this by itself, and not have preferred the Scala solution, but it turns out to
require the programmer to be quite so explicit. be less convenient in the context of a major feature
for Java 8: lambda expressions.
In fact, languages like Scala do a large amount of type
inference from expressions, and in fact assignment In Java 8, we can write a function which adds 2 to an
statements can be written as simply as this: integer like this:

val m = Map(“x” -> 24, “y” -> 25, “z” -> Function<Integer, Integer> fn = x -> x
26); + 2;

CONTENTS Page 4
Java 8 / eMag Issue 14 - July 2014

The Function interface is new with Java 8. It This suggests that we could convert the lambda
resides in the java.util.function package along with expression into a synthetic method that has the
specialized forms for primitive types. We’ve chosen correct signature and contains the body of the
this syntax as it resembles the Scala equivalent and lambda. Look at our example:
allows the developer to see the similarities more
easily. Function<Integer, Integer> fn = x -> x
+ 2;
By explicitly specifying the type of fn as a Function
which takes one Integer argument and returns The Java 8 compiler turns that into a private method
another Integer, the Java compiler is able to infer the with this bytecode:
type of the parameter x, which is Integer. This is the
same pattern that we saw in Java 7 diamond syntax: private static java.lang.Integer
we specify the types of variables and infer the types lambda$0(java.lang.Integer);
of values. descriptor: (Ljava/lang/Integer;)
Ljava/lang/Integer;
Let’s look at the corresponding Scala lambda flags: ACC_PRIVATE, ACC_STATIC, ACC_
expression: SYNTHETIC
Code:
val fn = (x : Int) => x + 2; stack=2, locals=1, args_size=1
0: aload_0
Here, we have to explicitly specify the type of the 1: invokevirtual #13 // Method
parameter x, as we don’t have the precise type of java/lang/Integer.intValue:()I
fn, and so we have nothing to infer from. The Scala 4: iconst_2
form is not difficult to read, but the Java 8 form has 5: iadd
a certain cleanliness of syntax which can be directly 6: invokestatic #8 // Method java/
traced back to the diamond syntax of Java 7. lang/Integer.valueOf:(I)Ljava/lang/
Integer;
Method handles 9: areturn
Method handles are simultaneously the most
important new feature of Java 7 and the feature that This has the correct signature (takes in an Integer
is least likely to appear in the day-to-day life of most and returns another one) and semantics. To use
Java developers. this lambda expression, we take a method handle
that refers to it and use it to build an object of the
A method handle is a typed reference to a method for appropriate type, as we’ll see in the next feature we
execution. It can be thought of as a typesafe function discuss.
pointer (for developers familiar with C/C++) or as
Core Reflection reimagined for the modern Java invokedynamic
developer. The final feature of Java 7 that opens the door for
Java 8 is even more esoteric than method handles.
Method handles play a huge part in the This is the new bytecode invokedynamic, the first
implementation of lambda expressions. Early new bytecode to be added to the platform since
prototypes of Java 8 converted each lambda Java 1.0. This feature is almost impossible for Java
expression to an anonymous inner class at compile developers to make use of in version 7, because
time. version 7 javac will not under any circumstances emit
a classfile that contains it.
More recent betas are more sophisticated. Let’s
start by recalling that a lambda expression (at least Instead, the bytecode was designed for use by
in Java) comprises a function signature (which in developers of non-Java languages such as JRuby,
the method handles API will be represented by a which require much more dynamic dispatch than
MethodType object) and a body, but not necessarily a Java. To see how invokedynamic works, let’s discuss
function name. how Java’s method calls are compiled into bytecode.

CONTENTS Page 5
Java 8 / eMag Issue 14 - July 2014

A standard Java method call will be turned into a is converted to an invokedynamic call like this:
piece of JVM bytecode that is often referred to as
a call site. It comprises a dispatch opcode (such as Code:
invokevirtual for regular instance method calls) and stack=4, locals=2, args_size=1
a constant (an offset into the Constant Pool of the 0: invokedynamic #2, 0 //
class) that indicates which method is to be called. InvokeDynamic #0:apply:()Ljava/util/
function/Function;
The different dispatch opcodes have different rules 5: astore_1
that govern how method lookup is done, but until
Java 7, the constant was always a straightforward The invokedynamic bootstrap method is the static
indication of which method was to be called. method LambdaMetafactory.metafactory(), which
returns a CallSite object that is linked to a target
invokedynamic is different. Instead of providing a method handle, which will return an object that
constant that directly indicates which method is to implements the Function interface.
be called, invokedynamic provides an indirection
mechanism that allows user code to decide which When the invokedynamic instruction is complete,
method to call at run time. an object that implements Function and that has
the lambda expression as the contents of its apply()
When an invokedynamic site is first encountered, it method is seated on top of the stack, and the rest of
does not yet have a known target. Instead, a method the code can proceed normally.
handle (called a bootstrap method) is invoked. This
bootstrap method returns a CallSite object, which Conclusion
contains another method handle that is the actual Getting lambda expressions into the Java platform
target of the invokedynamic call: was always going to be challenging, but Java 7 eased
that effort considerably by ensuring that the proper
1) invokedynamic site encountered in the execution groundwork was in place,. Plan B not only provided
stream (initially unlinked). developers with the early release of Java 7 but also
allowed core technologies to be fully road-tested
2) Call bootstrap method and return a CallSite object. before their use in Java 8 and especially in lambda
expressions.
3) CallSite object contains a method handle (the
target). ABOUT THE AUTHOR
Ben Evans is co-founder of jClarity, a
4) Invoke the target method handle. startup which delivers performance
tools & services to help development
The bootstrap method is the way in which user
& ops teams. He is an organizer for
code chooses which method to call. For lambda
the LJC (London’s JUG) and a member
expressions, the platform uses a library-supplied
bootstrap method called a lambda meta-factory. This of the JCP Executive Committee,
has static arguments that contain a method handle helping define standards for the Java
to the synthesized method (see last section) and the ecosystem. He is a Java Champion;
correct signature for the lambda. JavaOne Rockstar; co-author of “The
Well-Grounded Java Developer” & the
The meta-factory returns a CallSite that contains a new edition “Java in a Nutshell” and a
method handle, which will in turn return an instance
regular speaker on the Java platform,
of the correct type that the lambda expression has
performance, concurrency, and
been converted to. So, a statement like:
related topics.
Function<Integer, Integer> fn = x -> x
+ 2;
READ THIS ARTICLE
ONLINE ON InfoQ

CONTENTS Page 6
Java 8 / eMag Issue 14 - July 2014

How Functional Is Java 8?


by Ben Evans

There’s been a lot of talk about how Java 8 is bringing functional language, and doesn’t directly expose
functional programming (FP) to Java, but what does classes and objects in the high-level source language
that really mean? (although good interoperability with Java is
provided).
In this article, I’ll discuss what it means for a
language, or a programming style, to be functional. A Clojure function, such as the log-processing
By looking at the evolution of Java, particularly its function shown below, is a first-class citizen, and
type system, we can see how the new features of doesn’t need to be bundled up in a class to exist.
Java 8, especially lambda expressions, change the
landscape and provide some key benefits of the (defn build-map-http-entries [log-file]
functional style - before tackling the question “How (group-by :uri (scan-log-for-http-
functional is Java 8?” entries log-file)))

What is a functional programming Functional programming is most useful when


language? programs are written in terms of functions that
At its heart, a functional programming language is always return the same output for a given input
one that deals with code in the same way as data. (regardless of any other state present in the running
This means that a function should be a first-class program) and that do not cause any other effects
value and able to be assigned to variables, passed to or change any program state. Functions that obey
functions, and so forth. this are sometimes called “pure” functions, and they
behave in the same way that mathematical functions
In fact, many functional languages go even further do.
than this, and see computation and algorithms
as more fundamental than the data they operate The great advantage that pure functions have is
on. Some of these languages want to disentangle that they are much easier to reason about because
program state from functions (in a way that seems their operation does not depend on external state.
at odds with the desire of object-oriented languages Functions can easily be combined together - and this
that usually want to bring them closer together). can be seen in developer workflow styles such as
the REPL (read, execute, print, loop) style common
An example would be the Clojure programming to Lisp dialects and other languages with strong
language. Despite running on top of the class-based functional heritage.
Java virtual machine, Clojure is fundamentally a

CONTENTS Page 7
Java 8 / eMag Issue 14 - July 2014

Functional programming in non-FP Let’s take a look at some of the forms that it has
languages assumed over the years.
Whether a language is functional or not is not a
binary condition - instead, languages exist on a Java’s original type system
spectrum. At the extreme end are languages that Java’s original type system is now well over 15 years
basically enforce functional programming, often by old. It is simple and clear: types are either reference
prohibiting mutable data structures. Clojure is one types or primitive types. Reference types are classes,
example of a language that does not permit mutable interfaces, or arrays.
data in the accepted sense.
Classes are the heart of the Java platform. A class is
However, there are other languages in which it is the basic unit of functionality that the Java platform
common to write programs in a functional style, will load or link, and all code that is intended for
despite the language not enforcing this. An example execution must live inside a class.
would be Scala, which is a blend of object-oriented
and functional languages. It permits functions as Interfaces can’t be instantiated directly and a class
values, such as: instead must be defined that implements the API
defined by the interface.
val sqFn = (x: Int) => x * x
Arrays hold either primitive types, instances of
while retaining class and object syntax that is very classes, or other arrays.
close to that of Java.
The primitive types are all defined by the platform,
At the other extreme, it is of course possible to and the programmer can’t define new ones.
write functional programs in completely non-
functional languages, such as C, provided that From the very earliest days, Java’s type system has
suitable programmer discipline and conventions are been insistent on a very important point: every type
maintained. must have a name by which it can be referred. This is
known as “nominative typing” - and Java is a strongly
With this in mind, functional programming should nominatively typed language.
be seen as a function of two factors - one of which
is relevant to programming languages and one to Even the so-called “anonymous inner classes” still
programs written in that language: have a type by which the programmer must refer
to them, being the type of the interface that they
1. To what extent does the underlying programming implement:
language support or enforce functional
programming? Runnable r = new Runnable() { public
void run() { System.out.println(“Hello
2. How does this particular program make use of World!”); } };
the functional features provided by the language?
Does it avoid non-functional features such as Another way of saying this is that every value in Java
mutable state? is either a primitive or an instance of some class.

Some Java history Alternatives to named types


Java is an opinionated language. it has been Other languages do not have this fascination with
optimized for readability, for accessibility to junior named types. For example, Java has no equivalent to
programmers, and for long-term stability and Scala’s concept of a type that implements a specific
supportability. These design decisions have come at method (of a specific signature). In Scala, this would
a cost - in verbosity, and in a type system that can be written:
sometimes seem inflexible when compared to other
languages. x : {def bar : String}

However, Java’s type system has evolved, albeit Remember that Scala indicates the type of a variable
relatively slowly, over the history of the language. on the right (after the : ) so this is read as something

CONTENTS Page 8
Java 8 / eMag Issue 14 - July 2014

like “x is of a type that has a method called bar that of this metadata but annotations are considerably
returns String”. We could use this to define a Scala more flexible.
method like this:
Java’s generics provide parameterized types: the
def showRefine(x : {def bar : String}) = idea that one type can act as a container for objects
{ print(x.bar) } of another type, without regard for the specifics
of exactly which type is being contained. The type
Then, we can define a suitable Scala object like this: that fits into the container is often called the type
parameter.
object barBell { def bar = “Bell” }
Of the features introduced by Java 5, enums and
and calling showRefine(barBell) does the expected annotations provided new forms of reference type
thing: which require special treatment by the compiler and
which are effectively disjoint from the existing type
showRefine(barBell) Bell hierarchies.

This is an example of refinement typing. Generics provide significant additional complexity


Programmers coming from dynamic languages may to Java’s type system - not least because they are
be familiar with “duck typing”. Structural refinement purely a compile-time feature. This requires the Java
typing is similar, except that duck typing (“if it walks developer to be mindful of both a compile-time and a
like a duck, and quacks like a duck, it’s a duck”) is run-time type system that are slightly different from
about the runtime types, whereas these structural each other.
refinement types work at compile time.
Despite these changes, Java’s insistence on
In languages that fully support structural refinement nominative typing remained. Type names now
typing, these refined types can be used anywhere include List<String> (read as: “List-of-String”) and
the programmer might expect (such as the type of a Map<Class<?>, CachedObject> (“Map-of-Class-of-
parameter to a method). Java, by contrast, does not Unknown-Type-to-CachedObject”), but these are still
support this sort of typing (apart from a couple of named types, and every non-primitive value is still an
slightly bizarre edge cases). instance of a class.

The Java 5 type system Features introduced in Java 6 and 7


The release of Java 5 brought three major new Java 6 was essentially a performance and library-
features to the type system: enums, annotations, and enhancement release. The only change to the type
generic types. system was an expansion of the role of annotations,
and the release of a capability for pluggable
Enumerated types (enums) are similar to classes in annotation processing. This did not impact most Java
some respects, but they have the property that only developers, and did not really provide for pluggable
a specified number of instances may exist, and each type systems in Java 6.
instance is specified in the class description and
distinct. Intended primarily as a typesafe constant Java 7 did not materially change the type system. The
rather than the then-common practice of using small only new features, all of them very minor, are:
integers for constants, the enum construction also
permits additional patterns that are sometimes Small improvements in type inference in the javac
extremely useful. compiler.

Annotations are related to interfaces - the keyword Signature polymorphic dispatch, used as an
to declare one is @interface - with the initial @ implementation detail for method handles - which
indicating that this is an annotation type. As the are in turn used to implement lambda expressions in
name suggests, they’re used to annotate elements of Java 8.
Java code with additional information that doesn’t
affect behavior. Previously, Java had made use of so- Multi-catch provides some small traces of algebraic
called “marker interfaces” to provide a limited form data types, but these are purely internal to javac

CONTENTS Page 9
Java 8 / eMag Issue 14 - July 2014

and are not of any real consequence to the end-user Before Java 8, a developer who wanted to write in
programmer. a functional style would have to use nested types
(usually anonymous inner classes) as a stand-in for
The Java 8 type system function literals. The default collections libraries
Throughout its history, Java has been essentially would not do the code any favors, and the curse of
defined by its type system. It is central to the mutability would be ever-present.
language and has maintained a strict adherence to
nominative typing. From a practical point of view, the Java 8’s lambda expressions do not magically
Java type system did not change much between Java transform it into a functional language. Instead, their
5 and Java 7. effect is to create a still imperative, still strongly
nominative type language that has better syntax
At first sight, we might expect Java 8 to change that. support for lambda expressions as function literals.
After all, a simple lambda expression appears to Simultaneously, the enhancements to the collections
remove us from nominative typing: libraries have allowed Java developers to start
adopting simple functional idioms (such as filter and
() -> { System.out.println(“Hello map) to tidy up otherwise unwieldy code.
World!”); }
Java 8 required the introduction of some new types
This is a method, without a name, that takes no to represent the basic building blocks of functional
parameters and returns void. It’s still perfectly pipelines - interfaces such as Predicate, Function, and
statically typed, but is now anonymous. Consumer in java.util.function. These additions make
Java 8 capable of slightly functional programming
Have we escaped the Kingdom of the Nouns? Is this but Java’s need to represent them as types (and their
actually a new form of type for Java? location in a utility package rather than the language
core) speaks to the stranglehold that nominative
The answer is, perhaps unfortunately, no. The typing has on the Java language, and how far the
JVM, on which Java and other languages run, is language is from the purity of Lisp dialects or other
very strictly tied to the concept of classes. Class functional languages.
loading is central to the Java platform’s security and
verification modes. Simply put, it would be very, very Despite all the above, this small subset of the
difficult to conceive of a type that was not in some power of functional languages may well be all that
way represented through a class. most developers actually need for their day-to-day
development. For power users, other languages (on
Instead of creating a new kind of type, Java 8 lambda the JVM and elsewhere) still exist, and will doubtless
expressions are auto-converted by the compiler to continue to thrive.
be an instance of a class. The class of which they are
an instance is determined by type inference. For ABOUT THE AUTHOR
example: Ben Evans is co-founder of
jClarity, a startup which delivers
Runnable r = () -> { System.out. performance tools & services to
println(“Hello World!”); };
help development & ops teams.
He is an organizer for the LJC
The lambda expression on the right side is a perfectly
good Java 8 value - but its type is inferred from (London’s JUG) and a member of
the value on the left, so it is actually a value of type the JCP Executive Committee,
Runnable. Note, however, that a lambda expression helping define standards for the
used in an incorrect way will result in a compiler Java ecosystem. He is a regular
error. Nominative typing is still the Java way, and speaker on the Java platform,
even the introduction of lambdas has not changed performance, concurrency, and
that.
related topics.

How functional is Java 8?


Finally, let’s turn to the question we posed at the
start of the article: how functional is Java 8?
READ THIS ARTICLE
ONLINE ON InfoQ
CONTENTS Page 10
Java 8 / eMag Issue 14 - July 2014

Clarifying Lambdas in Java 8


presentation summary writen by Victor Grazi

If you ask average Java developers about Java 8, you (The red parts represent the parts we are interested
will hear ebullient joy in their voices, especially on in; blue represents the boilerplate code.)
the prospect of using lambda expressions.
In this problem, we want to find the highest score
But after honest introspection, we might find the in a Collection of students. We are using a common
fervor tempered by some fear of the tangled web external-iteration idiom to scan and compare.
of new and mysterious APIs. Simon Ritter has
unravelled some of the mystery in his talk on lambdas But there are some drawbacks to this. First, external
at the 2014 QCon London conference iteration means that we, the developers, are
responsible for the implementation, and because we
Ritter begins with the question “Why do we want are using a single loop, we are making it inherently
lambdas in Java?” Java as a language is Turing- serial. If we wanted to optimize this, we couldn’t
complete, which means that any problem that can be easily segment it into a parallel set of execution
solved with a computer program, can be expressed in instructions.
Java. So, why do we need to invest in implementing
and learning new features? Ritter answers that Secondly, the highestScore variable is mutable and
“lambdas can make life easier in terms of how you not thread-safe. So, even if we did want to break it
code and the way that we can take advantage of the up into multiple threads, we would have to introduce
platform underneath – multi-core, multi-processor additional locking to prevent race conditions, which
systems.” in turn can introduce performance issues.

Let’s look at a sample piece of code that illustrates a Now, if we’re clever, we can change the
common coding pattern in Java: implementation a bit more towards the functional
style by using an anonymous inner class.
List<Student> students = ...
double highestScore = 0.0; List<Student> students = ...
for (Student s : students) { double highestScore =
if (s.gradYear == 2011) { students.filter(new
if (s.score > highestScore) { Predicate<Student>() {
highestScore = s.score; public boolean op(Student s) {
} return s.getGradYear() == 2011;
} }
} }).map(new Mapper<Student, Double>()

CONTENTS Page 11
Java 8 / eMag Issue 14 - July 2014

{ You can think of a lambda expression as a method in


public Double extract(Student s) { the sense that it accepts parameters, has a body, and
return s.getScore(); returns a static type.
}
}).max(); This example uses lambda expressions to accomplish
the same high-score determination algorithm as
In this implementation, we eliminate the mutable above. Let’s take a closer look.
state, and hand the job of iteration to the library. We
are chaining together a sequence of method calls First, we create a Stream from our Collection. The
in order to apply that operation in an expression of stream method is new in the COLLECTION interface,
“Look at all of my students and filter out just the ones and works somewhat like a built-in Iterator (more on
who graduated in 2011”. that later). The stream prepares the results from the
collection, which we then pass to our filter method,
The anonymous inner class implements a Predicate describing the “how” part of the filter using a lambda
interface (it contains one method, accepts one expression that compares the graduation year of that
parameter, returns a boolean) with the method called student against 2011.
“op”, which simply compares the graduation year of
that student to 2011 and returns the result. Notice that there is no explicit return statement. We
simply say “Compare graduation year against 2011,”
We pass the result (all students who graduated in and the compiler infers that the Predicate interface
2011) to a map method, which is going to use another (which has a single method that needs a signature
anonymous inner class to call the map interface- with a return type of boolean) is intended. The
method with its single extract method, to extract the map method is processed similarly, using a lambda
data we want (by calling getScore). We then pass that expression, by passing a parameter of Student S and
result, which is a set of scores of all the students who mapping (a.k.a. translating) it to the return value,
graduated in 2011, to a max method, delivering the which is the score of that student. (The map method
largest number from that set of results. should not be confused with the very different java.
util.Map of key-value pairs. Rather, the Stream class’s
Using this approach, we have handed all the iteration, map method returns a new Stream instance that
filtering, and accumulation to the library code, consists of the results of the operation applied to all
freeing us from having to do that explicitly. Not elements of the incoming Stream, producing, in this
only does that simplify our implementation, it also case, a Stream of all of the scores.)
eliminates the shared state, making it easy to ask the
library code to decompose it into a number of sub- Using lambdas, we have implemented the same
tasks and allocate them to different threads to have algorithm with a lot less code. It is clearer, and
them execute in parallel. In many cases, we could also therefore less error-prone, and, as we said, it can be
perform a lazy evaluation, saving even more time. swapped for a parallel algorithm since there is no
shared state.
So, an approach that uses the anonymous inner class
is fast and thread-safe, but look at the color-coding. As Ritter says in his talk,
The ratio of blue to red is pretty high, indicating
boilerplate bloat. Lambda expressions represent an anonymous
function. So, I said they are like a method,
Enter lambda expressions! but they are not really a method. They are an
anonymous function in the sense that they do
the same thing as
a method, but they
are not a method
because they are
not associated with
a class. If you think
about Java as you
program now, you

CONTENTS Page 12
Java 8 / eMag Issue 14 - July 2014

create a class and the class has methods. So, Because the compiler understands where you are
the method has a class associated with it. In using a lambda expression, it can determine a lot about
the case of the lambda expression, there is no that expression. It knows the type of the functional
class associated with it!... interface, so it can infer other types for you.

It is like a method in its structure: it has a But, Ritter observes:


typed argument list; it has a return type
that can be inferred; but you can also use an The thing to be very aware of here is that
explicit return, if you want. It has potentially even though we are not explicitly putting the
a set of thrown exceptions so you can throw type information in there, this is not sneaking
exceptions from within lambda expression if dynamic typing into Java. We would never
you want to and it has a body, which defines do that. That is nasty, it is bad. So, what we
what you are actually doing. You can do the are doing is to say that this is still very much
same thing as with a method: you can group statically typed, but it is more typing with less
statements together; you can use braces typing.
and have multiple statements without any
problem. The important thing about this By the way, one thing that differentiates lambda
is that it now enables us in a simple way expressions from closures, says Ritter, is that unlike
to have parameterized behavior, not just closures, lambdas cannot access a variable from
parameterized values. outside the lambda expression unless that variable
is effectively final, meaning that although it does
Ritter extends this concept by pointing out that since a not require the final keyword (unlike an inner class),
lambda is a function without a class, the keyword “this” nonetheless the variable must not be reassigned. This
refers not to the lambda itself, but to the surrounding convention renders it “effectively final.
class. This is distinguished from an anonymous inner
class, where “this” refers to the inner class itself. Method references
The method-reference syntax is another by-product
It is helpful to look at the implementation choices of the new lambda-expression capability. This is a
made by the language designers to accomplish shortcut that allows you to reuse a method basically
lambdas. as a Lambda expression. You might have something
like this:
Looking at Java as a whole, there are many interfaces
that have just one method. FileFilter x = f -> f.canRead();

Let’s define a functional interface as an interface with Such syntax tells the program to create a FileFilter
exactly one abstract method, for example: that filters files based on a common property – in this
case, if it can be read. Note in this example, we never
interface Comparator<T> { boolean mentioned that f is a file; the compiler inferred that
compare(T x, T y); } from the signature of the lone method in FileFilter:
interface FileFilter { boolean
accept(File x); } boolean accept(File pathname);
interface Runnable { void run(); }
interface ActionListener { void That can be simplified further using the new Java 8 “::”
actionPerformed(…); } notation.
interface Callable<T> { T call(); }
FileFilter x = File::canRead;
A lambda expression lets us define a functional
interface (again, one abstract method), which the That is completely equivalent.
compiler identifies by structure. The compiler can
determine the represented functional interface from To call a constructor in a similar fashion, you can use
its position. The type of a lambda expression is that of the “::new” syntax. For example, if we have a functional
the associated functional interface. interface:

CONTENTS Page 13
Java 8 / eMag Issue 14 - July 2014

interface Factory<T> { Aggregate operations


T make();
} Business operations frequently involve aggregation:
find the sum, max, or average of a set of data, or
Then we can say: group by something. Until now, such operations were
typically performed by loops in an external iteration,
Factory<List<String>> f = which, as we said, restricts us from optimizing and
ArrayList<String>::new; introduces code bloat.

This is equivalent to: Java SE 8 Streams aim to solve that. In Ritter’s words:

Factory<List<String>> f = () -> return A stream is a way of abstracting and specifying


new ArrayList<String>(); how we do aggregate computations. It is not
a data structure. It is really a way of handling
And now, when f.make() is called, it will return a new data, but it is not a data structure on its own
ArrayList<String>. and, interestingly, it can be finite but it can
also be infinite. So, you can create a stream
By leveraging functional interfaces, the compiler can of, let’s say, random numbers and there is
infer a lot about typing and intent, as we see from not necessarily an end to that. This is where,
these examples. sometimes, things get a little bit confusing.
You think to yourself, “Well, if I got an infinite
Library evolution stream, I might just keep processing that data
One advantage of lambdas and expressing code as forever and ever. How do I stop what I am
data is that, as we have seen, existing libraries have doing with that data?”
been updated to accept lambdas as parameters. This
introduced some complexity: how do you introduce The answer is that potentially you will not. You can
new interface methods without breaking existing actually quite easily write a piece of code using
interface implementations? streams that will continue forever, in the same way
that “while(true);” loop will continue forever. It’s the
To address this, Java introduced the concept of same with a Stream: if you use an infinite Stream, it
extension methods, a.k.a. defender methods. could never end. But you can also allow that Stream
to stop – say, to provide an infinite stream of random
Let’s explain by way of example. The stream method numbers but with some particular point at which to
was added to the Collection interface to provide finish, That Stream will stop and you can carry on with
basic lambda support. In order to add the stream your code.
method to that interface without breaking existing
Collection implementations all over the globe, Streams provide a pipeline of data with three
Java added stream as an extension method to the important components:
interface, providing a default implementation:
1. A source of backing data
interface Collection<E> {
default Stream<E> stream() { 2. Zero or more intermediate operations,
return StreamSupport. producing a pipeline of filtered streams
stream(spliterator());
} 3. A terminal operation. That does one of two
} things: it either creates a result or it creates
a side effect. (A side effect means you might
So now you have the ability to implement the not actually return a result but instead, for
stream method, if you want to. And if you don’t, Java example, get a printout.)
provides a default implementation for you.

CONTENTS Page 14
Java 8 / eMag Issue 14 - July 2014

Let’s look at an example, in which we start with a • Pass in something to Stream.of(), a static
Collection of “transactions” and want to determine method on the Stream class.
the total price of all transactions that take place with
buyers from London. • Call one of the new static methods to return
particular streams, for example:
In this example, we apply a stream to our Collection of
transactions. yy IntStream.range(), supplying a start and
end index. For example, IntStream.range(1,
Then, we apply the filter operation to produce a new 10) would generate a stream from 1 to 9
Stream of London buyers. with an incremental step of 1. (IntRange.
rangeClosed(1,10) will generate a stream
Next, we apply the intermediate operation mapToInt from 1 to 10).
to extract the prices.
yy Files.walk() passing in a path and some
Finally, we apply the terminal sum operation to optional control parameters returns
compute the result. a stream of individual files and sub-
directories.
From the point of view of the execution, what
happens here is that the filter and the map methods yy Implement the java.util.Spliterator
(our intermediate operations) do not really do any interface to define your own way of
computational work. They are just responsible for creating a Stream. For more information
setting up the pipeline of operations, and the actual on Spliterator, see Oracle’s SE 8 Javadocs.
computation is performed lazily, deferred until you call
the terminal operation – the sum in this case – which is
when all the work happens. Stream terminal operations

Stream sources After we have piped together all of these streams,


There are a number of ways to obtain a Stream. Many we must specify a terminal operation to execute the
methods have been added to the Collection API (using pipeline and all operations (either sequentially or in
the extension methods in interfaces mechanism we parallel) and produce the final results (or side effects).
discussed.)

If you have, say, a List, Set, or Map.Entry, you can call


a Stream method on that and get a Stream of the
contents of that collection. Iterable interface
This is an old friend we’ve known since Java 1.5
An example is the stream() method, or parallelStream(), days, except that it now has a forEach() method that
which tells the underlying library to use the fork/join accepts a Consumer, the prototype class that accepts
framework to decompose the actions into a number of a single argument, returns no value, and produces a
subtasks. side effect. But this is still an external iteration, and
the better approach is to supply a lambda to the map()
There are other ways of getting a stream: method.

• Pass an array to the stream() method in the


Arrays class.

CONTENTS Page 15
Java 8 / eMag Issue 14 - July 2014

Examples mapToInt(String::length).
Ritter concluded his presentation with a number // Create a new Stream with the
of useful examples, which we list here, with String lengths replacing
explanations in the comments. (Lines in blue indicate
the special usage demonstrated by each example.) // the actual Strings with their
corresponding lengths.
Example 1. Convert words to upper case:
max().
List<String> output = wordList. // Get the max element of the stream
stream(). of
map(String::toUpperCase). // Map the // lengths (as an OptionalInt).
entire list to an upper-case stream.
collect(Collectors.toList()); // getAsInt();
Convert the stream to a list. // Replace the OptionalInt with an
int.
Example 2. Find even-length words in a list:
Example 6. Collect all words in a file into a list:
List<String> output = wordList.
stream(). List<String> output = reader.
filter(w -> (w.length() & 1 == 0). // lines().
Select only words of even-numbered flatMap(line -> Stream.of(line.
length. split(REGEXP))). // Get a stream of
collect(Collectors.toList()); the words from

Example 3. Count lines in a file: // all of the lines.

long count = bufferedReader. filter(word -> word.length() > 0).


lines(). // Get a stream of individual // Filter out the empty strings.
lines. This is a new method on
collect(Collectors.toList());
// bufferedReader that returns a // Create the return list.
stream<string>.
Example 7. Return the list of lower-case words in
count(); // Our terminal operator alphabetical order:
counts the elements of the incoming
stream. List<String> output = reader.
lines().
Example 4. Join lines 3 and 4 into a single string: flatMap(line -> Stream.of(line.
split(REGEXP))).
String output = bufferedReader. filter(word -> word.length() > 0).
lines().
skip(2). map(String::toLowerCase).
// Skip the first two lines. // Replace the source Stream with a
limit(2). Stream of
// Get a stream consisting of the // lower-case words.
next two lines only.
collect(Collectors.joining()); sorted(). //
// Join the lines. Replace the stream with the sorted
version.
Example 5. Find the length of the longest line in a file: collect(Collectors.toList());
// Create the return List.
int longest = reader.
lines().

CONTENTS Page 16
Java 8 / eMag Issue 14 - July 2014

Conclusion
Simon Ritter concludes the presentation by
declaring:
ABOUT THE SPEAKER
Java needs lambda expressions to make Simon Ritter is Head of Java Technology
life easier. It needs lambda expressions so Evangelism at Oracle Corporation. Simon has
that we can implement Streams, we can been in the IT business since 1984 and holds a
implement the idea of passing behavior as
Bachelor of Science degree in Physics from Brunel
well as passing values. We also need to be
University in the U.K.
able to extend existing interfaces, which
is why Java SE 8 has extension methods,
and that solves the problem of backward
compatibility. What this allows us to do is
to provide this idea of bulk operations on
Collections and be able to do things that are WATCH THE FULL
far more simple, (in a) far more readable kind PRESENTATION ON InfoQ
of way. Java SE 8 is basically evolving the
language; it is evolving the class libraries and
also the virtual machines at the same time.

Java 8 is available for download, and there is good


lambda support in all of the major IDE’s. I encourage
all Java developers to download it and give Project
Lambda a spin.

CONTENTS Page 17
Java 8 / eMag Issue 14 - July 2014

Intuitive, Robust Date and Time


Handling Finally Comes to Java
by Stephen Colebourne

The concepts of date and time are fundamental to Naming. Date is not a “date”. Calendar is not a
many applications. Things as diverse as birth dates, “calendar”.
rental periods, event timestamps, and shop opening
hours are all based on date and time, yet Java SE had Formatting. The formatter only works with Date,
no good API to handle them. With Java SE 8, a new not Calendar, and is not thread-safe
set of packages called java.time provides a well-
structured API to cover date and time. Around 2001, the Joda-Time project started. Its
purpose was simple: to provide a quality date and
History time library for Java. It took a while, but eventually
When Java was first launched, in version 1.0, the version 1.0 of Joda-Time was launched and it became
only support for dates and times was the java.util. a popular, widely used library. Over time, demand
Date class. The first thing most developers noted grew to provide a library like Joda-Time in JDK. With
about the class was that it didn’t represent a date. the help of Michael Nascimento Santos from Brazil,
What it did represent was actually quite simple: an the official process to create and integrate a new
instantaneous point in time based on millisecond date and time API for the JDK, JSR-310, started.
precision, measured from the epoch of 1970-01-
01Z. However, because the standard toString() form Overview
printed the date and time in the JVM’s default time The new java.time API consists of five packages:
zone, some developers wrongly assumed that the
class was time-zone aware. java.time - the base package containing the value
objects
The Date class was deemed impossible to fix when
the time came for improvements in version 1.1. As a java.time.chrono - provides access to different
result a new java.util.Calendar API was added. Sadly, calendar systems
the Calendar class isn’t really much better than java.
util.Date. Some of the issues of these classes are: java.time.format - allows date and time to be
formatted and parsed
Mutability. Classes like dates and time simply should
be immutable. java.time.temporal - the low-level framework and
extended features
Offset. Years in Date start from 1900. Months in
both classes start from zero. java.time.zone - support classes for time zones

CONTENTS Page 18
Java 8 / eMag Issue 14 - July 2014

Most developers will primarily use the base and date = date.plusMonths(2); // 2015-08-10
format packages, and perhaps the temporal package. date = date.minusDays(1); // 2015-08-09
Thus, although there are 68 new public types, most
developers will only actively use around a third of These changes are relatively simple, but often there
them. is a need to make more complex alterations to a date.
The java.time API includes the TemporalAdjuster
Dates mechanism to handle this. TemporalAdjuster is a pre-
The LocalDate class is one of the most important packaged utility capable of manipulating a date, such
in the new API. It is an immutable value type that as obtaining the instance corresponding to the last
represents a date. There is no representation of time day of the month. Common ones are supplied in the
of day or time zone. API but you can add your own. Using an adjuster is
easy but does benefit from static imports:
The “local” terminology is familiar from Joda-Time
and comes originally from the ISO-8601 date and import static java.time.DayOfWeek.*
time standard. It relates specifically to the absence
of a time zone. In effect, a local date is a description import static java.time.temporal.
of a date, such as “5 April 2014”. That particular local TemporalAdjusters.*
date will start at different points on the timeline
depending on your location on Earth. Thus, the LocalDate date = LocalDate.of(2014,
local date will start in Australia 10 hours before it Month.JUNE, 10);
starts in London and 18 hours before it starts in San date = date.with(lastDayOfMonth());
Francisco. date = date.with(nextOrSame(WEDNESDAY));

The LocalDate class is designed to have all the The immediate reaction to seeing an adjuster in use
methods that are commonly needed: is typically an appreciation of how close the code
is to the intended business logic. Achieving that is
LocalDate date = LocalDate.of(2014, important with date and time business logic. The
Month.JUNE, 10); last thing that we want to see is large numbers of
int year = date.getYear(); // 2014 manual manipulation of dates. If you have a common
Month month = date.getMonth(); // JUNE manipulation that you are going to perform many
int dom = date.getDayOfMonth(); // 10 times in your codebase, consider writing your own
DayOfWeek dow = date.getDayOfWeek(); // adjuster once and getting your team to pull it in as a
Tuesday pre-written, pre-tested component.
int len = date.lengthOfMonth(); // 30
(days in June) Dates and times as values
boolean leap = date.isLeapYear(); // It is worth spending a brief moment considering what
false (not a leap year) turns the LocalDate class into a value. Values are
simple data types where two instances that are equal
In the example, we see a date being created using are entirely substitutable – in other words, object
a factory method (all constructors are private). It is identity has no real meaning. The String class is the
then queried for some essential information. Note canonical example of a value: we care whether two
the Month and DayOfWeek enums designed to strings are true by equals(); we don’t care if they are
make code more readable and reliable. identical by ==.

In the next example, we see how an instance is Most date and time classes should also be values, and
manipulated. As the class is immutable, each the java.time API fulfills this expectation. Thus, there
manipulation results in a new instance, with the is never a good reason to compare two LocalDate
original unaffected. instances using ==, and in fact the Javadoc warns
against it.
LocalDate date = LocalDate.of(2014,
Month.JUNE, 10); For those wanting to know more, see my recent
date = date.withYear(2015); // 2015-06- definition of VALJOs, which defines a strict set of
10 rules for value objects in Java, including immutability,

CONTENTS Page 19
Java 8 / eMag Issue 14 - July 2014

factory methods, and good definitions of equals, point to alternate calendar systems, allowing them to
hashCode, toString, and compareTo. be looked up by locale. Four other calendar systems
are provided in Java SE 8: the Thai Buddhist, the
Alternate calendar systems Minguo, the Japanese, and the Hirah. Other calendar
The LocalDate class, like all main date and time systems can be supplied by applications.
classes in java.time, is fixed to a single calendar
system: the calendar system defined in the ISO-8601 Each calendar system has a dedicated date class,
standard. thus there is a ThaiBuddhistDate, MinguoDate,
JapaneseDate, and HijrahDate. These are used
The ISO-8601 calendar system is the world’s de facto if building a highly localized application, such as
civil calendar, also called the proleptic Gregorian one for the Japanese government. An additional
calendar. Standard years are 365 days long, and leap interface, ChronoLocalDate, is used as the base
years are 366 days long. Leap years occur every four abstraction of these four, which, with LocalDate,
years, but not every 100, unless divisible by 400. The allows the writing of code without knowing what
year before the year 1 is considered to be year 0 for calendar system it is operating on. Despite the
consistent calculations. existence of this abstraction, the intention is that it is
rarely used.
The first impact of using this calendar system as the
default is that dates are not necessarily compatible Understanding why the abstraction is to be rarely
with the results from GregorianCalendar. used is critical to correct use of the wholejava.
In GregorianCalendar, there is a switch from time API. The truth is that the code of applications
the Julian calendar system to the Gregorian one that that tries to operate in a calendar-system-neutral
occurs by default on 15 October, 1582. Before that manner is broken. For example, you cannot assume
date, it uses the Julian calendar, which has a leap that there are 12 months in a year, yet developers
year every four years without fail. After that date, do and add 12 months in the assumption that they
it switches to the Gregorian calendar and the more have added a whole year. You cannot assume that all
complicated leap-year system we use today. months are roughly the same length; for example,
the Coptic calendar has 12 months of 30 days and
Given that this change in calendar system is a one month of five or six days. Nor can you assume
historical fact, why does the new java.time API not that the next year has a number one larger than the
model it? The reason is that most Java applications current year, as calendars like the Japanese restart
that make use of such historic dates are incorrect year numbering with every new Emperor, and that
today, and it would be a mistake to continue that. change typically happens somewhere other than the
While the Vatican City in Rome changed calendar start of a year – meaning that you can’t even assume
systems on 15 October, 1582, most of the world did that two days in the same month have the same year!
not. In particular, the British Empire, including the
American colonies, did not change until nearly 200 The only way to write code across a large application
years later on 14 September, 1752. Russia didn’t in a calendar-system-neutral way is to have a heavy
change until 14 February, 1918, and Sweden’s regime of code review where every line of date and
change was particularly messy. Thus, the meaning time code is double-checked for bias towards the
of a date prior to 1918 is in fact quite open to ISO calendar system. That’s why the recommended
interpretation, and faith in the single cutover found use of java.time is to use LocalDate throughout
in GregorianCalendar is misplaced. The choice your application, including all storage, manipulation,
to have no cutover in LocalDate is a rational one. and interpretation of business rules. The only time
An application requires additional contextual that ChronoLocalDate should be used is when
information to accurately interpret a specific localizing for input or output, typically achieved by
historical date that may differ between the Julian storing the user’s preferred calendar system in their
and Gregorian calendars. user profile, and even then most applications do not
really need that level of localization.
The second impact of using the ISO-8601 calendar
system in all the main classes is a need for an For the full rationale in this area, see
additional set of classes to handle other calendar the Javadoc of ChronoLocalDate.
systems. The Chronology interface is the main entry

CONTENTS Page 20
Java 8 / eMag Issue 14 - July 2014

Time of day Prefix Description


Moving beyond dates, the next concept to consider is
local time of day, represented by LocalTime. Classic of Static factory methods that create an
examples of this might be to represent the time that instance from constituent parts.
a convenience store opens, say from 07:00 to 23:00
(7 a.m. to 11p.m.). Such stores might open at those Static factory methods that try to extract
hours across the whole of the USA, but the times are from an instance from a similar object. A from()
local to each time zone. method is less type-safe than an of()
method.
LocalTime is a value type with no associated date or
time zone. When adding or subtracting an amount of now Static factory method that obtains an
time, it will wrap around midnight. Thus, 20:00 plus 6 instance at the current time.
hours results in 02:00.
Static factory method that allows a string
Using a LocalTime is similar to using LocalDate: parse to be parsed into an instance of the
object.
LocalTime time = LocalTime.of(20, 30);
int hour = date.getHour(); // 20 get Gets part of the state of the date-time
int minute = date.getMinute(); // 30 object.
time = time.withSecond(6); // 20:30:06
time = time.plusMinutes(3); // 20:33:06 is Checks if something is true or false about
the date-time object.
The adjuster mechanism also works with LocalTime,
however there are fewer complicated manipulations with Returns a copy of the date-time object
of times that call for it. with part of the state changed.

Combined date and time plus Returns a copy of the date-time object
The next class to consider is LocalDateTime. This with an amount of time added.
value type is a simple combination of LocalDate
and LocalTime. It represents both a date and a time minus Returns a copy of the date-time object
without a time zone. with an amount of time subtracted.

A LocalDateTime is created either directly or by Converts this date-time object to


combining a date and time: to another, which may represent part or all
of the state of the original object.
LocalDateTime dt1 = LocalDateTime.
of(2014, Month.JUNE, 10, 20, 30); Combines this date-time object with
LocalDateTime dt2 = LocalDateTime. at additional data to create a larger or more
of(date, time); complex date-time object.
LocalDateTime dt3 = date.atTime(20, 30);
LocalDateTime dt4 = date.atTime(time); format Provides the ability to format this date-
time object.
The third and fourth options use atTime(), which
provides a fluent way to build up a date-time. Most of Instant
the supplied date and time classes have “at” methods When dealing with dates and times, we usually think
that can be used in this way to combine the object in terms of years, months, days, hours, minutes, and
you have with another object to form a more complex seconds. However, this is only one model of time,
one. one I refer to as “human”. The second common model
is “machine” or “continuous” time. In this model, a
The other methods on LocalDateTime are similar single large number represents any point in time.
to those of LocalDate and LocalTime. This familiar This approach is easy for computers to deal with,
pattern of methods is very useful to help learn the and is seen in the UNIX count of seconds from 1970,
API. This table summarises the method prefixes used: matched in Java by the millisecond count from 1970.

CONTENTS Page 21
Java 8 / eMag Issue 14 - July 2014

The java.time API provides a machine view of time An example of the confusion this brought initially
via the Instant value type. It provides the ability is shown in this photo of the clock on the old
to represent a point on the timeline without any Exchange building in Bristol, UK. The red hands show
other contextual information, such as a time zone. Greenwich Mean Time while the black hand shows
Conceptually, it simply represents the number of Bristol Time, 10 minutes different.
seconds since the epoch of 1970 (midnight at the
start of the 1 January, 1970 UTC). Since the API is A standard system of time zones evolved, driven by
based on nanoseconds, the Instant class provides the technology, to replace the older local solar time. But
ability to store the instant to nanosecond precision. the key fact is that time zones are political creations.
They are often used to demonstrate political control
Instant start = Instant.now(); over an area, such as the recent change in Crimea
// perform some calculation to Moscow time. As with anything political, the
Instant end = Instant.now(); associated rules frequently defy logic. The rules can
assert end.isAfter(start); and do change with very little notice.

The Instant class will typically be used for storing The rules of time zones are collected and gathered by
and comparing timestamps, where you need to an international group who publish the IANA Time
record when an event occurred but do not need any Zone Database. This set of data contains an identifier
information about the time zone it occurred in. for each region on the Earth and a history of time
zone changes in each. The identifiers are of the form
In many ways, the interesting aspect of Instant is Europe/London or America/New_York.
what you cannot do with it, rather than what you
can. For example, these lines of code will throw Before the java.time API, you used
exceptions: the TimeZone class to represent time zones.
Now you use the ZoneId class. There are two key
instant.get(ChronoField.MONTH_OF_YEAR); differences. Firstly, ZoneId is immutable, which
instant.plus(6, ChronoUnit.YEARS); provides that ability to store instances in static
variables amongst other things. Secondly, the
They throw exceptions because Instant only consists actual rules themselves are held in ZoneRules, not
of a number of seconds and nanoseconds and in ZoneId itself; simply call getRules() on ZoneId to
provides no ability to handle units meaningful to obtain the rules.
humans. If you need that ability, you need to provide
time-zone information. One common case of time zone is a fixed offset
from UTC/Greenwich. You commonly encounter
Time zones this when you talk about time differences, such
The concept of time zones was introduced by the as New York being five hours behind London. The
UK, where the invention of the railway and other class ZoneOffset, a subclass of ZoneId, represents
improvements in communication suddenly meant the offset of a time from the zero meridian of
that people could cover distances where the change Greenwich in London.
in solar time was important. Up to that point, every
village and town had its own definition of time based As a developer, it would be nice to not have to
on the sun and typically reckoned by sundial. deal with time zones and their complexities. The
java.time API allows you to do that so far as it is
possible. Wherever you can, use the LocalDate,
LocalTime, LocalDateTime, and Instant classes.
When you cannot avoid time zones, the
ZonedDateTime class handles the requirement.

The ZonedDateTime class manages the conversion


from the human timeline, seen on desktop calendars
and wall clocks, to the machine timeline measured
with the ever-incrementing count of seconds. As

CONTENTS Page 22
Java 8 / eMag Issue 14 - July 2014

such, you can create a ZonedDateTime from either a The Duration class represents an amount of time
local class or an instant: measured in seconds and nanoseconds – for example,
23.6 seconds.
ZoneId zone = ZoneId.of(“Europe/Paris”);
The Period class represents an amount of time
LocalDate date = LocalDate.of(2014, measured in years, months, and days – for example,
Month.JUNE, 10); three years, two months, and six days.
ZonedDateTime zdt1 = date.
atStartOfDay(zone); These can be added to, and subtracted from, the
main date and time classes:
Instant instant = Instant.now();
ZonedDateTime zdt2 = instant. Period sixMonths = Period.ofMonths(6);
atZone(zone); LocalDate date = LocalDate.now();
LocalDate future = date.plus(sixMonths);
One of the most annoying issues of time zones is
Daylight Saving Time (DST) or Summer Time. With Formatting and parsing
DST, the offset from Greenwich is changed two An entire package is devoted to formatting and
(or more) times a year, typically moving forward in printing dates and times: java.time.format. The
spring and back in autumn. When these adjustments package revolves around DateTimeFormatter and its
happen, we all have to change the wall clocks dotted associated builder DateTimeFormatterBuilder.
around the house. These changes are referred to
by java.time as offset transitions. In spring, there is The most common ways to create a formatter
a “gap” in the local timeline when some local times are static methods and constants on
do not occur. By contrast, in autumn, there is an DateTimeFormatter. These include:
“overlap” when some local times occur twice.
Constants for commons ISO formats, such as ISO_
The ZonedDateTime class handles this in its factory LOCAL_DATE.
methods and manipulation methods. For example,
adding one day will add a logical day, which may be Pattern letters, such as ofPattern(“dd/MM/uuuu”).
more or less than 24 hours if the DST boundary is
crossed. Similarly, the method atStartOfDay() is so Localized styles, such
named because you cannot assume that the resulting as ofLocalizedDate(FormatStyle.MEDIUM).
time will be midnight - there might be a DST gap from
midnight to 1 a.m. Once you have a formatter, you typically use it by
passing it to the relevant method on the main date
Here’s one final tip on DST. If you want to and time classes:
demonstrate that you have thought about what
should happen in a DST overlap (where the same DateTimeFormatter f = DateTimeFormatter.
local time occurs twice), you can use one of the two ofPattern(“dd/MM/uuuu”);
special methods dedicated to handling overlaps: LocalDate date = LocalDate.
parse(“24/06/2014”, f);
zdt = zdt.withEarlierOffsetAtOverlap(); String str = date.format(f);
zdt = zdt.withLaterOffsetAtOverlap();
In this way, you are insulated from the format and
Use of one of these two methods will select the parse methods on the formatter itself.
earlier or later time if the object is in a DST overlap.
In all other circumstances, the methods will have no If you need to control the locale of formatting, use
effect. the withLocale(Locale) method on the formatter.
Similar methods allow control of the calendar
Amounts of time system, time zone, decimal numbering system, and
The date and time classes discussed so far represent resolution of parsing.
points in time in various ways. Two additional value
types are provided for amounts of time.

CONTENTS Page 23
Java 8 / eMag Issue 14 - July 2014

If you need even more control, see


the DateTimeFormatterBuilder class, which allows
complex formats to be built up step by step. It also ABOUT THE AUTHOR
provides abilities such as case-insensitive parsing, Stephen Colebourne is a Java
lenient parsing, padding, and optional sections of the Champion and JavaOne Rock Star
formatter. speaker. He has been working
with Java since version 1.0 and
Summary contributing to open-source
The java.time API is a new, comprehensive model software since 2000. He has made
for date and time in Java SE 8. It takes the ideas and major contributions to Apache
implementation started in Joda-Time to the next Commons and created the Joda
level and finally allows developers to leave java.util. open-source projects including
Date and Calendar behind. It’s definitely time to Joda-Time. He blogs on Java and
enjoy date and time programming again! is a frequent conference speaker
and contributor to discussions on
Official tutorial at Oracle language change such as Project
Lambda. He was co-spec lead on
Unofficial project home page JSR-310, which created the new
java.time API in Java SE 8.
ThreeTen-Extra project, with additional classes that
supplement core Java SE

READ THIS ARTICLE


ONLINE ON InfoQ

CONTENTS Page 24
Java 8 / eMag Issue 14 - July 2014

Type Annotations in Java 8:


Tools and Opportunities
by Todd Schiller 

In previous versions of Java, developers could write you might cause a subclass method to not be
annotations only on declarations. With Java 8, you called. Eliminating a method call in this manner
can now write annotations on any use of a type such can introduce a defect or security vulnerability. In
as types in declarations, generics, and casts: response, the @Override annotation was introduced
so that developers could document methods as
@Encrypted String data; overriding a superclass method. The Java compiler
List<@NonNull String> strings; then uses the annotations to warn the developer if
myGraph = (@Immutable Graph) tmpGraph; the program doesn’t match their intentions. Used
this way, annotations act as a form of machine-
At first glance, type annotations aren’t the sexiest checked documentation.
feature of the new Java release. Indeed, annotations
are just syntax! Tools are what give annotations their Annotations have also played a central role in making
semantics (i.e. their meaning and behavior). This developers more productive through techniques
article introduces the new type-annotation syntax such as metaprogramming. The idea is that
and practical tools to boost productivity and build annotations can tell tools how to generate new code,
higher-quality software. transform code, or behave at run time. For example,
the Java Persistence API (JPA), also introduced in
In the financial industry, our fluctuating market and Java 1.5, allows developers to declaratively specify
regulatory environments mean that time to market the correspondence between Java objects and
is more important than ever. Sacrificing security or database entities using annotations on declarations
quality, however, is not an option: simply confusing such as @Entity. Tools such as Hibernate use these
percentage points and basis points can have serious annotations to generate mapping files and SQL
consequences. The same story is playing out in every queries at run time.
other industry.
In the case of JPA and Hibernate, annotations are
As a Java programmer, you’re probably already used to support the DRY (don’t repeat yourself)
using annotations to improve the quality of your principle. Interestingly, wherever you look for
software. Consider the @Override annotation, tools for supporting development best practices,
which was introduced back in Java 1.5. In large annotations are not hard to find! Some notable
projects with non-trivial inheritance hierarchies, examples are reducing coupling with dependency
it’s hard to keep track of which implementation injection and separating concerns with aspect-
of a method will execute at run time. If you’re not oriented programming.
careful, when modifying a method declaration

CONTENTS Page 25
Java 8 / eMag Issue 14 - July 2014

This raises the question: if annotations are already File file = ...;
being used to improve quality and boost productivity, @Encrypted File encryptedFile = ...;
why do we need type annotations? @Open Connection connection = ...;

The short answer is that type annotations When executing the program, passing either of these
enable more: they allow more kinds of defects to be files to the connection’s send(...) method will result in
detected automatically and give you more control of same method implementation being called:
your productivity tools.
// These lines call the same method
Type-annotation syntax connection.send(file);
In Java 8, type annotations can be written on any use connection.send(encryptedFile);
of a type, such as the following:
As you’d expect, the lack of run-time effect implies
@Encrypted String data that while the types of parameters can be annotated,
List<@NonNull String> strings methods cannot be overloaded based on the
MyGraph = (@Immutable Graph) tmpGraph; annotated types:

Introducing a new type annotation is as simple as public class Connection{


defining an annotation with the ElementType.TYPE_ void send(@Encrypted File file) {
PARAMETER target, ElementType.TYPE_USE target, ... }
or both targets: // Impossible:
// void send( File file) { ... }
@Target({ElementType.TYPE_PARAMETER, . . .
ElementType.TYPE_USE}) }
public @interface Encrypted { } The intuition behind this limitation is that the
compiler doesn’t have any way of knowing the
The ElementType.TYPE_PARAMETER target relationship between annotated and un-annotated
indicates that the annotation can be written on the types, or between types with different annotations.
declaration of a type variable (e.g. class MyClass<T>
{...}). The ElementType.TYPE_USE target indicates But wait! There’s an @Encrypted annotation on
that the annotation can be written on any use of a the variable encryptedFile that corresponds to
type (e.g. types appearing in declarations, generics, the parameter file in the method signature – but
and casts). where is the annotation in the method signature
corresponding to the @Open annotation on
Once annotations on types are in the source code, the connection variable? In the call connection.
like annotations on declarations, they can both send(...), the connection variable is referred to as the
be persisted in the class file and made available at method›s «receiver». (The «receiver» terminology is
run time via reflection (using the RetentionPolicy. from the classic object-oriented analogy of passing
CLASS or RetentionPolicy.RUNTIME policy on messages between objects). Java 8 introduces a
the annotation definition). There are two primary new syntax for method declarations so that type
differences between type annotations and their annotations can be written on a method’s receiver:
predecessors. First, unlike declaration annotations,
type annotations on the types of local variable void send(@Open Connection this, @
declarations can also be retained in class files. Encrypted File file)
Second, the full generic type is retained and is
accessible at run time. Again, since annotations don’t affect execution, a
method declared with the new receiver-parameter
Although the annotations can be stored in the class syntax has the same behavior as one using the
file, annotations don’t affect the regular execution of traditional syntax. In fact, currently the only use of
the program. For example, a developer might declare the new syntax is so that a type annotation can be
two File variables and a Connection variable in the written on the type of the receiver.
body of a method:

CONTENTS Page 26
Java 8 / eMag Issue 14 - July 2014

A full explanation of the type-annotation syntax, The @MaybeTainted annotation can be thought of as


including syntax for multidimensional arrays, can be a supertype of the @Untainted annotation. There are
found on the JSR (Java Specification Request) 308 a couple ways of thinking about this relation. First, the
website. set of values that might be tainted must be a superset
of the values that we know aren’t tainted (a value
Detecting defects with annotations that is certainly untainted can be an element of the
Writing annotations in the code serves to emphasize set of values that may be tainted). Conversely, the @
the errors in buggy code: Untainted annotation provides a strictly stronger
guarantee than the @MaybeTainted annotation. Let’s
@Closed Connection connection = ...; see if our subtyping intuition works in practice:
File file = ...;
… userInput = dbQuery; // OK
connection.send(file); // Bad!: closed dbQuery = “SELECT FROM * WHERE “ +
and unencrypted! userInput; // Type error!

However, the above code will still compile, run, and The first line checks out – we can’t get in trouble if
crash – Java’s compiler does not check user-defined we make the assumption that an untainted value is
annotations. Instead, the Java platform exposes actually tainted. Our subtyping rule reveals a bug in
two APIs, the Java Compiler plugin and Pluggable the second line: we’re trying to assign the supertype
Annotations Processing APIs, so that third parties to the more restrictive subtype.
can develop their own analyses.
The Checker Framework
In the previous examples, the annotations were, The Checker Framework is a framework for
in effect, qualifying what values variables could checking Java annotations. First released in 2007,
contain. We could imagine other ways of qualifying the framework is an active open-source project led
the File type: @Open File, @Localized File, @ by the co-lead of the JSR 308 specification, Michael
NonNull File. We could imagine these annotations Ernst. The Checker Framework comes prepackaged
qualifying other types, too, such as @Encrypted with a broad array of annotations and checkers for
String. Because type annotations are independent detecting defects such as null-pointer dereferences,
of the Java type system, concepts expressed as unit-of-measure mismatches, security vulnerabilities,
annotations can be reused for many types. and threading/concurrency errors. Because the
checkers use type checking under the hood, their
But how might these annotations be checked results are sound – a checker won’t miss any
automatically? Intuitively, some annotations are potential errors, whereas a tool using just heuristics
subtypes of other annotations, and their usage can might. The framework uses the compiler API to run
be type checked. Consider the problem of preventing these checks during compilation. As a framework,
SQL-injection attacks caused by the database you can also quickly create your own annotation
executing user-provided (tainted) input. We might checkers to detect application-specific defects.
think of data as being either @Untainted or @
MaybeTainted, corresponding to whether the data is The goal of the framework is to detect defects
guaranteed to be free from user input: without forcing you to write a lot of annotations.
It does this primarily through two features: smart
defaults and control-flow sensitivity. For example,
when detecting null-pointer defects, the checker
assumes that parameters are non-null by default.
The checker can also make use of conditionals to
determine that dereferencing an expression is safe.

void nullSafe(Object nonNullByDefault, @


Nullable Object mightBeNull){
@MaybeTainted String userInput; nonNullByDefault.hashCode(); // OK
@Untainted String dbQuery; due to default
mightBeNull.hashCode(); // Warning!

CONTENTS Page 27
Java 8 / eMag Issue 14 - July 2014

if (mightBeNull != null){ These kinds of results are achievable without


mightBeBull.hashCode(); // OK cluttering the code. In practice, verifying a property
due to check with the Checker Framework requires only two or
} three annotations per thousand lines of code!
}
Those of you using Java 6 or Java 7 can still use the
In practice, defaults and control-flow sensitivity Checker Framework to improve the quality of your
mean that you rarely have to write annotations code. The framework supports type annotations
in the body of methods; the checker can infer and written as comments (e.g. /*@NonNull*/ String).
check the annotations automatically. By keeping the Historically, the reason for this is that the Checker
semantics for annotations out of the official Java Framework was co-developed with JSR 308 (the
compiler, the Java team has ensured that third-party type-annotation specification) beginning back in
tool designers and users can make their own design 2006.
decisions. This allows customized error checking to
meet a project’s individual needs. While the Checker Framework is the best framework
for taking advantage of the new syntax for error
The ability to define your own annotations also checking, it’s not the only one right now. Both Eclipse
enables what you might consider domain-specific and IntelliJ are type-annotation-aware:
type checking. For example, in finance, interest
rates are often quoted using percentages while the
difference between rates is often described using Support  
basis points (1/100th of 1%). Using the Checker
Framework’s Units Checker, you could define the two Checker Framework Full support, including
annotations @Percent and @BasisPoints to make annotations in comments
sure you don’t mix them up:
Eclipse Null error analysis support
BigDecimal pct = returnsPct(...); //
annotated to return @Percent IntelliJ IDEA Can write custom
requiresBps(pct); // error: @BasisPoints inspectors, no null error
is required analysis support

Here, because the Checker Framework is


control-flow sensitive, it knows that pct is No Support  
a @Percent BigDecimal at the time of the
call to requiresBps(pct) based on two facts: PMD
first, returnsPct(...) is annotated to return a @
Percent BigDecimal; second, pct hasn’t been Coverity
reassigned before the call to requiresBps(...). Often
developers use naming conventions to try to prevent Find Bugs
these kinds of defects. What the Checker Framework
gives you is a guarantee that these defects don’t Check Style No support for Java 8
exist, even as the code changes and grows.

The Checker Framework has already been run Boosting productivity with type
on millions of lines of code, exposing hundreds of annotations
defects in even well-tested software. Perhaps my The main driver behind the new type-annotation
favorite example is when the framework was run on feature was error checking. Perhaps not surprisingly,
the popular Google Collections library (now Google error-checking tools have the best current and
Guava). It revealed null-pointer defects that even planned support for annotations. However, there
extensive testing and heuristic-based static analysis are compelling applications for type annotations in
tools had not. productivity tools as well. To get a feeling for why,
consider these examples of how annotations are
used:

CONTENTS Page 28
Java 8 / eMag Issue 14 - July 2014

Aspect-oriented @Aspect, @Pointcut, etc. is a similar story. With Spring 4, you could finally use
programming generics as a form of qualifier:

Dependency injection @Autowired, @Inject, etc. @Autowired private Store<Product> s1;


@Autowired private Store<Service> s2;
Persistence @Entity, @Id, etc.
Using generics eliminated the need to introduce
The annotations are declarative specifications of (1) classes such as ProductStore and ServiceStore or to
how tools should generate code or auxiliary files, use fragile name-based injection rules.
and (2) how the tools should impact the run-time
behavior of the program. Using annotations in these With type annotations, it’s not hard to imagine
ways can be considered metaprogramming. Some (read: this is not implemented in Spring yet) using
frameworks, such as Lombok, take metaprogramming annotations to further control injection:
with annotations to the extreme, resulting in code
that barely looks like Java anymore. @Autowired private Store<@Grocery
Product> s3;
Let’s first consider aspect-oriented programming
(AOP). AOP aims to separate concerns such as This example demonstrates type annotations
logging and authentication from the main business serving as a tool for separating concerns, keeping
logic of the program. With AOP, you run a tool at the project’s type hierarchy clean. This separation is
compile time that adds additional code to your possible because type annotations are independent
program based on a set of rules. For example, of the Java type system.
we could define a rule that automatically adds
authentication based on type annotations: The road ahead
We’ve seen how the new type annotations can be
void showSecrets(@Authenticated User used to both detect and prevent program errors
user){ and boost productivity. However, the real potential
// Automatically inserted using for type annotations is in combining error checking
AOP: and metaprogramming to enable new development
if (!AuthHelper.ensureAuth(user)) paradigms.
throw . . .;
} The basic idea is to build run times and libraries
that leverage annotations to automatically make
As before, the annotation is qualifying the type. programs more efficient, parallel, or secure, and to
Instead of checking the annotations at compile automatically enforce that developers use those
time, however, the AOP framework is being used annotations correctly.
to automatically perform verification at run time.
This example shows type annotations being used to A great example of this approach is Adrian
give you more control over how and when the AOP Sampson’s EnerJ framework for energy-efficient
framework modifies the program. computing via approximate computing. EnerJ is
based on the observation that sometimes, such
Java 8 also supports type annotations on local as when processing images on mobile devices, it
declarations that are persisted in the class file. This makes sense to trade accuracy for energy savings. A
opens up new opportunities for performing fine- developer using EnerJ annotates data that is non-
grained AOP. For example, adding tracing code in a critical using the @Approx type annotation. Based
disciplined way: on these annotations, the EnerJ run time takes
various short cuts when working with that data. For
// Trace all calls made to the ar object example, it might store and perform calculations on
@Trace AuthorizationRequest ar = . . .; the data using low-energy approximate hardware.
However, having approximate data moving through
Again, type annotations give more control when the program is dangerous; as a developer, you don’t
metaprogramming with AOP. Dependency injection want control flow to be affected by approximate
data. Therefore, EnerJ uses the Checker Framework

CONTENTS Page 29
Java 8 / eMag Issue 14 - July 2014

to make sure that no approximate data can flow into


data used in control flow (e.g. in an if-statement).
ABOUT THE AUTHOR
The applications of this approach aren’t limited to Todd Schiller is the head of
mobile devices. In finance, we often face a trade-off FinLingua, a financial-software-
between accuracy and speed. In these cases, the development and consulting
run time can be left to control the number of Monte company. FinLingua’s consulting
Carlo paths or convergence criteria, or even run practice helps development teams
computation on specialized hardware, based on the adopt domain-specific language,
current demands and available resources. metaprogramming, and program-
analysis techniques. Todd is an
The beauty of this approach is that the active member of the software-
concern of how the execution is performed engineering research community;
is kept separate from the core business logic his research on specification and
describing what computation to perform. verification has been presented
at premier international
Conclusion conferences including ICSE and
In Java 8, you can write annotations on any use of a OOPSLA.
type in addition to being able to write annotations
on declarations. By themselves, annotations don’t
affect program behavior. However, by using tools
such as the Checker Framework, you can use type
annotations to automatically check and verify
the absence of software defects and boost your READ THIS ARTICLE
productivity with metaprogramming. While it ONLINE ON InfoQ
will take some time for existing tools to take full
advantage of type annotations, the time is now to
start exploring how type annotations can improve
both your software quality and your productivity.

Acknowledgements
I thank Michael Ernst, Werner Dietl, and the New
York City Java Meetup Group for providing feedback
on the presentation on which this article is based. I
thank Scott Bressler, Yaroslav Dvinov, and Will Leslie
for reviewing a draft of this article.

CONTENTS Page 30
Java 8 / eMag Issue 14 - July 2014

Where Has the Java PermGen Gone?


by Monica Beckwith

The Java Virtual Machine (JVM) uses an internal representation of its classes
containing per-class metadata such as class hierarchy information, method data
and information (such as bytecodes, stack and variable sizes), the runtime constant
pool and resolved symbolic reference and Vtables.

In the past (when custom class loaders weren’t that Bye, Bye PermGen, Hello Metaspace!
common), the classes were mostly “static” and were With the advent of JDK8, we no longer have the
infrequently unloaded or collected, and hence were PermGen. No, the metadata information is not gone,
labeled “permanent”. Also, since the classes are a part just that the space where it was held is no longer
of the JVM implementation and not created by the contiguous to the Java heap. The metadata has now
application they are considered “non-heap” memory. moved to native memory to an area known as the
“Metaspace”.
For HotSpot JVM prior to JDK8, these “permanent”
representations would live in an area called the The move to Metaspace was necessary since the
“permanent generation”. This permanent generation PermGen was really hard to tune. There was a
was contiguous with the Java heap and was limited to possibility that the metadata could move with every
-XX:MaxPermSize that had to be set on the command full garbage collection. Also, it was difficult to size the
line before starting the JVM or would default to PermGen since the size depended on a lot of factors
64M (85M for 64bit scaled pointers). The collection such as the total number of classes, the size of the
of the permanent generation would be tied to the constant pools, size of methods, etc.
collection of the old generation, so whenever either
gets full, both the permanent generation and the old Additionally, each garbage collector in HotSpot
generation would be collected. One of the obvious needed specialized code for dealing with metadata
problems that you may be able to call out right in the PermGen. Detaching metadata from PermGen
away is the dependency on the XX:MaxPermSize. not only allows the seamless management of
If the classes metadata size is beyond the bounds Metaspace, but also allows for improvements such as
of XX:MaxPermSize, your application will run out simplification of full garbage collections and future
of memory and you will encounter an OOM (Out of concurrent de-allocation of class metadata.
Memory) error.

CONTENTS Page 31
Java 8 / eMag Issue 14 - July 2014

What Does The Removal Of Moving On To Metaspace And Its


Permanent Space Mean To The End Allocation:
Users? The Metaspace VM now employs memory
Since the class metadata is allocated out of native management techniques to manage Metaspace.
memory, the max available space is the total available Thus moving the work from the different garbage
system memory. Thus, you will no longer encounter collectors to just the one Metaspace VM that
OOM errors and could end up spilling into the swap performs all of its work in C++ in the Metaspace.
space. The end user can either choose to cap the max A theme behind the Metaspace is simply that the
available native space for class metadata, or the user lifetime of classes and their metadata matches the
can let the JVM grow the native memory in-order to lifetime of the class loaders’. That is, as long as the
accommodate the class metadata. classloader is alive, the metadata remains alive in the
Metaspace and can’t be freed.
Note: The removal of PermGen doesn’t mean that
your class loader leak issues are gone. So, yes, you We have been using the term “Metaspace” loosely.
will still have to monitor your consumption and plan More formally, per classloader storage area is
accordingly, since a leak would end up consuming called “a metaspace”. And these metaspaces are
your entire native memory causing swapping that collectively called “the Metaspace”. The reclamation
would only get worse. of metaspace per classloader can happen only after
its classloader is no longer alive and is reported dead

CONTENTS Page 32
Java 8 / eMag Issue 14 - July 2014

by the garbage collector. There is no relocation or compaction in these metaspaces. But metadata is scanned
for Java references.

The Metaspace VM manages the Metaspace allocation by employing a chunking allocator. The chunking size
depends on the type of the classloader. There is a global free list of chunks. Whenever a classloader needs a
chunk, it gets it out of this global list and maintains its own chunk list. When any classloader dies, its chunks are
freed, and returned back to the global free list. The chunks are further divided into blocks and each block holds
a unit of metadata. The allocation of blocks from chunks is linear (pointer bump). The chunks are allocated
out of memory mapped (mmapped) spaces. There is a linked list of such global virtual mmapped spaces and
whenever any virtual space is emptied, its returned back to the operating system.

The figure above shows Metaspace allocation with metachunks in mmapped virtual spaces. Classloaders 1 and
3 depict reflection or anonymous classloaders and they employ “specialized” chunk size. Classloaders 2 and 4
can employ small or medium chunk size based on the number of item in those loaders.

Tuning And Tools For Metaspace


As previously mentioned, a Metaspace VM will manage the growth of the Metaspace. But there may be
scenarios where you may want to limit the growth by explicitly setting the -XX:MaxMetaspaceSize on the
command line. By default, the –XX:MaxMetaspaceSize doesn’t have a limit, so technically the Metaspace size
could grow into swap space and you would start getting native allocation failures.

For a 64-bit server class JVM, the default/initial value of –XX:MetaspaceSize is 21MB. This is the initial high
watermark. Once this watermark is hit, a full garbage collection is triggered to unload classes (when their
classloaders are no longer alive) and the high watermark is reset. The new value of the high watermark
depends on the amount of freed Metaspace. If insufficient space is freed up, the high watermark goes up;
if too much space is freed, the high watermark goes down. This will be repeated multiple times if the initial
watermark is too low. And you will be able to visualize the repeated full garbage collections in your garbage
collector logs. In such a scenario, you are advised to set the –XX:MetaspaceSize to a higher value on the
command line in order to avoid the initial garbage collections.  

CONTENTS Page 33
Java 8 / eMag Issue 14 - July 2014

After subsequent collections, the Metaspace VM will automatically adjust your high watermark, so as to push
the next Metaspace garbage collection further out.

There are also two options: XX:MinMetaspaceFreeRatio and XX:MaxMetaspaceFreeRatio. These are
analogous to GC FreeRatio parameters and they can be set on the command line as well.

A few tools have been modified to help get more information regarding the Metaspace and they are listed
here:

jmap –clstats <PID>: prints class loader statistics. (This now supersedes –permstat that used to print class
loader stats for JVMs prior to JDK8). An example output while running DaCapo’s Avrora benchmark:

$ jmap -clstats <PID>


Attaching to process ID 6476, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.5-b02
finding class loader instances ..done.
computing per loader stat ..done.
please wait.. computing liveness.liveness analysis may be inaccurate ...
class_loader classes      bytes parent_loader     alive? type 

<bootstrap>     655  1222734     null      live   <internal>


0x000000074004a6c0    0    0    0x000000074004a708    dead      java/util/
ResourceBundle$RBClassLoader@0x00000007c0053e20
0x000000074004a760    0    0      null      dead      sun/misc/
Launcher$ExtClassLoader@0x00000007c002d248
0x00000007401189c8     1     1471 0x00000007400752f8    dead      sun/reflect/
DelegatingClassLoader@0x00000007c0009870
0x000000074004a708    116   316053    0x000000074004a760   dead      sun/misc/
Launcher$AppClassLoader@0x00000007c0038190
0x00000007400752f8    538  773854    0x000000074004a708   dead      org/dacapo/
harness/DacapoClassLoader@0x00000007c00638b0
total = 6      1310   2314112           N/A       alive=1, dead=5     N/A    
jstat –gc <LVMID>: now prints Metaspace information as shown in the following example:

jcmd <PID> GC.class_stats: This is a new diagnostic command that enables the end user to connect to a live
JVM and dump a detailed histogram of Java class metadata.

Note: With JDK8 build 13, you have to start Java with XX:+UnlockDiagnosticVMOptions. 

$ jcmd <PID> help GC.class_stats


9522:
GC.class_stats
Provide statistics about Java class meta data. Requires
-XX:+UnlockDiagnosticVMOptions.

CONTENTS Page 34
Java 8 / eMag Issue 14 - July 2014

Impact: High: Depends on Java heap size and content. 

Syntax : GC.class_stats [options] [<columns>] 

Arguments:
     columns : [optional] Comma-separated list of all the columns
to show. If not specified, the following columns are shown:
InstBytes,KlassBytes,CpAll,annotations,MethodCount,Bytecodes,MethodAll,ROAll,RWAll,Total
(STRING, no default value)

Options: (options must be specified using the <key> or <key>=<value> syntax)


     -all : [optional] Show all columns (BOOLEAN, false)
     -csv : [optional] Print in CSV (comma-separated values) format for spreadsheets
(BOOLEAN, false)
     -help : [optional] Show meaning of all the columns (BOOLEAN, false)

Note: For more information on the columns, please see here.

An example output:

 $ jcmd <PID> GC.class_stats 

7140:

Index Super InstBytes KlassBytes annotations   CpAll MethodCount Bytecodes MethodAll   ROAll   RWAll   Total ClassName

    1    -1    426416        480           0       0           0         0         0      24     576     600 [C

    2    -1    290136        480           0       0           0         0         0      40     576     616 [Lavrora.arch.legacy.LegacyInstr;

    3    -1    269840        480           0       0           0         0         0      24     576     600 [B

    4    43    137856        648           0   19248         129      4886     25288   16368   30568   46936 java.lang.Class

    5    43    136968        624           0    8760          94      4570     33616   12072   32000   44072 java.lang.String

    6    43     75872        560           0    1296           7       149      1400     880    2680    3560 java.util.HashMap$Node

    7   836     57408        608           0     720           3        69      1480     528    2488    3016 avrora.sim.util.MulticastFSMProbe

    8    43     55488        504           0     680           1        31       440     280    1536    1816 avrora.sim.FiniteStateMachine$State

    9    -1     53712        480           0       0           0         0         0      24     576     600 [Ljava.lang.Object;

   10    -1     49424        480           0       0           0         0         0      24     576     600 [I

   11    -1     49248        480           0       0           0         0         0      24     576     600 [Lavrora.sim.platform.ExternalFlash$Page;

   12    -1     24400        480           0       0           0         0         0      32     576     608 [Ljava.util.HashMap$Node;

   13   394     21408        520           0     600           3        33      1216     432    2080    2512 avrora.sim.AtmelInterpreter$IORegBehavior

   14   727     19800        672           0     968           4        71      1240     664    2472    3136 avrora.arch.legacy.LegacyInstr$MOVW

…<snipped>

…<snipped>

1299  1300         0        608           0     256           1         5       152     104    1024    1128 sun.util.resources.LocaleNamesBundle

 1300  1098         0        608           0    1744          10       290      1808    1176    3208    4384 sun.util.resources.OpenListResourceBundle

 1301  1098         0        616           0    2184          12       395      2200    1480    3800    5280 sun.util.resources.ParallelListResourceBundle

              2244312     794288        2024 2260976       12801    561882   3135144 1906688 4684704 6591392 Total

                34.0%      12.1%        0.0%   34.3%           -      8.5%     47.6%   28.9%   71.1%  100.0%

Index Super InstBytes KlassBytes annotations   CpAll MethodCount Bytecodes MethodAll   ROAll   RWAll   Total ClassName

CONTENTS Page 35
Java 8 / eMag Issue 14 - July 2014

Current Issues
As mentioned earlier, the Metaspace VM employs a chunking allocator. There are multiple chunk sizes
depending on the type of classloader. Also, the class items themselves are not of a fixed size, thus there are
chances that free chunks may not be of the same size as the chunk needed for a class item. All this could
lead to fragmentation. The Metaspace VM doesn’t (yet) employ compaction hence fragmentation is a major
concern at this moment.

ABOUT THE AUTHOR


Monica Beckwith is a
performance engineer working
in the hardware industry for well
over a decade. Her most current
title is Performance Architect at
Servergy - a startup that offers
a new class of hyper-efficient
Cleantech Servers ®. Prior to
Servergy, Monica has worked at
Oracle/Sun and AMD optimizing
the JVM for server class systems.
Monica was voted a Rock Star
speaker @JavaOne 2013. You can
READ THIS ARTICLE follow Monica on twitter
ONLINE ON InfoQ @mon_beck.

CONTENTS Page 36
Java 8 / eMag Issue 14 - July 2014

Nashorn: The Combined Power of


Java and JavaScript in JDK 8
by Oliver Zeigermann

Ever since JDK 6, Java has shipped with a bundled Let’s create a simple Java project consisting of the
JavaScript engine based on Mozilla’s Rhino. following two example files and let the program run:
This feature allowed you to embed JavaScript
code into Java and even call into Java from the
embedded JavaScript. Additionally, it provided the
capability to run JavaScript from the command line
using jrunscript. That was pretty good provided you
didn’t require great performance and you could live
with the limited ECMAScript 3 feature set.

Starting with the JDK 8, Nashorn replaces Rhino


as Java’s embedded JavaScript engine. Nashorn
supports the full ECMAScript 5.1 specification plus
some extensions. It compiles JavaScript to Java In line 12, we use the engine’s eval method to
bytecode using new language features based on JSR evaluate any JavaScript code. In this case, we just
292, including invokedynamic, that were introduced load the top JavaScript file and evaluate it. You
in JDK 7. might find “print” to be unfamiliar. It is not a built-in
function for JavaScript, but Nashorn provides this
This brings a two to 10-times performance boost and other convenience functions that come in handy
over the former Rhino implementation, although it is in a scripting environment. You could have also
still somewhat short of V8, the engine inside Chrome embedded the printing of “Hello, World!” directly
and Node.js. If you are interested in details of the into the string passed into the eval method, but
implementation, you can have a look at these slides having your JavaScript in a file of its own opens up a
from the 2013 JVM Language Summit. whole world of tooling for it.

As Nashorn comes with JDK 8, it also adds very neat


support for functional interfaces, as we shall see in
more detail shortly.

Let’s kick it off with a very small example. First, you


might want to install JDK 8 and NetBeans, IntelliJ
IDEA, or Eclipse. All of them provide at least basic
support for integrated JavaScript development.

CONTENTS Page 37
Java 8 / eMag Issue 14 - July 2014

Eclipse currently has no dedicated Nashorn support #!/usr/bin/env jjs


via its JavaScript Development Tools (JSDT) project
but it does support basic tooling and editing for var name = $ARG[0];
JavaScript. print(name ? “Hello, ${name}!” : “Hello,
world!”);
IntelliJ IDEA 13.1 (Community and Ultimate
Editions) provides outstanding JavaScript and To pass in program arguments to jjs, prefix them with
Nashorn support. It has a fully featured debugger “--”. So for example you might call:
and it even allows refactoring to be synchronized
between Java and JavaScript; if, for example, ./hello-script.js -- Joe
you rename a Java class that is referenced from
JavaScript or if you rename a JavaScript file sourced Without the “--” prefix, the parameter would be
in from Java, the IDE will modify the corresponding interpreted as a file name.
references across languages.
Passing data to and from Java
Here is an example of how you can debug the As indicated above, you can call JavaScript directly
JavaScript called from Java (note that NetBeans from your Java code; just obtain an engine and call its
also provides JavaScript debugging as shown in the eval method. You can pass in data explicitly as strings:
screenshot below):
ScriptEngineManager scriptEngineManager
= new ScriptEngineManager();
ScriptEngine nashorn =
scriptEngineManager.
getEngineByName(“nashorn”);
String name = “Olli”;
nashorn.eval(“print(‘” + name + “’)”);

You can also pass bindings from Java that can


be accessed as global variables from inside the
JavaScript engine:

int valueIn = 10;


You may say the tooling looks nice and the new SimpleBindings simpleBindings = new
implementation fixes the performance as well as SimpleBindings();
the compliance problems, but ask why you should it. simpleBindings.put(“globalValue”,
One reason would be general scripting. Sometimes valueIn);
it comes in handy to be able to throw in any kind of nashorn.eval(“print (globalValue)”,
string and just let it be interpreted. Sometimes it simpleBindings);
might just be nice to not have a compiler in the way,
or not to worry about static typing. Or maybe you The results of a JavaScript eval computation will be
are interested in the Node.js programming model, returned from the engine’s eval method:
which can be used with Java, as we will see at the end
of this article. There is also a case to be made that Integer result = (Integer) nashorn.
developing JavaFX will be much faster using eval(“1 + 2”);
JavaScript as opposed to Java. assert(result == 3);

Shell scripts Using Java classes in Nashorn


The Nashorn engine can be called from the command As mentioned before, one of the most powerful
line using the jjs command. You can call it without any features of Nashorn comes from calling Java classes
argument, which will bring you into an interactive from inside JavaScript. You can not only access
mode, you can pass the name of a JavaScript file you classes and create instances, you can also subclass
want executed, or you can use it as a replacement for them, call their static members, and do virtually
a shell script, like this: anything you could do from Java.

CONTENTS Page 38
Java 8 / eMag Issue 14 - July 2014

As an example, let’s take a look at threads. JavaScript consumer’s accept method by passing in each
does not have any language features for concurrency element of the collection one by one.
and all common runtimes are single-threaded or at
least without any shared state. It is interesting to see As already mentioned, the functional-language
that in the Nashorn environment, JavaScript could in approach for such a higher-order function would
fact run concurrently and with shared state, just like rather accept a function parameter than an object.
in Java: While passing around references to functions per se
is not traditionally Java’s province, JDK 8 now has
// this is how we get access to Java some syntactic sugar for expressing just that using
class Thread lambda expressions (a.k.a. “closures”). For example:
var Thread = Java.type(“java.lang.
Thread”); List<Integer> list = Arrays.asList(3, 4,
1, 2);
// subclass with our run method list.forEach(el -> System.out.
var MyThread = Java.extend(Thread, { println(el));
run: function() {
print(“Run in separate thread”); In this case, the parameter to forEach has the form
} of such a function reference. This is possible because
}); Consumer is a functional interface, sometimes called
var th = new MyThread(); a single abstract method (SAM) type.
th.start();
th.join(); So why are we talking about lambdas in a discussion
of Nashorn? Because in JavaScript you can write
Note that the canonical way to access a class from code like this as well and Nashorn is especially
Nashorn is to use Java.type and you can extend a well-prepared to bridge the gap between Java
class using Java.extend. and JavaScript in this case. In particular, it allows
you to even pass plain JavaScript functions as
Functional delight implementations of functional interfaces (SAM
By all counts, with the release of JDK 8, Java types).
has, at least to a certain extent, become a
functional language. You can now use higher-order Let us have a look at some plain JavaScript code that
functions on collections, for example to iterate over does the same thing as our Java code above. Note
their elements. A higher-order function is a function that there is no built-in list type in JavaScript, only
that takes another function as a parameter and does arrays – but those arrays are dynamically sized and
something meaningful with it. Have a look at this have methods comparable to the ones of a Java list.
example in Java: So, in this example we are calling the forEach method
of a JavaScript array:
List<Integer> list = Arrays.asList(3, 4,
1, 2); var jsArray = [4,1,3,2];
list.forEach(new Consumer() { jsArray.forEach(function(el) { print(el)
} );
@Override
public void accept(Object o) { The similarity is obvious, but that isn’t all. You can
System.out.println(o); also convert such a JavaScript array to a Java list:
}
}); var list = java.util.Arrays.
asList(jsArray);
In this example, instead of iterating over the
elements using an external loop as we would See? And yes, this is JavaScript running inside
traditionally have done, we now pass a Consumer Nashorn. As this is now a Java list, you can call its
function to the forEach operation, a higher-order forEach method. Note that this is not the same
internal-looping operation that executes the forEach method that we called on the JavaScript
array, but rather Java’s forEach method defined on

CONTENTS Page 39
Java 8 / eMag Issue 14 - July 2014

collections. Still, we are passing in a plain JavaScript The code of this example already looks similar to how
function here: we would implement an interface as an anonymous
inner class in Java, but it’s not quite the same. This
list.forEach(function(el) { print(el) } brings us to the first extension, which lets you pass
); the last parameter after the closing “)” when you
make a constructor call. Doing this, our code looks
Nashorn allows us to provide plain JavaScript like this:
function references where a functional interface
(SAM type) is expected. This is thus not only possible var r = new java.lang.Runnable() {
from Java, but also from JavaScript. run: function() {
print(“running...\n”);
The next version of ECMAScript (which is expected }
to become final in 2014) will include a short syntax };
for functions that will allow them to be written nearly
as Java lambdas, except that it uses a fat arrow, “=>”. That does exactly the same thing, but has an even
This will drive the alignment even further. greater resemblance to Java.

Special Nashorn JavaScript dialect The second frequently used extension is a shortcut
As I mentioned in the introduction, Nashorn supports for functions that allows you to omit both the
JavaScript in the ECMAScript 5.1 version plus some curly braces as well as the return statement for
extensions. I do not necessarily recommend using the method body in a single line function. Take our
those extensions because, being neither Java nor example from the previous section:
JavaScript, they can feel unnatural to developers.
On the other hand, Oracle uses two extensions list.forEach(function(el) { print(el) }
throughout its documentation, so we should become );
familiar with them.
That could be expressed as the slightly more terse:
First, let us set the stage for the first extension. As
you have seen before, you can extend a Java class list.forEach(function(el) print(el));
from JavaScript using Java.extend. If you want to
subclass an abstract Java class or implement an Avatar.js
interface, you can use a more convenient syntax. We have seen that with Nashorn we have a premium
In this case, you can virtually call the constructor JavaScript engine embedded into Java. We have
of the abstract class or the interface and pass also seen that from Nashorn we can access any Java
in a JavaScript object literal that describes the class. Avatar.js goes one step further and brings, as
implemented methods. JavaScript object literals are the web site says, “the Node programming model,
just name/value pairs, similar to what you may know APIs, and module ecosystem to the Java platform”. To
from the JSON format. This allows us to implement understand what this means and why it is exciting, we
the Runnable interface like this: first have to understand what Node is. Node basically
extracts Chrome’s V8 JavaScript engine to make it
var r = new java.lang.Runnable({ work from the command line without the need for
run: function() { a browser. It thus makes JavaScript executable not
print(“running...\n”); only in the browser but also on the server side. To
} execute JavaScript on a server in any meaningful way,
}); you will at least need to access the file system and
the network. To achieve this, Node embeds a library
In this example, we virtually call the constructor of called libuv that does this in an asynchronous way.
Runnable with an object literal that specifies the Practically, this means that your calls to the operating
implementation of the run method. Note that this is system never block even if they take a while to
something the Nashorn implementation is giving us; return. Instead of blocking, you provide a callback
it would otherwise not be possible in JavaScript. function that will be triggered once the call is done,
delivering the results if there are any.

CONTENTS Page 40
Java 8 / eMag Issue 14 - July 2014

There are several companies using Node for serious java -Djava.library.path=lib -jar lib/
applications, among them Walmart and PayPal. avatar-js.jar helloWorld.js

Let’s take a look at a small JavaScript example that I We assume that the demo server (the code above) is
have adapted from Node’s web site: saved in a file called “helloWorld.js”.

// load module ‘http’ (this is blocking) Again, let us ask, why is this useful? The good people
to handle http requests at Oracle (see slide 10 of this JavaOne San Francisco
var http = require(‘http’); 2013 presentation) see a couple of use cases for such
a library. I mainly concur with two of them, namely:
// when there is a request we return
‘Hello, World\n’ You have a Node application and want to use certain
function handleRequest(req, res) { Java libraries to complement the Node API.
res.writeHead(200, {‘Content-Type’:
‘text/plain’}); You want to switch to JavaScript and the Node API,
res.end(‘Hello, World\n’); but need to embed legacy Java code either partially
} or completely.

// we listen on localhost, port 1337 Both use cases work by using Avatar.js and calling
// and give handleRequest as call back any required Java classes from the JavaScript code,
// you see the non-blocking / which is supported by Nashorn, as we have seen.
asynchronous nature here
http.createServer(handleRequest). Let me give you an example of the first use case.
listen(1337, ‘127.0.0.1’); JavaScript currently has just a single type for
// logs to the console to reassure that expressing numbers called “number”. This would
we are on our way be equivalent to the Java “double”, with the same
console.log(‘Get your hello at limitations: JavaScript’s number, like Java’s double, is
http://127.0.0.1:1337/’); not able to express arbitrary range and precision, for
To run this code, you would need to install Node, save example when dealing with money.
the above JavaScript code into a file, and, finally, call
Node with this file as a parameter. In Java, you could use BigDecimal, which supports
exactly that. But JavaScript has no built-in
The goal of Avatar.js is to provide the same core API equivalent, so you could just access the BigDecimal
as Node by binding libuv to Java classes and then class from your JavaScript code to safely handle
making them accessible to JavaScript. Even though monetary values.
this may sound cumbersome, it works surprisingly
well. Avatar.js supports a large number of Node Let us look at an example web service that calculates
modules and its support of Express, the mainstream the percentage of some amount. First, we need a
web framework for Node, indicates that this could function that does the actual calculation:
indeed work with a large number of existing projects.
var BigDecimal = Java.type(‘java.math.
Unfortunately, at the time of this writing, there BigDecimal’);
is no binary distribution for Avatar.js. There is a
readme that explains how to build it from source, function calculatePercentage(amount,
but if you are not so much into building from scratch, percentage) {
you can get the binaries without building them. Both var result = new BigDecimal(amount).
approaches work, but I recommend the second one multiply(
for quicker results. new BigDecimal(percentage)).divide(
new BigDecimal(“100”), 2,
Once you have set up your binaries and put them BigDecimal.ROUND_HALF_EVEN);
into a lib folder, you would then call the Avatar.js return result.toPlainString();
framework using something like: }

CONTENTS Page 41
Java 8 / eMag Issue 14 - July 2014

In JavaScript, there are no declared types, but apart I get the correct answer of
from that the code looks pretty similar to the Java “7567230000000000006600158.73”, which
code I have written for this task: would have been impossible using JavaScript’s plain
“number” type.
public static String calculate(String
amount, String percentage) { The second use case would make sense when you
BigDecimal result = new decide to migrate your existing JEE application
BigDecimal(amount).multiply( to JavaScript and Node. In this case, you can
new BigDecimal(percentage)).divide( easily access all your existing services from within
new BigDecimal(“100”), 2, JavaScript. Another related use case would be to
BigDecimal.ROUND_HALF_EVEN); have a new piece of server functionality built using
return result.toPlainString(); JavaScript and Node that still can benefit from
} existing JEE services.

We just need to replace the handleRequest function In the same direction, there is also Project


of the Node example above to complete our code. It Avatar, which is based on Avatar.js. Details are
goes like this: beyond the scope of this article but have a look at this
Oracle announcement for a quick overview. The
// load utility module ‘url’ to parse basic idea is to write your application in JavaScript
url and access JEE services. Project Avatar comes with
var url = require(‘url’); a combined binary distribution for Avatar.js, but
requires GlassFish for installation and development.
function handleRequest(req, res) {
// ‘/calculate’ is the path of our Wrap-up
web service Project Nashorn has enhanced the original JDK
if (url.parse(req.url).pathname === 6 Rhino implementation by greatly improving
‘/calculate’) { performance for longer running applications, for
var query = url.parse(req.url, example when used inside a web server. Nashorn
true).query; integrates Java with JavaScript and even takes the
// amount and percentage are new lambdas of JDK 8 into account. A real innovation
passed in as query parameters comes with Avatar.js, which builds on those features
var result = and provides for integration of enterprise Java and
calculatePercentage(query.amount, JavaScript code while being largely compatible
with the de facto standard for JavaScript server
query.percentage); programming.
res.writeHead(200, {‘Content-
Type’: ‘text/plain’}); Complete examples including Avatar.js binaries for
res.end(result + ‘\n’); Mac OS X can be found on GitHub.
}
}
ABOUT THE AUTHOR
We use a second core module of Node to process Oliver Zeigermann is a self-
the URL of the request to parse out the query employed software architect/
parameters for amount and percentage. developer, consultant, and
coach from Hamburg, Germany.
I start the server (as shown above) and issue a He is currently focused on
request like this using the web browser: using JavaScript in enterprise
applications.
http://localhost:1337/calculate?
amount=99700000000000000086958613&
percentage=7.59 READ THIS ARTICLE
ONLINE ON InfoQ

CONTENTS Page 42
Java 8 / eMag Issue 14 - July 2014

8 Great Java 8 Features No One’s


Talking About
by Tal Weiss

If you haven’t seen some of the videos or tutorials around Java 8, you’ve probably
been super-busy or have a more interesting social life than I do (which isn’t saying
much). With new features like lambda expressions and Project Nashorn taking so
much of the spotlight, I wanted to focus on some new APIs that have been a bit
under the radar, but make Java 8 better in so many ways.

1. Stamped Locks a reader was holding an optimistic lock, will cause


Multi-threaded code has long been the bane of the optimistic unlock to be invalidated (the stamp
server developers (just ask Oracle Java Language is no longer valid). At that point the application can
Architect and concurrency guru Brian Goetz). start all over, perhaps with a pessimistic lock (also
Over time complex idioms were added to the core implemented in StampedLock.) Managing that is
Java libraries to help minimize thread waits when up to you, and one stamp cannot be used to unlock
accessing shared resources. One of these is the another – so be super careful.
classic ReadWriteLock that lets you divide code into
sections that need to be mutually exclusive (writers), Let’s see this lock in action-
and sections that don’t (readers).
long stamp = lock.tryOptimisticRead();
On paper this sounds great. The problem is that the // non blocking path - super fast
ReadWriteLock can be super slow(up to 10x), which work(); // we’re hoping no writing will
kind of defeats its purpose. Java 8 introduces a new go on in the meanwhile
ReadWrite lock – called StampedLock. The good if (lock.validate(stamp)){
news here is that this guy is seriously fast. The bad //success! no contention with a
news is that it’s more complicated to use and lugs writer thread
around more state. It’s also not reentrant, which }
means a thread can have the dubious pleasure of else {
deadlocking against itself. //another thread must have acquired
a write lock in the meanwhile, changing
StampedLock has an “optimistic” mode that issues the stamp. 
a stamp that is returned by each locking operation //bummer - let’s downgrade to a
to serve as a sort of admission ticket; each unlock heavier read lock
operation needs to be passed its correlating stamp.
Any thread that happens to acquire a write lock while stamp = lock.readLock(); //this is a

CONTENTS Page 43
Java 8 / eMag Issue 14 - July 2014

traditional blocking read lock Array.sort(myArray);


try {
//no writing happening now You can now use –
work();
} Arrays.parallelSort(myArray);
finally {
lock.unlock(stamp); // This will automatically break up the target collection
release using the correlating stamp into several parts, which will be sorted independently
} across a number of cores and then grouped back
} together. The only caveat here is that when called in
highly multi-threaded environments, such as a busy
2. Concurrent Adders web container, the benefits of this approach will
Another beautiful addition to Java 8, meant begin to diminish (by more than 90%) due to the cost
specifically for code running at scale, is the of increased CPU context switches.
concurrent “Adders”. One of the most basic
concurrency patterns is reading and writing the value 4. Switching to the new Date API
of a numeric counter. As such, there are many ways in Java 8 introduces a complete new date-time API. 
which you can do this today, but none so efficient or You kind of know it’s about time when most of
elegant as what Java 8 has to offer. the methods of the current one are marked as
deprecated... The new API brings ease-of-use and
Up until now this was done using Atomics, which accuracy long provided by the popular Joda time API
used a direct CPU compare and swap (CAS) into the core Java library.
instruction (via the sun.misc.Unsafe class) to try
and set the value of a counter. The problem was As with any new API the good news is that it’s more
that when a CAS failed due to contention, the elegant and functional. Unfortunately there are still
AtomicInteger would spin, continually retrying the vast amounts of code out there using the old API, and
CAS in an infinite loop until it succeeded. At high that won’t change any time soon.
levels of contention this could prove to be pretty
slow. To help bridge the gap between the old and new
API’s, the venerable Date class now has a new
Enter Java 8’s LongAdders. This set of classes method called toInstant() which converts the Date
provides a convenient way to concurrently read into the new representation. This can be especially
and write numeric values at scale. Usage is super effective in those cases where you’re working on an
simple. Just instantiate a new LongAdder and use API that expects the classic form, but would like to
itsadd() and intValue() methods to increase and enjoy everything the new API has to offer.
sample the counter.
5. Controlling OS Processes
The difference between this and the old Atomics is Launching an OS process from within your code is
that here, when a CAS fails due to contention, instead right there with JNI calls – it’s something you do
of spinning the CPU, the Adder will store the delta half-knowing there’s a good chance you’re going to
in an internal cell object allocated for that thread. It get some unexpected results and some really bad
will then add this value along with any other pending exceptions down the line.
cells to the result of intValue(). This reduces the need
to go back and CAS or block other threads. Even so, it’s a necessary evil. But processes have
another nasty angle to them - they have a tendency
If you’re asking yourself when should I prefer to to dangle. The problem with launching process from
use concurrent Adders over Atomics to manage within Java code so far has been that is was hard to
counters? The simple answer is – always. control a process once it was launched.

3. Parallel Sorting To help us with this Java 8 introduces three new


Just as concurrent Adders speed up counting, Java 8 methods in the Process class -
delivers a concise way to speed up sorting. The recipe
is pretty simple. Instead of -

CONTENTS Page 44
Java 8 / eMag Issue 14 - July 2014

destroyForcibly - terminates a process with a much The only downside is that it’s up to you to find those
higher degree of success than before. places in your code where overflows can happen. Not
an automagical solution by any stretch, but I guess
isAlive tells if a process launched by your code is still it’s better than nothing.
alive.
7. Secure Random Generation
A new overload for waitFor() lets you specify the Java has been under fire for several years for having
amount of time you want to wait for the process security holes. Justified or not, a lot of work has
to finish. This returns whether the process exited been done to fortify the JVM and frameworks from
successfully or timed-out in which case you might possible attacks. Random numbers with a low-level
terminate it. of entropy make systems that use random number
generators to create encryption keys or hash
Two good use-cases for these new methods are - sensitive information more susceptible to hacking.

If the process did not finish in time, terminate and So far selection of the Random Number Generation
move forward: algorithms has been left to the developer. The
problem is that where implementations depend on
if (process.wait(MY_TIMEOUT, TimeUnit. specific hardware / OS / JVM, the desired algorithm
MILLISECONDS)){ may not be available. In such cases applications have
//success! } a tendency to default to weaker generators, which
else { can put them at greater risk of attack.
process.destroyForcibly();
} Java 8 has added a new method
called SecureRandom.getInstanceStrong() whose
Make sure that before your code is done, you’re not aim is to have the JVM choose a secure provider for
leaving any processes behind. Dangling processes you. If you’re writing code without complete control
can slowly but surely deplete your OS. of the OS / hardware / JVM on which it would run
(which is very common when deploying to the cloud
for (Process p : processes) { or PaaS), my suggestion is to give this approach some
      if (p.isAlive()) { serious consideration.
p.destroyForcibly();
} 8. Optional References
} NulPointers are like stubbing your toes - you’ve been
doing it since you could stand up, and no matter how
6. Exact Numeric Operations smart you are today - chances are you still do. To help
Numeric overflows can cause some of the nastiest with this age-old problem Java 8 is introducing a new
bugs due to their implicit nature. This is especially template called Optional<T>.  
true in systems where int values (such as counters)
grow over time. In those cases things that work Borrowing from Scala and Haskell, this template is
well in staging, and even during long periods in meant to explicitly state when a reference passed to
production, can start breaking in the weirdest or returned by a function can be null. This is meant
of ways, when operations begin to overflow and to reduce the guessing game of whether a reference
produce completely unexpected values. can be null, through over-reliance on documentation
which may be out-of-date, or reading code which
To help with this Java 8 has added several new may change over time.
“exact” methods to the Math class geared towards
protecting sensitive code from implicit overflows, by Optional<User> tryFindUser(int userID) {
throwing an unchecked ArithmeticException when
the value of an operation overflows its precision. or -

int safeC = Math.multiplyExact(bigA, void processUser(User user,


bigB); // will throw ArithmeticException Optional<Cart> shoppingCart) {
if result exceeds +-2^31

CONTENTS Page 45
Java 8 / eMag Issue 14 - July 2014

The Optional template has a set of functions


that make sampling it more convenient, such
asisPresent() to check if an non-null value is available, ABOUT THE AUTHOR
or  ifPresent() to which you can pass a Lambda Tal Weiss is the CEO of Takipi. Tal
function that will be executed if isPresent is true. The has been designing scalable, real-
downside is that much like with Java 8’s new date- time Java and C++ applications
time APIs, it will take time and work till this pattern for the past 15 years. He still
takes hold and is absorbed into the libraries we use enjoys analyzing a good bug
and design everyday. though, and instrumenting Java
code. In his free time Tal plays
New Lambda syntax for printing an optional value - Jazz drums.

value.ifPresent(System.out::print);

READ THIS ARTICLE


ONLINE ON InfoQ

CONTENTS Page 46

You might also like