InfoQ - Java8 PDF
InfoQ - Java8 PDF
Java 8
eMag Issue 15 - July 2014
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!
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
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
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)))
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.
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.
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.
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
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.
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
This is equivalent to: Java SE 8 Streams aim to solve that. In Ritter’s words:
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
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
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.
CONTENTS Page 17
Java 8 / eMag Issue 14 - July 2014
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
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.
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.
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
CONTENTS Page 24
Java 8 / eMag Issue 14 - July 2014
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:
CONTENTS Page 26
Java 8 / eMag Issue 14 - July 2014
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.
CONTENTS Page 27
Java 8 / eMag Issue 14 - July 2014
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:
CONTENTS Page 29
Java 8 / eMag Issue 14 - July 2014
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
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
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.
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:
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.
CONTENTS Page 34
Java 8 / eMag Issue 14 - July 2014
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)
An example output:
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.
CONTENTS Page 36
Java 8 / eMag Issue 14 - July 2014
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.
CONTENTS Page 37
Java 8 / eMag Issue 14 - July 2014
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.
CONTENTS Page 42
Java 8 / eMag Issue 14 - July 2014
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.
CONTENTS Page 43
Java 8 / eMag Issue 14 - July 2014
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 -
CONTENTS Page 45
Java 8 / eMag Issue 14 - July 2014
value.ifPresent(System.out::print);
CONTENTS Page 46