You are on page 1of 77

JAVA 9S NEW REPL 43 | NIO.

2 49 | ADVANCED GENERICS 56 | JRUBY 62

ENTERPRISE JAVA

JULY/AUGUST 2016

17 25 31 37
JSF 2.3 JASPIC JSON-P JAVAMAIL
WHATS AUTHENTICATION PROCESS DATA AUTOMATE
COMING? FOR CONTAINERS EASILY ALERTS FROM
JAVA EE APPS

ORACLE.COM/JAVAMAGAZINE
//table of contents /

25 31 37
CUSTOM SERVLET USING THE JAVA APIS USING JAVAMAIL IN
AUTHENTICATION FOR JSON PROCESSING JAVA EE
USING JASPIC By David Delabasse By T. Lamine Ba
By Steve Millidge Two easy-to-use APIs greatly Create web applications that
A little-known Java EE simplify handling JSON data. can send emails.
standard makes it simple to
enforce authentication using
17 your preferred resources.

JAVASERVER FACES 2.3:


WHATS COMING
By Arjan Tijms
New features in JSF resolve long-standing limitations.
COVER ART BY I-HUA CHEN

04 13 56 71
From the Editor Java Books New to Java Fix This
Writing small classes is a universally Review of Building Maintainable Software Generics: The Hard Parts By Simon Roberts
prescribed best practice. While simple in By Michael Klling Our latest code challenges
concept, on real projects this presents its 43 Wildcards, subtyping, and type erasure
Java 9 61
own diiculties.
JShell: Read-Evaluate-Print Loop 62 Java Proposals of Interest
06 for the Java Platform JVM Languages JEP 282 jlink: The Java Linker
Letters to the Editor By Constantin Drabo JRuby 9000: Beautiful 70
Comments, questions, suggestions, Testing code snippets will be part of the Language, Powerful Runtime
and kudos
User Groups
upcoming JDK. By Charles Nutter
Bucharest JUG
09 A simple language that inspired Ruby on
49 Rails facilitates complex Java coding. 76
Events New to Java Contact Us
Upcoming Java conferences and events Modern Java I/O Have a comment? Suggestion?
By Benjamin Evans and David Flanagan
11 Want to submit an article
JavaOne 2016 NIO.2 makes many things easier, includ- proposal? Heres how.
The worlds largest Java conference ing monitoring directories for changes.
01
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
EDITORIAL PUBLISHING
Editor in Chief Publisher
Andrew Binstock Jennifer Hamilton +1.650.506.3794
Managing Editor Associate Publisher and Audience
Claire Breen Development Director
Copy Editors Karin Kinnear +1.650.506.1985 September 1822, 2016 | San Francisco
Karen Perkins, Jim Donahue Audience Development Manager oracle.com/javaone
Technical Reviewer Jennifer Kurtz
Stephen Chin
ADVERTISING SALES
DESIGN Sales Director

REGISTER NOW
Senior Creative Director Tom Cometa
Francisco G Delgadillo Account Manager
Design Director Mark Makinney
Richard Merchn Account Manager
Senior Designer Marcin Gamza
Arianna Pucherelli
Designer
Jaime Ferrand
Advertising Sales Assistant
Cindy Elhaj +1.626.396.9400 x 201 Respond Early, Save $400*
Mailing-List Rentals
Senior Production Manager Contact your sales representative.
Sheila Brennan
Production Designer
Kathy Cygnarowicz RESOURCES
Oracle Products
+1.800.367.8674 (US/Canada)
Oracle Services
+1.888.283.0591 (US) Learn about Java 9 and beyond
450+ educational sessions

ARTICLE SUBMISSION
Explore innovations at the Java Hub
If you are interested in submitting an article, please email the editors.
Network with 500+ Java experts
SUBSCRIPTION INFORMATION
Subscriptions are complimentary for qualified individuals who complete the
subscription form.
MAGAZINE CUSTOMER SERVICE
java@halldata.com Phone +1.847.763.9635
PRIVACY Innovation Sponsor Diamond Sponsor

Oracle Publishing allows sharing of its mailing list with selected third parties. If you prefer
that your mailing address or email address not be included in this program, contact
Customer Service. Gold Sponsor Silver Sponsors

Copyright 2016, Oracle and/or its affiliates. All Rights Reserved. No part of this publication may be reprinted or otherwise
reproduced without permission from the editors. JAVA MAGAZINE IS PROVIDED ON AN AS IS BASIS. ORACLE EXPRESSLY Bronze Sponsors
DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ORACLE BE LIABLE FOR ANY
DAMAGES OF ANY KIND ARISING FROM YOUR USE OF OR RELIANCE ON ANY INFORMATION PROVIDED HEREIN. Opinions
expressed by authors, editors, and intervieweeseven if they are Oracle employeesdo not necessarily reflect the views of Oracle.
The information is intended to outline our general product direction. It is intended for information purposes only, and may not
be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied
upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracles
products remains at the sole discretion of Oracle. Oracle and Java are registered trademarks of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective owners.
Java Magazine is published bimonthly and made available at no cost to qualified subscribers by * Save $400 over onsite registration. Visit oracle.com/javaone/register for early bird registration dates and details.
Oracle, 500 Oracle Parkway, MS OPL-3A, Redwood City, CA 94065-1600. Copyright 2016, Oracle and/or its affiliates. All rights reserved. Oracle and Java are registered
trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.

02
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// JULY/AUGUST 2016
//from the editor /

The Problem of Writing Small Classes


The highly recommended best practice presents a series of challenges that its
advocates rarely address.

T here are few coding practices that, when


followed conscientiously, deliver as much
beneit as writing small classes. Take almost any
code and the wisdom of consultants, there is little
guidance on how to manage the issues that small
classes present.
desirable metricsimplicity, testability, debug- Small classes have been a favorite concern of
abilityand small classes score high. Take almost mine for a long time. Ive written about how to
any undesirable metriccomplexity, error den- tease small ones from larger ones, how to think
sity, brittlenessand small classes score low. In in terms of small code units, and so on. But over
addition, various programming rules of thumb the years, I have found that small classeswhile
point directly toward smaller classes: the single- delivering the promised beneitscreate prob-
responsibility principle, in particular, as well as lems whose solutions are largely unexplored.
many fundamental refactorings. Lets begin by deining a small class. I deine it
With all these beneits, it seems that if you as fewer than 60 lines of code (LOCs). The num-
want to write good code, small classes should ber appears arbitrary, but it works in deliver-
represent a fundamental implementation goal ing classes that can be seen in their entirety
and class size should be a metric that is con- with a single page-up or page-down keystroke
stantly kept in mind as code is written. in the IDE. This same logic drives NASAs
If you work this way, though, youll ind that Power of Ten rule that limits functions also to
for all the advice available on how to write good 60 lines. Classes this size can be read and under-
PHOTOGRAPH BY BOB ADLER/GETTY IMAGES
04
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//from the editor /
stood quickly. Sixty LOCs is not a small classes so that its apparent and down, setting bookmarks,
hard limit, but beyond it, I start they go together. This is where and jumping about inside that
getting itchy. Almost none of my the lack of useful guidelines on one big class. So, in efect, with
classes exceed 70 LOCs. Some designing Java packages becomes small classes Ive replaced that
developers ind a numerical limit glaringly obvious. There are very physical activity with my own. I
objectionable and would prefer few useful ideas on the topic use multiple windows across two
the minimum LOCs necessary of packaging. Sites use mostly screens, which solves many of
for the taskwhich invariably a seat-of-the-pants approach, my problemsat a glance, I can
leads to classes in which size is no which is rarely the right way to see the code I need in the open
longer a disciplined constraint do things. The trees in my pack- window.
while a hard number leads you to age hierarchy are bushier than In sum, working hard to create
review lengthy code looking for those of most projects. This pro- small classes presents a series
refactorings that simplify it. vides beneits in that its much of challenges that are little dis-
Whatever number you settle clearer where to look for certain cussed either in the literature or
on, if you start using it as a functionality. In addition, access in the counsel of experts. Given
discipline-inducing limit, you restriction can be made very that diminutive classes make
quickly run into several chal- granular. The disadvantage is testability much easier and more
lenges. The irst is perhaps the that its not always easy to group thorough, facilitate legibility
most persistent problem in classes into smaller packages. and maintainability, and enforce
computing: naming. As objects Choosing whether FontDisplay object-oriented basics, the extra
become smaller, more are goes here or is more logically part work to igure out these chal-
created, and more names must of another package can take care- lenges by yourself seems well
be formulated. FontHandler ful consideration. However, that worth it.
becomes FontLocator, Font- kind of review helps reine the
Veriier, FontLoader, FontMetric- projects design. Andrew Binstock, Editor in Chief
Extractor, and so on. After a The inal problem is purely javamag_us@oracle.com
while, you begin to codify a set mechanical. In my IDE, I often @platypusguy
of naming conventions that have many, many tabs open to
you use with precision so that small classes, and I do a lot of P.S. In this issue, we continue our
two classes with similar names bounding around between the reinement of the magazines
can be readily distinguished. various windows. At times, this design with a more legible code
Inspector is not the same as can be a pain. If all the code were font that lets us print more
veriier, which is not the same in one big class, Id have one place characters per line, and so wrap
as validator, and so on. to go, which is easy. However, code less often. Feel free to send
This leads to a second problem, when I got there, I would ind other suggestions to me at the
which is the proper grouping of myself constantly scrolling up address above.
05
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//letters to the editor /
ENUMS 40 | JPA CRITERIA 45 | GOLO LANGUAGE 54
Polymorphic Dispatch with Enums private String commandString;
I would like to comment on the article Making
MARCH/APRIL 2016

the Most of Enums (March/April 2016, page 40). In CommmandWord(String commandString) {


that article, Michael Klling points out how enums this.commandString = commandString;
improve type safety and internationalization and how }
they allow the easy creation of thread-safe singletons.
Inside Java
and the JVM While he mentions that enum declarations are public String toString() {
14 20 24 28 35 classes, and enum values refer to objects, he missed return commandString;
UNDERSTANDING G1 AND INSIDE THE HOW JAVA PROCESSING

the opportunity to show how this enables poly-


WHAT THE JIT IS SHENANDOAH: JVMS CODE COLLECTIONS ANNOTATIONS
DOING THE NEW GARBAGE
COLLECTORS
CACHE BECAME LAZY
}
morphism and allows for more object-oriented and
ORACLE.COM/JAVAMAGAZINE

maintenance-friendly programs. public abstract void exec(String secondWord);


MARCH/APRIL 2016
Building upon the adventure game example, sup- }
pose you want to add the drop command. You have
added the DROP("drop") constant to the enum and By adding curly braces after the declaration of an
implemented the dropItem() method. Yet the pro- enum constant, you create an anonymous subclass of
gram still does not recognize the command. The CommandWord, which is used only to create the instance
problem is that you failed to add the appropriate case for this speciic constant. By overriding the abstract
to the switch statement. exec() method, you add command-speciic behavior
Let us extend the enum declaration further: to the individual constants.
With this change in place, the entire switch state-
public enum CommandWord { ment can be replaced with a single line:
GO("go") {
@Override commandWord.exec(secondWord);
public void exec(String secondWord) {
// logic from the goRoom() method If you now want to add the drop command, you only
} have to add another constant to the enum declaration.
}, And if you forget to override the exec() method, the
// ... compiler will complain about it because it was deined
// the other commands follow a similar pattern as abstract in the CommandWord enum itself.
// ... Tobias Stensbeck
QUIT("quit") {
@Override Michael Klling responds: You make a very good point,
public void exec(String secondWord) { and I did indeed miss an opportunity to go further and
// logic from the quit() method discuss polymorphic dispatch with enum methods, and
} how this can further improve the code. The gain you
}; describeavoiding the switch statement and replacing
06
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//letters to the editor /
it with a single polymorphic callis one of the most sig- hosting services will eventually have to be paid for,
niicant improvements that come out of the replacement but we see a future for free baseline features.
of constants with enums. It improves maintainability and Although companies involved with hosting projects
removes the implicit coupling. You discuss the method and have either discontinued them or shut their doors,
advantages perfectly, and all that remains for me is to hosting projects will remain a vital, if not ubiquitous,
thank you for bringing this up. part of the developer community as the demand for
digital content and increased collaboration continues
The Misery of Project Hosting? to grow.
In The Miserable Business of Hosting Projects (May/ Job van der Voort
June 2016, page 4), Andrew Binstock speculates on Vice President of Product, GitLab
whether the current model of free open source host-
ing is sustainable, examining several hosting ser- Codehaus and What Came Next
vices, including GitLab. While I cant speak for other Re: the editorial The Miserable Business of Hosting
companies, I can share thoughts from us at GitLab on Projects, I consider my involvement with the for-
several of the points mentioned in the piece. mer Codehaus to be one of the deining aspects of
In regard to the industry as a whole, it has seen my professional career. As folks who participated in
some growing pains but its not quite as miserable the Codehaus know, the members were known as
as the title of the article suggests. The freemium hausmates and many personal relationships were
model is a well-known pricing strategy for SaaS formed through the involvement of project partici-
[software-as-a-service]based companies across pants. These relationships form a web of many of the
many markets, not just hosting projects, with compa- bright stars of the industry, across ThoughtWorks,
nies that have free solutions also ofering paid ver- Walmart, DRW, Google, Square, Twitter, Red Hat,
sions to help customers pay only for what they need, and others.
along with allowing them to test-drive services. The Codehaus always tried to be pragmatic, in order
We see this pricing strategy following the same to ofer the best environment possible. This allowed
path as email, which now exists as a free service with us to take support from Atlassian for its suite of
additional features (extra storage) available at an tools; from JetBrains for licenses to its IDEs; and
additional cost. In terms of cost eiciency, weve seen others including Sonar, which grew at the Codehaus
success through an open core model with a strong itself. Additionally, we were always thankful for
community vital to the development and implemen- the support of Matthew Porter and his company,
tation of new features. Other companies take a simi- Contegix. Id be completely remiss if I did not mention
lar approach, taking revenue from an Enterprise Ben Walding, who kept the Codehaus operational for
or paid version of a service in conjunction with addi- much of its lifetime. (I was merely a igurehead.)
tional paid options to keep up with the growth in sub- The article rings true regarding how GitHub ate
scriptions for their free editions. Mr. Binstock men- everyones lunch. I love GitHub, and it has knocked
tioned that services currently free to developers using the ball out of the park. While the footprint of its
07
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//letters to the editor /
services is smaller than that of the Codehaus, its
augmented by other organizations, such as Travis CI,
CloudBees, and Google Groups. One of the leading
points of the Codehaus Manifesto was acknowledging
strong project leadership. The current combination of
GitHub/GitLab, providers of continuous integration,
and so on deliver such leadership within a project.
Bob The Despot McWhirter
Cofounder, Codehaus

Erratum
In the May/June issue, in Mr. Kllings article
[Understanding Generics, page 45], he several times
uses HashSet() in his code examples. But I believe
that he meant to use HashMap(), which will actually
work in the code he presents.
Bibhaw Kumar

Michael Klling responds: Youre quite right. HashSet()


has only one generic parameter. My apologies for the
confusion this caused.

Where Are the Back Issues?


Several readers have inquired about the lack of access
to back issues. This is a temporary problem that
occurred when we switched content delivery net-
works. It should be resolved by press time or shortly
thereafter. Our apologies for the inconvenience.

Contact Us
We welcome comments, suggestions, grumbles,
kudos, article proposals, and chocolate chip cookies.
All but the last two might be edited for publication.
If your note is private, indicate this in your message.
Write to us at javamag_us@oracle.com. For other
ways to reach us, see the last page of this issue.
08
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//events /
JVM Language Summit ably. Subject matter is aimed
AUGUST 13 at software developers, engi-
SANTA CLARA, CALIFORNIA neers, project managers, qual-
The JVM Language Summit is ity assurance specialists, and
an open technical collabora- test managers. Participants get
tion among language design- both one-on-one interaction
ers, compiler writers, tool with instructors and opportu-
builders, runtime engineers, nities to network with other
and architects who target the software professionals.
JVM. This years event will be
held in Oracles auditorium. JavaZone
Presentations will run in a SEPTEMBER 68
single track and are allotted 45 OSLO, NORWAY
minutes each (including ques- This year marks the 15th
tions). Workshop sessions will anniversary of JavaZone. The
run for 60 minutes, with two event consists of a day of
or more sessions in parallel. workshops followed by two
Breakfast and lunch are served days of presentations and
onsite. Breakout rooms are more workshops. Last years
available for workshops, con- event drew more than 2,500
versation, and ad hoc consul- attendees and featured 150
tations. Presentations will be talks covering a wide range of
recorded and made available to Java-related topics.
JavaOne SEPTEMBER 1822
SAN FRANCISCO, CALIFORNIA the public.
JDK IO
The ultimate Java gathering celebrates its 20th year. JavaOne features
DevOps Week DC SEPTEMBER 1315
hundreds of sessions and hands-on labs. Topics covered include the core
AUGUST 1519 COPENHAGEN, DENMARK
Java platform, security, DevOps, IoT, scalable services, and development
WASHINGTON DC This annual event hosted by
tools. Georges Saab, vice president of development for the Java Platform
DevOps Week features a series the Danish Java User Group
Group at Oracle and chair of the OpenJDK governing board, and Mark
of specialized courses designed consists of a two-day confer-
Reinhold, chief architect of the Java Platform Group, are slated to speak
to help organizations create ence followed by one day of
at the event, as are many members of the Java development team. Highly
an environment where the workshops. The focus is on all
anticipated Java 9 release enhancements will be presented and discussed.
building, testing, and releas- things Java: the language, the
(See page 11 for more information.)
ing of software can happen platform, the frameworks, and
more rapidly and more reli- the virtual machine.
PHOTOGRAPH BY ERIC E CASTRO/FLICKR
09
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// JULY/AUGUST 2016
//events /
Architecture Conference is explor- W-JAX
ing evolutionary architecture to NOVEMBER 711
relect the broadening of the ield, MUNICH, GERMANY
encompassing new disciplines W-JAX is a conference focused
such as DevOps. Topics include on Java, architecture, and soft-
strategies for meeting business ware innovation. More than 160
goals, developing leadership presentations on technologies
skills, and making the conceptual and languages ranging from Java,
jump from software developer Scala, and Android, to web pro-
to architect. gramming, agile development
models, and DevOps are planned.
VOXXED Days THESSALONIKI The main conference takes place
OCTOBER 21 November 810, with workshops
THESSALONIKI, GREECE scheduled on November 7 and 11.
The inaugural VOXXED Days (No English page available.)
event in Thessaloniki is a devel-
oper conference that promises
expert speakers, core developers Special Note: Event Cancellation
of popular open source technolo- QCon Rio
gies, and professionals willing to OCTOBER 57
Strange Loop ence for cutting-edge software share their knowledge and experi- RIO DE JANEIRO, BRAZIL
SEPTEMBER 1517 engineers and enterprise-level ences. Former Oracle Technology The organizers report: Faced
ST. LOUIS, MISSOURI professionals, bringing together Evangelist Simon Ritter is with an unstable political and
Strange Loop is a multidisciplin- the worlds leading innovators in scheduled to present JDK 9: Big economic environment . . . we
ary conference that brings the ields of Java, microservices, Changes to Make Java Smaller. considered it prudent to cancel our
together developers and think- continuous delivery, and DevOps. edition of QCon 2016. We empha-
ers in ields such as emerging Hands-on workshops take place Devoxx size that this decision does not
languages, alternative databases, on October 10, followed by confer- NOVEMBER 711 afect the preparation of QCon
concurrency, distributed systems, ence sessions, keynotes, and expo. ANTWERP, BELGIUM So Paulo 2017.
security, and the web. Devoxx is one of the largest
OReilly Software Architecture mostly Java conferences in the Have an upcoming conference
JAX London Conference world, with numerous experts youd like to add to our listing?
OCTOBER 1012 OCTOBER 1921 from the US and Europe present- Send us a link and a description of
LONDON, ENGLAND LONDON, ENGLAND ing a wide range of sessions on all your event four months in advance
JAX London is a three-day confer- This year, the OReilly Software aspects of Java development. at javamag_us@oracle.com.
PHOTOGRAPH BY CCHANA/FLICKR
10
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// JULY/AUGUST 2016
//conference /

JavaOne 2016
The largest Java conference is again a must-attend event.

J avaOne San Francisco, the central Java conference of


the year, will be held September 1822 at its custom-
ary sitea pair of hotels near Moscone Center in down-
Cloud and server-side development, focusing on Java EE;
enterprise technologies such as those discussed in this
issue; and all things cloud, especially microservices
town San Francisco, California. As usual during the last Devices, including coverage of the Internet of Things
20 years of the conference, the irst event is the opening and Java ME, among other topics
keynote, on Sunday, September 18. The next four days Java clients and user interfaces, highlighted in 35 ses-
see in-depth tutorials in the morning and more than sions, 20 of which are on JavaFX
300 presentations running from late morning until early Development tools
evening. Evenings are set aside for Birds of a Feather DevOps and methodologies, focusing mainly on auto-
meetings, which are informal gatherings of developers mation but also featuring sessions on design, code
who want to compare notes and share insights on a par- quality, and project management
ticular topic. The conference is preceded on Saturday, September 17,
If youve ever attended JavaOne, you know that experts by JavaOne4Kids, a series of workshops and tutorials for
deliver the tutorials and presentations. Many of these programmers and programmer-hopefuls from ages 10 to
experts are members of the core Java development team, 18. On Sunday, September 18, there are full-day inten-
Java Champions, or JavaOne Rock Stars. (This last title is sives, called Java University, which are separate events,
accorded to JavaOne speakers whose previous sessions paid for separately and held at a diferent venue. Finally,
were among the most highly rated.) there is a trade-show component to JavaOne, with
The sessions in this years event are divided into seven more than 40 vendors available to present products and
tracks on the following topics: answer questions.
The core Java platform, which has more than a dozen JavaOne is a deep dive into all things Java and the place
sessions dedicated to Java 9 and components of JDK 9 to meet and listen to the worlds premier Java experts
and half as many focused on illuminating the dark and speakers.
corners of Java 8
Emerging languages, such as the JVM languages we
Main JavaOne site
cover in every issueKotlin, Groovy, Scala, and
Registration
othersas well as cutting-edge languages that are
emerging in new domains Catalog of sessions (viewable by track)
11
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//java books /
BUILDING MAINTAINABLE SOFTWARE (JAVA EDITION)
By Joost Visser (principal author)
OReilly Media

There are many books available level of expertise to be qualiied for each guideline for code that
on writing good code. They dig as authors: practitioners of soft- aims to be in the topmost tier
into a bag of well-known tips ware engineering, the discipline of quality. For example, on the
and recommendations that are that quantiies software devel- rule against redundant code, the
aimed at beginner and interme- opment via analysis of thousands authors state that their model
diate programmers. The prob- of projects from all areas of allows no more than 4.6 percent
lem with some of these books programming. The problem is of lines of code to be redundant.
is that its hard to tell how the that most software engineering Thats helpful data, and it under-
authors are qualiied to dole experts dont examine coding scores the fact that guidelines
out their advice. Most authors style and so, as a ield, theyve cannot always be followed 100
of these texts are consultants, said relatively little on the topic. percent of the time. Ill come
which suggests that they see a The principal author of this book back to this in a moment.
wide range of code. However, and his colleagues come close Each guideline is presented, its
most consultants work within to this level of qualiication, raison dtre explained, its appli-
a narrow range of industries though. For 15 years, theyve cation demonstrated, and the
and dont often stray into areas run the Software Improvement counterarguments to it contested.
where programming is done Group, which studies software This last part is an imaginative
substantially diferently. For quality quantitatively based in addition that targets the reasons
example, can authors credibly part on coding style. developers tell themselves for not
discuss rules for testability if From this work, they came obeying a guideline.
theyve never written software up with 10 guidelines, most of The examples chosen for each
that could cost lives when errors which will be familiar (write guideline contain problematic
occur? Can authors who have no small units of code, use loose code and show the resolution,
experience proving code correct coupling, automate tests, and so frequently relying on tried-and-
speak with authority on writing on). They present them in the true techniques. For example,
correct code? context of a prescriptive model to reduce duplicate code, the
One group of professionals of maintainability, which has authors wisely suggest using
comes close to meeting the high strict numerical requirements the Extract Method and Extract
13
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// JULY/AUGUST 2016
//java books /

Get Java
Superclass refactorings. These values in a switch are no longer
examples are useful although not enforced in a HashMap. (Adding
suiciently numerous to be a guide objects with the same key to a
for readers who are keen to imple- HashMap simply overwrites exist-
ment the suggestions fully. (For ing entries without any error.) The
that, I recommend Martin Fowlers
classic, Refactoring.)
Some implementation sugges-
tions strike me as dubious. For
example, in the chapter on
solution is also weak because if
we handle the lags of, say, Africa,
surely writing by hand 54 classes
is more complex than one large
switch statement. The proposed
Certified
avoiding complexitywhich is
measured solely via cyclomatic
approach also shows a lack of
understanding of enums in Java,
Oracle University
complexitythe authors unwisely which are full classes and guaran-
dig into the switch statement. The teed to maintain the unique keys.
switch construct is a known weak- In addition, by using an enum dec-
ness in the cyclomatic complexity laration, all 54 classes for African
measure, which greatly overesti- lags are generated by the compiler.
Upgrade & Save 35%*
mates its complexity. In an exam- And the EnumMap gives you the data
ple of associating colors with the structure you want.
lags of six European nations, the Although I wish the book more
authors try to prove that a forgot- thoroughly explored topics and Get noticed by hiring managers
ten break statement in the six-way I have quibbles with some of the
switch is the result of complexity. proposed solutions, the overall Learn from Java experts
Problems that arise from complex- level of this work is better than
ity are generally the inability to many other volumes that advise Join online or in the classroom
understand code and how to ix how code should be written. It
it, rather than an omission that certainly can be recommended to
Connect with our Java
is detected by all code analyzers. beginners and early intermediate
The authors suggest that the ideal programmers and those whose
certification community
solution is to create six separate work shows a repeated problem in
classesone for each country code reviews. Andrew Binstock
instantiate each one, and put the
Save 35% when you upgrade or advance your existing Java certification. Offer expires December 31, 2016. Click for further details, terms, and conditions.

resulting objects into a HashMap.


This solution is suboptimal
because the uniqueness of key
14
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// JULY/AUGUST 2016
The Profusion of T
he history of Java in the enterprise is the story
of the evolution of a complex knot of technolo-
gies into a palette of services that can be used
collectively or individually. This evolution par-

Enterprise Services allels the progress of services in general from tightly


bundled to loosely coupled. This direction continues in
the present with the design and implementation of so-
called microservices.
In this issue, we examine some services that are used
in enterprise apps either with containers or in full-scale
Java EE apps. In the latter grouping is an update on
JSF 2.3 (page 17), which is one of the most actively evolv-
ing standards. Our article on JavaMail (page 37) shows a
classic Java EE service that can easily be used with other
kinds of apps. Its value is not so much in building mail
servers and readers but rather in enabling apps to send
out alerts and updates to sysadmins or users.
JASPIC (page 25), the little-known but potent method
of implementing custom security in applications, shows
how much services can be created as standalone mod-
ules that plug into larger applications. Finally, for devel-
opers new to Java services, we include a tutorial on using
JSON-P (page 31), the oicial libraries for handling JSON
in Java.
We extend our series on JVM languages with an article
on JRuby (page 62) written by its principal developer,
Charlie Nutter. Our ongoing exploration of features in
the upcoming Java 9 release examines JShell (page 43),
the interactive REPL for Java. And, of course, we con-
tinue with our tutorials, detailed quiz, letters from
readers, book review, and other content we expect
youll ind interesting.

ART BY I-HUA CHEN


16
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /

JavaServer Faces 2.3:


Whats Coming
New features promise to resolve long-standing limitations.
ARJAN TIJMS

J avaServer Faces (JSF) is the component-based model-


view-controller (MVC) framework in Java EE. It was irst
included in Java EE 5 in 2006, although it had been available
While Contexts and Dependency Injection (CDI) had already
transparently replaced the JSF native bean facility in JSF 2.0,
some native featuressuch as the often-used view scope
separately for two years prior to that. During its 12-year exis- kept people tied to native managed beans. JSF 2.2 started the
tence, JSF has reinvented itself several times. alignment with CDI by introducing a CDI-compatible view
scope as well as basing its new low scope directly on CDI.
JSF History up to Recent Times Were JSF created today, it would likely be based fully on
In version 1.2, JSF transitioned from a separate framework to CDI to begin with. That is, most of the factories and plugin
being integrated in Java EE, which led to ixing some major points that JSF ofers today would be based on the CDI bean
issues regarding JSP compatibility and removing JSFs own manager, CDI extensions, and decorators. While this would
expression language (EL) in favor of the language provided certainly be desirable for new projects, such a full re-creation
by JSP. of JSF would be diicult, if not impossible, to keep backward-
JSF 2.0 in 2009 was the largest evolutionary step to date: compatible. One of the virtues of JSF (and Java EE in general)
postbacks, a heavy view state, and encapsulation of links is a strong focus on backward compatibility: 10-year-old JSF
(navigation rules) were all de-emphasized in favor of REST- applications should still largely or even fully run on the very
style verbs, limited support for the MVC action pattern, and a latest versions of Java EE. This often makes it relatively pain-
much smaller view state (efectively abandoning the restore- less to upgrade. Instead of facing a large amount of up-front
view concept and instead rebuilding a view from scratch after work in order to migrate to a newer version of Java EE, exist-
a postback). ing code can run as is, while the application is updated
JSF 2.2, which appeared in 2013, continued the direction of piece by piece to take advantage of newer APIs.
JSF 2.0 by further de-emphasizing state with the introduction In the light of this history, JSF 2.3 will align further with
of a completely stateless mode, de-emphasizing components CDI, but it will do so in a backward-compatible way and pro-
somewhat by introducing syntax to create pages directly in vide switches for reverting back to earlier behavior. JSF 2.3
HTML (with only a special namespace attribute to connect will also take advantage of Java 8 where possible and will
the syntax to the server-side logic), and more support for the take advantage of additional Java EE services, such as the
MVC action pattern. WebSocket support that was introduced in Java EE 7.
17
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
In this article, I demonstrate two features that have largely etary SPI, such as the aforementioned InjectionProvider,
been completed as of version 2.3 milestone 6 of the reference but instead uses genuine CDI beans. Efectively, JSF uses the
implementation. They are CDI alignment with regard to con- standardized BeanManager here as the mechanism to both
verters and validators, injection, and EL resolution; and using obtain those artifacts and to provide injection and all the
bean validation for multicomponent validation. I also show two other services that come for free when CDI is used.
features that are well underway but have not been completed For backward-compatibility goals, the native lookup and
at the time of writing this article. They are extensionless URLs, injection machinery is retained. In fact, behind the scenes,
and programmatic and annotation-based coniguration. Mojarra currently uses an old native converter that delegates
To follow this article, you need to be familiar with Java EE to the CDI-based converter to transparently integrate this
technologies and JSF concepts. Its not intended to be an newer type of converter into the runtime. (This is a trick
introductory tutorial. thats seen more often in Java EE.)

CDI Alignment CDI-Based EL Resolver


JSF has supported @Inject-based injection in many of its arti- Another area where JSF 2.3 replaces its own functionality
facts since JSF 2.2. This ability works much like how a servlet with that of CDI is with respect to the EL resolver for implicit
supports @Inject without actually being a CDI bean. Theres objects. Implicit objects are the variables that you can use
a service provider interface (SPI) that each application server via EL on, for example, a Facelet such as #{facesContext},
vendor needs to implement to provide injection services. #{request}, #{param}, and so on. Currently the JSF spec
In the case of Oracles open source implementation of JSF, states that these objects should be resolved via a JSF-speciic
Mojarra, this is the com.sun.faces.spi.InjectionProvider EL resolver.
interface. CDI, however, already provides a universal EL resolver. The
While this approach provides an abstraction over the actual main advantage of using this resolver is that JSF can auto-
injection service, which is occasionally useful by itself, its matically take advantage of speciic performance improve-
disadvantage is obviously that its a nonstandard interface ments, and using the CDI resolver releases JSF from the bur-
that needs to be implemented separately for each JSF imple- den of having to duplicate similar improvements and tunings
mentation and each Java EE application server that wishes to in its own resolver.
fully support JSF. This not only creates an N x M proliferation The way the universal CDI EL resolver works is by having
problem that prohibits freely mixing and matching imple- so-called built-in Bean<T>s available, which have a name (the
mentations, but it also greatly limits the extent to which CDI implicit objects name) and a create() method that produces
features can be supported. For example, a PhaseListener may the implicit object itself. Almost a side efect from the point
support @Inject, but it does not support a scope, cant be of view of EL resolving is the fact that by using Bean<T>, those
decorated, and cant contain interceptors, and the injection very same implicit objects can also trivially be made available
points generally cant be modiied using CDI extensions. for injection. Furthermore, a scope can be set. Such scope will
For a limited number of artifacts (converters, validators, function as a kind of cache and might further help with per-
and behaviors), JSF 2.3 takes a diferent approach. A variant formance, although care must be taken that the scope accu-
of those artifacts is available that does not rely on a propri- rately relects the lifetime of the implicit object.
18
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
The following code shows an example of a builder for a requirement that a password from the main input ield be the
Bean<T>: same as one from the conirmation input ield.
The need for multicomponent validation was recognized
public class HeaderValuesMapProducer extends long ago and, in fact, the very irst issue ever publicly iled
CdiProducer<Map<String, String[]>> { for JSF asked for exactly this functionality. Historically, solu-
tions to this problem were found in creating special compo-
public HeaderValuesMapProducer() { nents (such as a single component with two input ields, one
super.name("headerValues") for the main entry and one for the conirmation), using spe-
.scope(RequestScoped.class) cial multicomponent validators from utility libraries such as
.qualifiers( OmniFaces, or just validating manually in the action method.
new HeaderValuesMapAnnotationLiteral()) In all this time, this basic problem was never addressed at
.types( a foundational level. JSF 2.3 has taken an initial attempt at
new ParameterizedTypeImpl( resolving this problem by again utilizing an existing platform
Map.class, service: class-level bean validation.
new Type[]{String.class, The idea here is that a special constraint validator is
String[].class}), attached to a backing bean. Per the bean validation rules, this
Map.class, attachment happens by irst deining a special annotation,
Object.class) then deining an implementation of ConstraintValidator,
.beanClass(Map.class) then linking the annotation to the ConstraintValidator
.create(e -> via an attribute on the annotation, and then annotating the
FacesContext.getCurrentInstance() backing bean with this.
.getExternalContext() The following code shows an example:
.getRequestHeaderValuesMap());
} @Named @RequestScoped
} @ValidIndexBean(groups =
java.util.RandomAccess.class)
Multicomponent Validation public class IndexBean implements
One important reason for using a web framework such as JSF ConstraintValidator<ValidIndexBean, IndexBean> {
is that it provides well-deined facilities for validating data @Constraint(validatedBy = IndexBean.class)
coming from the client. In JSF, this works by attaching either @Target(TYPE) @Retention(RUNTIME)
a native validator to the source side (the component, such as public @interface ValidIndexBean {
input text) or a bean validation constraint to the target side String message() default "Invalid Bean";
(the backing bean property). Class<?>[] groups() default {};
In both cases, validation works only for input coming in via Class<? extends Payload>[] payload() default{};
a single component. While this works great for validating that }
a password is at least eight characters, it doesnt help with the public void initialize(
19
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
ValidIndexBean constraintAnnotation) {} @Target(TYPE) @Retention(RUNTIME)
public boolean isValid( public @interface ValidateEqual {
IndexBean other, String message() default "Invalid Bean";
ConstraintValidatorContext context) { Class<?>[] groups() default {};
return other.getFoo().equals(other.getBar()); Class<? extends Payload>[] payload() default {};
} String[] inputs();
}
@NotNull
private String foo; Note the extra attribute inputs.

@NotNull Then the actual validator can be defined:


private String bar;
// + getters/setters public class ValidateEqualValidator implements
} ConstraintValidator<ValidateEqual, Object> {

For a reusable validator, such as @Email, which can be applied private List<String> inputs;
to many diferent ields in diferent beans, this work is surely
worth it. Multicomponent validation for backing beans is, public void
however, often more ad hoc, and for a one-of validation case initialize(ValidateEqual constraintAnnotation) {
for a single bean, the number of moving parts is perhaps a bit this.inputs =
too much. asList(constraintAnnotation.inputs());
Alternatively, a library of somewhat more-reusable valida- }
tors can be createdfor example, the bean validation coun-
terparts of the OmniFaces multicomponent validators such as public boolean
validateEqual, validateOneOrMore, validateOneOrNone, and isValid(Object bean,
so on. ConstraintValidatorContext ctx) {
To contrast with the example above, Ill show an example return new
of a reusable validateEqual validator that uses an EL-enabled HashSet<>(collectValues(bean, inputs))
attribute to specify the bean properties that should be vali- .size() == 1;
dated. Note that using EL for this is just an example and there }
are certainly other feasible options, such as marking the }
properties with annotations.
Ill irst deine the validation annotation, this time This validator works by leveraging the platform-provided
separately: ELProcessor from the EL 3.0 spec to easily obtain the prop-
erty values from the bean that is being validated. This is
@Constraint(validatedBy = ValidateEqualValidator.class) done as follows:
20
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
public static List<Object> collectValues(Object bean) { @Named
ELProcessor elProcessor = getElProcessor(bean); @RequestScoped
@ValidateEqual(
return inputs.stream() groups = RandomAccess.class,
.map(input -> elProcessor.eval(input)) inputs={"this.foo", "this.bar"})
.collect(toList()); public class IndexBean {
} @NotNull
private String foo;
A fully functional ELProcessor for usage in a Java EE environ- @NotNull
ment can be obtained by just instantiating a new instance, private String bar;
and then providing it with the ELResolver from the CDI bean // + getter/setters
manager. This can be done as shown below: }

public static ELProcessor getElProcessor(Object bean) { Note here that the inputs attribute is initialized with EL refer-
ELProcessor elProcessor = new ELProcessor(); ences to the two properties that should be validated together.
In both cases, the part of a Facelet containing the actual
elProcessor.getELManager() input components looks as follows:
.addELResolver(
CDI.current() 01 <h:form>
.getBeanManager() 02 <h:inputText value="#{indexBean.foo}">
.getELResolver()); 03 <f:validateBean validationGroups =
04 "javax.validation.groups.Default,
elProcessor.defineBean("this", bean); 05 java.util.RandomAccess" />
06 </h:inputText>
return elProcessor; 07
} 08 <h:inputText value="#{indexBean.bar}">
09 <f:validateBean validationGroups =
Notice, in particular, that in the getElProcessor() method, 10 "javax.validation.groups.Default,
the bean to be validated is being added to the ELProcessor 11 java.util.RandomAccess" />
context under the "this" name. This approach will be used 12 </h:inputText>
when the properties that should be validated are deined 13
shortly. (As a side note, its perhaps interesting to realize that 14 <f:validateWholeBean value="#{indexBean}"
four diferent Java EE specs are used together here rather 15 validationGroups="java.util.RandomAccess"/>
seamlessly: those for JSF, bean validation, EL, and CDI.) 16
Finally, the backing bean is annotated again, but this time 17 <h:commandButton value="submit" />
with the reusable validator: 18 </h:form>
21
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
[Lines 4 and 5 are wrapped due to space constraints and The goal for extensionless URLs in JSF 2.3 is threefold:
should be entered as a single line, as are lines 10 and 11. Ed.] First, path mapping should work without an extension.
A rather important aspect of full class bean validation in For example, a URL such as http://example.com/faces/page
combination with JSF is that the bean seen by the valida- should work out of the box.
tor is a copy of the backing bean and not the actual backing Second, exact mapping should be oicially supported. For
bean. The reason for this is that the JSF validation semantics example, a URL such as http://example.com/page should
demand that the model (the backing bean) is not updated work when the following mapping is present in web.xml:
when any validation or conversion failure happens. However,
full class bean validation can happen only after the bean has <servlet>
been fully updated. To break this mismatch, the runtime <servlet-name>Faces Servlet</servlet-name>
irst makes a copy of the backing bean, updates this copy, <servlet-class>
and validates it. Only if all validation constraints pass is the javax.faces.webapp.FacesServlet
actual backing bean updated. </servlet-class>
</servlet>
Extensionless URLs <servlet-mapping>
JSF is implemented internally via a servlet, the so-called <servlet-name>Faces Servlet</servlet-name>
FacesServlet, which listens to requests that have a spe- <url-pattern>/page</url-pattern>
ciic pattern. By default, this pattern includes "/faces/*", </servlet-mapping>
"*.jsf", "*.faces", and, as of JSF 2.3, "*.xhtml". Users can
set their own pattern in web.xml using the same servlet syn- Third, the most ambitious part of the goal is that a URL
tax thats used to map any servlet to a URL pattern. such as http://example.com/page should work without
As can be seen from the information above, both path map- requiring the user to map /page (or any page) explicitly by
ping and extension mapping are supported. An example of path using exact mapping, but rather it should work by setting
mapping would be http://example.com/faces/page.xhtml, only a single coniguration option.
while an example of extension mapping would be something At press time, its not yet clear how the third goal should be
like http://example.com/page.jsf. implemented, but a possible approach would be adding a new
In modern web applications, its often desirable to have listViewResources() method to the ResourceHandler, and
clean URLsthat is, URLs that speciically dont have an then taking advantage of the Servlet 3.0 specs programmatic
extension and generally dont have any kind of clutter in mapping during application startup to automatically add
them. Unfortunately, JSF does not support such URLs out of exact mappings for all view resources (for example, Facelets)
the box. Curiously, even when you are using path mapping, an that are handled by a given ResourceHandler.
extension is still required, as shown above.
Clean URLs in JSF can be obtained by using third-party Programmatic and Annotation-Based Configuration
libraries, such as PrettyFaces or OmniFaces, but this kind of High-level declarative coniguration in JSF is done using
functionality is now deemed to be suiciently well under- either context parameters in web.xml or the dedicated
stood and mature that it qualiies for inclusion in JSF itself. faces-config.xml iles. Additionally, there are some
22
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
lower-level options available, such as coniguration via the @FacesConfig(
Application class or programmatically by providing the con- stateSavingMethod = Server,
tent of a faces-config.xml ile via a callback and the XML faceletsRefreshPeriod = -1,
Document Object Model (DOM) API. projectStage = Production
Context parameters in web.xml particularly have the disad- )
vantage of consisting of mere strings (usually long ones) that public class SomeClass {
have to be looked up and can be misspelled easily. Its also
not directly possible to see what the defaults are for any given }
coniguration item.
Both web.xml and the faces-config.xml ile that resides in The intent here is to use strongly typed values where pos-
a .war iles WEB-INF folder have the shared disadvantage that sible. For example, the Server value would come from an
they cannot be read by CDI extensions and other artifacts that enumeration.
start up early in the Java EE boot process. Although it hasnt been fully worked out yet, the pro-
Finally, XML-based iles (so-called deployment descriptors) grammatic aspect might be added using EL-enabled attri-
are not particularly lexible, speciically because theres no butes, much as in the validator example shown earlier,
overall platform service in Java EE that allows placeholders in for example:
them or a way to provide conditional included iles or overlays.
Because of the above issues, its planned to provide an @FacesConfig(
annotation-based and optionally programmatic high-level stateSavingMethod = Server,
coniguration system in JSF. In its most basic form, such con- faceletsRefreshPeriodExpr =
iguration looks as follows: "this.faceletsRefreshPeriod",
projectStageExpr = "configBean.dev?
@FacesConfig 'Development' : 'Production'"
public class SomeClass { )
public class SomeClass {
} int getFaceletsRefreshPeriod() {
return ? -1 : 0;
This coniguration by itself will automatically add the JSF }
servlet mappings, which is currently done when an empty }
(but valid) faces-config.xml ile exists or when, for example,
the deprecated @ManagedBean annotation is encountered on In this example, the faceletsRefreshPeriod is set by an
any class in the application. expression that directly refers to a property of the bean on
As an alternative to the mentioned context parameters, which the annotation appears. Inside the getter method
attributes on the @FacesConfig annotation can be used to of that property, arbitrary logic can be used to determine
conigure various aspects of JSF: the desired outcome. The projectStage, however, is set

23
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
by an expression that performs some logic directly in EL
itself. Although the complexity of such EL expressions can

13 Billion
be fairly high, its good practice to keep them fairly small.
Note that referencing any bean other than "this" might not
be supported for those attributes that have to be read by
CDI extensions.

Conclusion
JSF 2.3 is moving forward by using existing services from the
Java EE platform and providing glue code where necessary to
Devices Run Java
bridge gaps. In addition to that main theme, an assortment of
features will be introduced that aim to keep JSF up to date and
generally easier to use. The features presented in this article
represent a work in progress and might still change before
the inal release of JSF 2.3. More details about the features ATMs, Smartcards, POS Terminals, Blu-ray Players,
discussed here, as well as about other JSF 2.3 features, can be
Set Top Boxes, Multifunction Printers, PCs, Servers,
found on my blog. </article>
Routers, Switches, Parking Meters, Smart Meters,
Arjan Tijms is a member of the Expert Groups for JSF (JSR 372)
and the Java EE Security API (JSR 375). He is the cocreator of Lottery Systems, Airplane Systems, IoT Gateways,
the popular OmniFaces library for JSF that was a 2015 Dukes Programmable Logic Controllers, Optical Sensors,
Choice Award winner, and he is the main creator of a suite of tests
for the Java EE authentication service provider interface (JASPIC) Wireless M2M Modules, Access Control Systems,
that has been used by several Java EE vendors. [See the article Medical Devices, Building Controls, Automobiles
on JASPIC in this issue. Ed.] Tijms holds a Master of Science
degree in computer science from the University of Leiden in
the Netherlands.

#1 Development Platform
learn more
The authors blog on JSF 2.3 updates
The oicial JSF 2.3 JSR
24
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /

Custom Servlet Authentication


Using JASPIC
A little-known Java EE standard makes it simple to enforce authentication using
STEVE MILLIDGE your preferred resources.

W hen you build web applications using Java EE, you often
need to work with some organization-speciic user
repository for authenticating users and obtaining a users
article, I examine an alternative solution that is tucked away
in Java EE. I expect readers to have a basic working knowledge
of Java EE and its authentication mechanisms.
groups. Typically users are deined in a speciic database, a
strange LDAP coniguration, or some other user-identity store Enter JASPIC
speciic to the project. All Java EE application servers ship with When developers design their own authentication modules,
the capability to integrate with a common set of identity stores. the Java Authentication Service Provider Interface for Con-
For example, GlassFish Server ships with several so-called tainers (JASPIC) provides an elegant solution. JASPIC has
realms: ile, LDAP, JDBC, Oracle Solaris, PAM, and certiicate. been part of Java EE since Java EE 6, but it is not well known
Each realm needs to be manually conigured, and the con- and has a reputation for being diicult to use. The goal of the
iguration is speciic to the application server and outside the JASPIC speciication is to deine, in a standard way, how the
control of your application. If the predeined realms dont authentication process occurs within a Java EE container and
it your needs, you then need to develop an application- the points within that process where custom authentication
speciic module to extend the capabilities using applica- modules for validating security messages, users, and groups
tion serverspeciic APIs. Many developers faced with this can be integrated.
prospect build some custom code in the web application, If you just download the JASPIC speciication and dive right
which integrates with their required identity store and uses in with the aim of building a compliant Server Authentication
application-speciic mechanisms to manage authentication Module (SAM), you will surely become confused and dispir-
and authorization. ited. This is because the speciication is designed to describe
The problem with this approach is that these developer- in depth what an implementer of a Java EE container has to
designed mechanisms for managing authentication are do. It also covers both client and server authentication and
not integrated with the application server, so the standard a large number of security scenarios, most of which are not
Java EE security model does not apply, the power of Java EE relevant to you.
APIs such as isUserInRole and getUserPrincipal cant be In this article, I cut through the confusion and demonstrate
used, and standard Java EE declarative security fails. In this that developing an authentication module that is well inte-
25
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
grated with Java EE and comes packaged in your web applica- before it is returned to the client. The SAM is the key com-
tion is actually, barring some boilerplate code, pretty simple. ponent you need to implement to develop a custom authen-
This is because in the case of custom servlet authentication, tication provider for your web application. A SAM needs to
JASPIC provides a small proile and deines the interaction implement the JASPIC-deined interface ServerAuthModule.
between your module and the servlet containerand this Listing 1 shows the key method deinitions that need to
interaction is fairly simple. In this article, I assume that you be implemented.
are familiar with standard Java, Java Authentication and
Authorization Service (JAAS), and Java EE security concepts Listing 1.
such as principals, subjects, and callback handlers. public Class[] getSupportedMessageTypes();

SAM Concept public void initialize(


JASPIC deines in its message processing model (MPM) how MessagePolicy requestPolicy,
authentication occurs in a container. The MPM deines the MessagePolicy responsePolicy,
speciic processing steps an inbound HTTP request into the CallbackHandler handler, Map options)
servlet container progresses through to be validated and throws AuthException;
secured. At the heart of JASPIC is the concept of a SAM. A
SAM is called at speciic points in the processing of the serv- public AuthStatus validateRequest(
let request, as shown in Figure 1. MessageInfo messageInfo,
As can be seen in Figure 1, the SAMs validateRequest Subject clientSubject,
method is called by the servlet container whenever there is Subject serviceSubject)
an inbound servlet request, prior to the request being passed throws AuthException;
to the servlet for processing.
The SAM is also called after the servlet request is complete public AuthStatus secureResponse(
to enable additional postprocessing of the servlet response MessageInfo messageInfo,
Subject serviceSubject)
Servlet Container throws AuthException;

SAM public void cleanSubject(


MessageInfo messageInfo,
HTTPRequest validateRequest()
Subject subject)
Service() Servlet throws AuthException;

HTTPResponse secureResponse() Ill examine each method in turn. The getSupportedMessage


Types method indicates to the container the types of mes-
sages your module supports. For the example, in the case
Figure 1. JASPIC servlet MPM where youre authenticating servlet calls, you must return
26
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
HttpServletRequest and HttpServletResponse classes in your ing of the servlet response at this point you can, but a simple
implementation, as shown in Listing 2. implementation would be just to return success, as shown
in Listing 4.
Listing 2.
public Class[] getSupportedMessageTypes() { Listing 4.
return new Class[] { public AuthStatus secureResponse(
HttpServletRequest.class, MessageInfo messageInfo,
HttpServletResponse.class}; Subject serviceSubject)
} throws AuthException {
return SEND_SUCCESS;
The initialize method of your SAM should conigure the }
SAM based on the properties passed in. The options map
could contain ServletContext initializer parameters, and Another method that is not really needed for developing a
these could be used to initialize your SAM with the proper- servlet authenticator but is part of the interface of the SAM is
ties required to access a database, an LDAP server, or any cleanSubject. This method can be implemented as a no-op,
custom properties you need to set up your SAM. However, the as shown in Listing 5.
key thing to do in this method is to store a reference to the
passed-in CallbackHandler, because you will need it in your Listing 5.
validateRequest implementation to pass the user and group public void cleanSubject(
principals to the servlet container. A simple implementation MessageInfo messageInfo,
of initialize looks like Listing 3. Subject subject)
throws AuthException {
Listing 3. }
public void initialize(
MessagePolicy requestPolicy, Implementing validateRequest()
MessagePolicy responsePolicy, As you can see from the previous listings, the majority of
CallbackHandler handler, the methods you need to implement for your SAM can be
Map options) fairly straightforward. The inal method to be implemented,
throws AuthException { validateRequest, is the heart of your authentication provider.
this.handler = handler; The implementation of this method needs to perform several
} key tasks.
Retrieve the servlet request and servlet response from the

The secureResponse method is called after the servlet request MessageInfo object and retrieve whatever information you
has been processed. In the case of a simple SAM for use need to use to authenticate a user.
with servlets, this method doesnt really need to contain Connect to your identity store and authenticate the user and

any speciic processing. If you need to do any postprocess- retrieve the groups associated with the user.
27
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
Use the stored callback handler to pass these user and (Principal)null)
group principals to the servlet container. };
Finally, return success to the servlet container to allow the }
request to proceed to the servlet.
In Listing 6, which shows the body of my validateRequest try {
method, I retrieve the username and the users groups handler.handle(callbackArray);
directly from the servlet request parameters and use these } catch (Exception ex) {
to set up the user and group principals. Obviously this is AuthException ae =
not very secure, but it illustrates the skeleton of what needs new AuthException(ex.getMessage());
to be done. ae.initCause(ex);
}
Listing 6. return SUCCESS;
HttpServletRequest request =
(HttpServletRequest) Some key points to note about this implementation are
messageInfo.getRequestMessage(); that if you decide that the authentication is successful, the
String user = request.getParameter("user"); resulting Principals need to be passed to the container. To
String groups[] = pass Principals to the servlet container, you need to create
request.getParameterValues("group"); instances of speciic callbacks that are deined by JASPIC.
The irst is a CallerPrincipalCallback, which should be
Callback callbackArray [] = null; initialized with the clientSubject passed into your validate
if (user != null && groups != null ) { RequestMethod and a String representing your username or a
// callback used to set the user Principal custom Principal object.
Callback userCallback = The second callback is a GroupPrincipalCallback, which
new CallerPrincipalCallback( also should be initialized with the clientSubject and with
clientSubject, user); an array of Strings representing the names of the groups the
Callback groupsCallback = user belongs to or an array of custom Principals. These call-
new GroupPrincipalCallback( back handlers are then passed to the handle method of the
clientSubject,groups); handler you stored in your initialize method earlier so that
callbackArray = new Callback[] { the servlet container can initialize the Java EE caller principal
userCallback, and set up the Java EE roles.
groupsCallback}; If the authentication is not successful, you need to create a
} CallerPrincipalCallback initialized with the clientSubject
else { and a null Principal, and then pass these to the handler. This
callbackArray = new Callback[] { has the efect of letting the request proceed but with no user
new CallerPrincipalCallback( associated. Authorization security checks in the container
clientSubject, will then deny access.
28
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
Therefore, you always return SUCCESS from your validate AuthConfigFactory
Request method. FAILURE should be used as a return value .getFactory()
only if there was some problem with your SAMfor example, .removeRegistration(
if you were unable to contact some external resource such as registrationid);
an LDAP server. }
}
Registering Your SAM
To deploy your custom SAM with your application, you pack- There are some additional boilerplate classes required to inte-
age the implementation classes into the WAR ile, as you grate your SAM into the JASPIC infrastructure. These classes
would for any other application classes. The JASPIC specii- are implementations of three interfaces, and they are rarely
cation deines how to register and unregister a custom SAM; diferent than the versions in the zip ile available in the Java
this can be done in a WebListener, which is called when your Magazine download area. Typically, if youre using a single
web application starts. Listing 7 shows how to register and SAM, youll use the following iles without modiication:
unregister the SAM in a WebListener. AuthConfigProvider is a factory for creating ServerAuth

Config objects.
Listing 7. ServerAuthConfig is an object that describes a conigu-

@WebListener ration for a speciic application context and message


public class SimpleSAMWebListener implements layerwhich, in the case of my servlet application, is
ServletContextListener { always the same. ServerAuthConfig is also a factory for
private String registrationid; ServerAuthContext objects.
ServerAuthContext is a class that wraps the SAM, because

public void contextInitialized( in the general case there can be multiple SAMs, but in most
ServletContextEvent sce) { casesand in my examplethere is only one. If there are
String appContext = multiple SAMs, the ServerAuthContext implementation
registrationid = should call each in turn and then adjudicate the results.
AuthConfigFactory.getFactory() The implementation included in this article will work as
.registerConfigProvider( expected unless there are more-complex initialization and
new SimpleSAMAuthConfigProvider( coniguration requirements or there are multiple SAMs that
null,null), need to be invoked.
"HttpServlet",
appContext, Testing the Example SAM
"Simple SAM"); In my example SAM, I implemented validateRequest so
} that the user and groups were obtained from the servlet
request parameters.
public void contextDestroyed( To test the SAM, I need to deine a servlet with a security
ServletContextEvent sce) { constraint, as shown in Listing 8.
29
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /

Figure 3. Successful test result showing user data

up the admin role and the caller principal from the servlet
request parameters.
For this to work in your application server, you will need to
conigure role mapping in your web application for the logi-
cal role admin that is declared on your servlet to be mapped
Figure 2. Testing error message
to a server group admin. This is typically done in the appli-
cation serverspeciic deployment descriptor. In the case of
Listing 8. GlassFish, the server can be conigured to map roles auto-
@WebServlet(name = "SecureServlet", matically to the group with the same name.
urlPatterns = {"/SecureServlet"})
@DeclareRoles("admin") Conclusion
@ServletSecurity(@HttpConstraint( I encourage you to use JASPIC to build your own custom web
rolesAllowed = "admin")) application authentication modules. It is not too diicult once
public class SecureServlet extends HttpServlet { you get started and you realize that the core of the imple-
... mentation is purely in your validateRequest method of your
custom SAM. The additional support classes can be used
For this example, I implemented the servlet so that it just directly from my example project to support your SAM and
prints the caller principal: are suicient for the majority of cases. Once you have built a
SAM, you can take full advantage of the power of the stan-
out.println("User Principal is " + dard Java EE declarative security mechanisms for securing
request.getUserPrincipal().getName()); your application. </article>

If I access the servlet directly without any request parame- Steve Millidge (@l33tj4v4) is the founder and director of Payara
ters, I receive the forbidden access response from the con- Services and C2B2 Consulting. He has used Java extensively
tainer, because my SAM cannot ind the user or groups (see since version 1.0 and is a member of the Expert Groups for
Figure 2). JSR 107 (Java caching), JSR 286 (portlets), and JSR 347 (data
If I use the URLincluding a user and group admin, as in grids). He founded the London Java EE User Group and is an ardent
http://127.0.0.1:8080//jaspic-sam-example/Secure Java EE advocate. Millidge has spoken at several conferences.
Servlet?user=steve&group=adminI get the authenticated
response from the servlet (see Figure 3) because the SAM sets
30
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /

Using the Java APIs for


JSON Processing
Two easy-to-use APIs greatly simplify handling JSON data.
DAVID DELABASSE

J avaScript Object Notation (JSON) enables lightweight


data interchange. It is often used in lieu of XML, but
clearly both options have their beneits and drawbacks.
The JSON-P Object Model API
The JSON-P object model API is based on an in-memory, tree-
like structure that represents the JSON data structure in a way
XML is powerful, but its power comes at the price of com- that can be queried easily. The API also enables navigation
plexity. On the other hand, JSON is somewhat more limited through this JSON tree structure. Note that this API delivers
than XML but this leads to one of the main beneits of JSON: ease of use, but it consumes more memory and is not as ei-
its simplicity. This simplicity probably explains why today, cient as the lower-level streaming API, which I discuss later
JSON is unarguably the most common data interchange in this article.
format on the internet. JSON is often associated with REST The object model API supports the diferent JSON data types
services, but traditional enterprise applications are more via the following classes: JsonObject, JsonArray, JsonString,
and more using JSON, too, so the introduction of JSON in the and JsonNumber. In addition, the class JsonValue deines a few
latest version of Java EEJava EE 7was a welcome addition constants to represent speciic JSON values (true, false, and
to the platform. null). JsonValue is also the common supertype of JsonObject,
JSON support is delivered through the new Java API for JSON JsonArray, JsonString, and JsonNumber.
Processing (JSON-P), which was standardized in JSR 353. This The object model API resides in the javax.json package
speciication deines a simple API to processthat is, parse, and works with two principal interfaces: JsonObject and
generate, transform, and queryJSON documents. Note that JsonArray. JsonObject provides a Map view for accessing the
binding (that is, marshaling of Java objects to JSON docu- unordered collection of zero or more key-value pairs repre-
ments and vice versa) will be addressed in a related API, the senting the model. JsonArray provides a List view for access-
Java API for JSON Binding (JSON-B), which is currently being ing the ordered sequence of zero or more values of the model.
deined in JSR 367. Using the JsonReader.readObject method, you can create
JSON-P ofers not one but two APIs: a high-level object instances of either type from an input source. You can also
model API that is similar to the XML Document Object Model build JsonObject and JsonArray instances using a luent API,
(DOM) API and a lower-level streaming API that is similar as I explain next.
to the Streaming API for XML (StAX). This article provides a To create a model that represents a JSON object or a JSON
brief introduction to both these APIs. array, the object model API relies on a simple builder pattern.
31
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
You just need to use static methods // 1) get a JSON object builder
from the Json class (Json.create The JSON-P JsonObject country = Json.createObjectBuilder()
ObjectBuilder or Json.create object model
ArrayBuilder method) to get a builder // 2) add the different key/values pairs
object. You then chain multiple add
API provides .add("country", "Belgium")
method invocations on the builder only getter . . .
object to add the necessary key-value methods and no .add("population", 11200000)
pairs. Finally, the build method is // note that JSON objects can be nested
invoked to actually return the gener-
setter methods. .add("officialLanguages", Json.createArrayBuilder()
ated JSON object or JSON array. .add(Json.createObjectBuilder()
JSON-P 1.0 can be used from .add("language", "Flemish"))
Java EE 7 (just use any Java EE 7compatible application .add(Json.createObjectBuilder()
server) or from Java SE. To do that in Maven, just make sure .add("language", "French"))
you add the following two dependencies in your project object .add(Json.createObjectBuilder()
model (POM) ile. .add("language", "German")))

<dependency> // 3) return the generated JSON object


<groupId>javax.json</groupId> .build();
<artifactId>javax.json-api</artifactId>
<version>1.0</version> [For the sake of brevity and clarity, the code snippets omit
</dependency> unrelated but important aspects such as proper error
handling, imports, proper resources management, and
<dependency> so forth. Ed.]
<groupId>org.glassfish</groupId> The JSON-P object model API provides a variety of get-
<artifactId>javax.json</artifactId> ter methods for performing queries on JSON objects (or JSON
<version>1.0.4</version> arrays). Note that the API is immutable and thread-safe. This
</dependency> explains why the API provides only getter methods and no
setter methods.
The irst javax.json-api dependency is needed to compile The irst parameter passed to a getter is the key of the
to code. The second dependency is referencing the JSON-P key-value pair to look up. Optionally, you can pass a second
reference implementation, which is necessary to run JSON-P parameter to specify a default value in case that key cannot
compiled code. be found.
The following example illustrates how to create a JSON
representation of a country using the JSON-P object models // looking up the country name value
builder API. This example also shows how to handle a very String capital =
common use case, nesting JSON objects. country.getString("country ", "Unknown!");
32
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
Here is an example that uses JsonReader to create a JSON common supertype JsonValue and is illustrated in the fol-
object from a ile, multiple JSON-P getters to query it, and the lowing example. This example shows a simple recursive
Java 8 Stream API to join the results. method, navigate, that navigates through the tree structure
to display each of its elements. For each tree element, this
JsonReader jsonReader = method invokes the getValueType method to get the actual
Json.createReader(new FileReader("data.json")); type of the element (for example, a JSON string) so it can
JsonObject country = jsonReader.readObject(); then act accordingly (such as invoking the appropriate getter
getString method).
System.out.println("Country: " +
country.getString("country", "empty!")); public static void navigate (
JsonValue tree, String key) {
int population = country.getInt("population", 0); if (key != null)
if (population > 0 ) System.out.print(key + ": ");
System.out.println("Population: " + population);
switch(tree.getValueType()) {
JsonArray langs = case OBJECT:
country.getJsonArray("officialLanguages"); JsonObject object = (JsonObject) tree;
for (String name : object.keySet())
String offLangs = navigate (object.get(name), name);
langs.getValuesAs(JsonObject.class) break;
.stream() case ARRAY:
.map(lang -> lang.getString("language","")) System.out.println(" (JSON array)");
.collect(Collectors.joining(", ")); JsonArray array = (JsonArray) tree;
for (JsonValue val : array)
System.out.println( navigate (val, null);
"Official languages: " + offLangs); break;
case STRING:
Using the sample JSON data, this code will produce the JsonString str = (JsonString) tree;
following output: System.out.println(str.getString());
break;
Country: Belgium default:
Population: 11200000 // for brevity, let's ignore NUMBER,
Official languages: Flemish, French, German // BOOLEAN and NULL
break;
Using the object model API, you can also navigate through }
the in-memory object tree. The navigation is based on the }
33
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
To use this example, just invoke the method and pass it a The pull parser can gen-
JSON object: erate any of the following JSON-P obviously is not
self-explanatory events: the first Java-based
navigate (country, null); START_OBJECT, END_OBJECT,
START_ARRAY, END_ARRAY,
JSON-related API, but it
The object model API also permits, via the JsonWriter class, KEY_NAME, VALUE_STRING, is the first one that has been
outputting a JSON object (or array) to a stream. You irst use VALUE_NUMBER, VALUE_ standardized through the
the Json.createWriter method to specify the output stream TRUE, VALUE_FALSE, and
to use. The JsonWriter.writeObject method then writes the VALUE_NULL. The application
Java Community Process.
JSON object to that stream. Finally, you need to close the logic should leverage these
output stream either by calling the JsonWriter.close method diferent events to advance
or via the AutoCloseable try-with-resources approach, as the parser to the necessary position within the JSON docu-
illustrated in the example below. ment to obtain the required data.
First, create a pull parser using the Json.createParser
StringWriter strWriter = new StringWriter(); method from either an InputStream or a Reader. The applica-
try (JsonWriter jsonWriter = tion will then keep advancing the parser forward by calling
Json.createWriter(strWriter)) { the hasNext method (Has the parser reached the end yet?) and
jsonWriter.writeObject(country); next method on the parser. Keep in mind that the parser can
} be moved in only one direction: forward.
The following example uses a free online service that
The JSON-P Streaming API exposes country-related information in JSON. The code is
The second JSON-P API is a lower-level streaming API that simply creating a streaming parser from an inputStream
is conceptually similar to StAX. This streaming API provides using the Json.createParser method. The application then
forward-only, read-only access to JSON data in a streaming keeps advancing the parser to go over each country. In this
way. It is particularly well suited for reading, in an eicient case, the parsing logic is looking at only two keys: name and
manner, large JSON payloads. The streaming API also allows capital. For each country, the application looks at the "name"
you to write JSON data to output in a streaming fashion. value; if it is not "France", the application keeps advanc-
This API resides in the javax.json.stream package. The ing the parser. Once "France" is found, the application
JsonParser interface is at the core of this streaming API. It looks only at the "capital" key. Because the current parser
provides forward-only, read-only access to JSON data using state is Event.KEY_NAME (that is, the parser is on Frances
a pull-parsing programming model. In this pull model, capital key), the application advances the parser one step
the application controls the parser by repeatedly calling (Event.VALUE_STRING) and gets the actual value of the capital
JsonParser methods to advance the parser. Based on that, the using the getString method on the parser. Once this is done,
parser state will change, and parser events will be generated it is useless to continue parsing the rest of the JSON stream,
to relect this. so the application exits the loop.

34
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
//1. Create a streaming parser from an InputStream // no need to parse the rest of doc
URL url = new URL("http://restcountries.eu/rest/v1/all"); foundCapital = true;
try (InputStream is = url.openStream(); }
JsonParser parser = Json.createParser(is)) { break;

boolean foundCapital = false; }


boolean foundCountry = false; }
}
//2. Keep advancing the parser }
//until it finds the 'France' capital
This example has very simple parsing logic. And depending
while (parser.hasNext() && !foundCapital) { on the parsing logic requirements, this streaming approach
might require you to do a bit more work, but it is clearly more
Event e = parser.next(); eicient than the higher-level object modelbased approach.
if (e == Event.KEY_NAME) { Similarly, you can also generate a JSON document in a
streaming fashion as illustrated in the example below.
switch (parser.getString()) {
FileWriter writer = new FileWriter("canada.json");
// is the parser on a pair JsonGenerator gen = Json.createGenerator(writer);
// whose key is 'name' and gen.writeStartObject()
// value is 'France'? .write("country", "Canada")
case "name": .write("capital", "Ottawa")
parser.next(); .write("poulation", 36048521)
String country = parser.getString(); .writeStartArray("officialLanguages")
if (country.equals("France")) { .writeStartObject()
foundCountry = true; .write("language", "English")
} .writeEnd()
break; .writeStartObject()
.write("language", "French")
case "capital": .writeEnd()
if (foundCountry) { .writeEnd()
// parser is on the 'France' key/value .writeEnd();
// just advance the parser one step gen.close();
parser.next();
// and get the actual value! A JsonGenerator is used to write JSON to a byte stream (or
String capital = parser.getString(); to a Writer). To obtain a generator, call one of the javax
35
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
.json.Json.createGenerator static methods. Once you
have a JsonGenerator instance, you can invoke the diferent
writeStartObject, writeArrayObject, and write methods to
construct the representation of the desired JSON object.
When you call the writeStartObject and writeArrayObject
methods, it is important to call the corresponding closing
method, writeEnd. Finally, you need to invoke the close
method on the generator to properly close resources.

Conclusion
JSON-P provides a simple object model API to parse, gener-
ate, and query JSON documents. It also ofers an eicient,
lower-level API to parse and generate large JSON payloads in a
streaming way.
JSON-P is obviously not the irst Java-based JSON-related
API, but it is the irst one that has been standardized through
the Java Community Process. And given that JSON-P is now
part of Java EE, you can be sure that this API will be available
regardless of the Java EE 7 application server you are using. In
addition, JSON-P has no dependency on Java EE, so it can also
be used in regular Java SE applications. </article>

David Delabasse (@delabassee) is a Java veteran and also a


regular speaker on the Java conferences circuit. He is currently
working at Oracle, where he focuses on server-side Java.

learn more
Introducing JSON
JSON object model Javadoc
JSON Stream API Javadoc
36
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//from the vault /

Using JavaMail in Java EE


Create a web application that can send emails.

T. LAMINE BA
I n this article, I explain how to build a simple web application
that uses the core JavaMail API to send email. The applica-
tion includes three web pages: a front page, a sent e-mail
not plain text, including Multipurpose Internet Mail Exten-
sions (MIME), URLs, and ile attachments.

conirmation page, and a failed e-mail notiication page. Required Software


The front page of the web application (see Figure 1) contains For the purposes of this tutorial, I used the following soft-
the following web components: input ields for the email ware: Microsoft Windows (I used Windows 7), the JDK for Java
address of the sender and recipient, ields for the subject EE 6 or higher, an IDE (I used NetBeans 7), and a web server
and body, and several ields related to the SMTP server (IP
address, username, password, and port number). It also con-
tains the crucial send button.
The conirmation page (see Figure 2) and the similar noti-
ication page for a successful send need only a button that
redirects the user back to the front page.

The JavaMail API


The JavaMail API is a package that provides general email
facilities, such as reading, composing, and sending electronic
messages. JavaMail, which is a platform-independent and
protocol-independent framework, is included in Java EE.
As shown in Figure 3, JavaMail has an application-level Figure 1. The main page of the email app
interface used by the application components to send and
receive email. There is also a service provider (SP) inter-
face that speaks protocol-speciic languages. For instance,
SMTP is used to send emails. Post Oice Protocol 3 (POP3) is
the standard for receiving emails. Internet Message Access
Protocol (IMAP) is an alternative to POP3.
In addition, the JavaMail API contains the JavaBeans
Activation Framework (JAF) to handle email content that is Figure 2. The confirmation page
37
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//from the vault /
Perform validation on a components value.
POP3 SMTP IMAP Handle value-change events.

mail store Server mail store


Accordingly, in a backing bean called emailJSFManagedBean,
JavaMail we create the getter and setter methods necessary for each
of the eight web components listed at the beginning of this
POP3 SMTP IMAP article. If the recipients email address is a variable of type
SP SP SP String called to, Listing 1 shows how the getter and setter
methods would be deined.
JavaMail API JAF
Listing 1.
Java Application package useJavaMail;
/*** Import all necessary libraries ***/

Figure 3. Design of the JavaMail API @ManagedBean


@RequestScoped
such as GlassFish or Apache Tomcat. public class emailJSFManagedBean {
private String to;
Methodology /** Create a new instance of emailJSFManagedBean */
The tutorial uses JavaServer Faces (JSF) technology to build public emailJSFManagedBean() {
the web application. Accordingly, the following worklow to = null;
is proposed: }
1. Create a backing bean.
2. Create web pages using component tags. public String getTo() {
3. Map the FacesServlet instance. return to;
}
Step 1: Create a Backing Bean
A backing bean is a type of managed bean speciic to the public void setTo(String to) {
JSF technology. It holds the logic of the web application and this.to = to;
interacts with the web components contained in the web }
pages. The backing bean can contain private attributes that }
correspond to each web component, getter and setter meth-
ods referring to the attributes, and methods to handle the In this code, @ManagedBean is a declaration that registers the
following four tasks: backing bean as a resource with the JSF implementation. In
Perform processing associated with navigation from one addition, @RequestScoped is the annotation that identiies the
web page to another. managed bean as a resource that exists only in the scope of
Handle action events. the request. In other words, the bean exists for the duration
38
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//from the vault /
of a single HTTP request for the users interaction with the The identiier UIComponent toValidate of the web compo-
web application. nent that is invoking the method, which, in this case, is a
We also create two speciic methods within the backing bean. text input ield (see Listing 1) method, takes user input as an
The irst methods function is to validate all emails submit- argument, as illustrated in Figure 1.
ted by the user in the web application (see Listing 2). The variable value, which contains the email address that

needs to be validated.
Listing 2. Accordingly, the code shown in Listing 2 accomplishes the fol-
public void validateEmail(FacesContext context, lowing tasks:
UIComponent toValidate, Object value) { It gets the local value of the web component.

It checks whether the value is null or empty.

String message = ""; If the value is null or empty, the method sets the compo-

String email = (String) value; nents valid property to false and sets the error message
to E-mail address is required.
if(email == null || email.equals("")) { Otherwise, the method checks whether the @ character and

((UIInput)toValidate).setValid(false); the period (.) character are contained in the value.


message = "E-mail address is required"; If they arent, the method sets the components valid

property to false and sets the error message to E-mail


context.addMessage( address is invalid.
toValidate.getClientId(context), Then, the error message is sent to the FacesContext instance,
new FacesMessage(message)); which associates it with the invoking web component.
} The second method handles the logic for sending an email
else if (!(email.contains("@") && with JavaMail. This navigation handling method is trig-
email.contains("."))) { gered by the action of clicking the SEND E-MAIL button (see
((UIInput)toValidate).setValid(false); Listing 3).
message = "E-mail address is invalid";
context.addMessage( Listing 3.
toValidate.getClientId(context), public String submitEmail() {
new FacesMessage(message)); // create e-mail and send
} /*** Initialize variables ***/
} props = new Properties();
// fill props w/ session and message data
Note that the validation email method takes three session = Session.getDefaultInstance(
arguments: props, null);
The context of the JSF implementation, in order to pass message = new MimeMessage(session);
error messages from the managed bean to the user try {
interface. message.setContent(this.getDescr(),
39
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//from the vault /
"text/plain"); method returns g_response (for good response), which
message.setSubject(this.getSubject()); displays the page g_response.xhtml in the browser (see
fromAddress = Figure 2). If the email transmission fails, b_response (for bad
new InternetAddress(this.getFrom()); response) is returned and the browser displays the page
message.setFrom(fromAddress); b_response.xhtml.
toAddress = To send an email using JavaMail, we irst initiate an
new InternetAddress(this.getTo()); email session instance with the Session class. The email
message.setRecipient(RecipientType.TO, session is the starting point for JavaMail. It uses the
toAddress); java.util.Properties class to get information, such as the
email server, the username, and the password, which can
// Transport message be shared across the rest of the application. In this case, we
message.saveChanges(); //send implies save create a default instance of the Session class:
Transport transport =
session.getTransport("smtp"); session =
transport.connect(this.smtp, this.port, Session.getDefaultInstance(props, null);
this.username,
this.password); Second, through the session, we produce the email using
if(transport.isConnected() == false) the Message class. However, considering that Message is an
return "b_response"; abstract class, we choose instead its subclass MimeMessage,
transport.sendMessage( which allows us to create messages that understand MIME
message, message.getAllRecipients()); types and headers, as deined in the diferent standards-
transport.close(); deining RFCs. The message is constructed with the session
} as an argument:
catch (MessagingException me) {
// handle catch MimeMessage message =
return "b_response"; new MimeMessage(session)
}
Then, we send the email by manipulating an object of type
return "g_response"; Transport. The message is sent via the transport protocol
} SMTP. The transmission is handled by the Transport class
and an object is instantiated as follows:
This type of method is known as an action method. It is
a public method that takes no argument and returns a Transport transport =
string that corresponds to the page that the web applica- session.getTransport("smtp");
tion will navigate to. In this case, the method produces and
sends an email. If the email transmission is successful, the Then, the transport object attempts to connect to the SMTP
40
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//from the vault /
server using the suggested credentials (the SMTP server However, contrary to the inputText tag, the inputSecret does
address, the port number that accepts SMTP connections, not display the value entered by the user. This tag is used to
the username, and the password) to pass authentication on record the SMTP server password.
the server. The inputTextArea is equivalent to the textarea tag in
HTML. It is used to record the body of the email we intend
transport.connect(this.smtp, to send.
this.port, this.username, User input is validated by the application either by using
this.password); the standard validators or by invoking a validating method
implemented in the backing bean (see Listing 2).
If the connection is accepted by the SMTP server, the email is For example, using Facelets, we invoke the validating
sent via the send command. method emailJSFManagedBean.validateEmail for the FROM
Finally, we close the transportation service by invoking the address ield using the code shown in Listing 4.
close command:
Listing 4.
transport. sendMessage(message, <h:form>
message.getAllRecipients()); <table>
transport.close(); <tr>
<th style="width:100px"
Note that the ile containing the backing bean should be align="right">FROM:</th>
under the Sources Packages directory of the web application. <td>
<h:inputText id="from" size="100"
Step 2: Create Web Pages Using Component Tags validator=
The diferent web pages of the application take advantage of "#{emailJSFManagedBean.validateEmail}"
the Facelets declaration language to produce tags for various value="#{emailJSFManagedBean.from}" />
web components. <span style="margin-left:10px">
Create the front page. On this page (Figure 1), there are four <h:message style="color:red" for="from"/>
types of tags associated with the web components: inputText, </span>
inputSecret, inputTextArea, and commandButton. The </td>
inputText is equivalent to an input tag of type text in HTML. </tr>
In other words, it is a ield that takes user input. We use this </table>
type of tag to obtain the senders address, the recipients </form>
address, the subject of the email, the SMTP server address,
the SMTP server username, and the port number of the Note that the purpose of the message tag (<h:message/>) is to
SMTP server. display the error message if the email address validation fails.
The inputSecret is equivalent to the input tag of type As another example, Listing 5 shows how we use standard
password in HTML. It is also a ield that takes user input. validators in Facelets for the SUBJECT ield.
41
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//from the vault /
Listing 5. The code creates a button that, when clicked, moves the user
<h:form> to the front page (index.xhtml).
<table>
<tr> Step 3: Map the FacesServlet Instance
<th style="width:100px" align="right">FROM:</th> The inal step consists of mapping the FacesServlet instance
<td> by altering the web deployment descriptor, that is, the web
<h:inputText id="subject" size="100" .xml ile. Listing 6 is a typical example.
validatorMessage="Subject is required"
value="#{emailJSFManagedBean.subject}"> Listing 6.
<f:validateRequired for="subject"/> <servlet>
</h:inputText> <servlet-name>Faces Servlet</servlet-name>
<span style="margin-left:10px"> <servlet-class>
<h:message style="color:red" for="from"/> javax.faces.webapp.FacesServlet</servlet-class>
</span> <load-on-startup>1</load-on-startup>
</td> </servlet>
</tr> <servlet-mapping>
</table> <servlet-name>Faces Servlet</servlet-name>
</form> <url-pattern>/faces/*</url-pattern>
</servlet-mapping>
The validateRequired tag (<f:validateRequired/>) is applied
to the inputText with an id of subject. This invalidates the Note, however, that the mapping is done automatically if you
form when it is submitted and the SUBJECT ield is empty. In are using an IDE such as NetBeans.
this case, an error message is displayed where the message These examples have demonstrated how to use only the
tag (<h:message/>) is located. basic functionality of the JavaMail API. The library, however,
Create the confirmation page and the error notification page. The is much more extensive and covers almost all the needs of a
conirmation page (g_response.xhtml) is called when an email mail agent. While JavaMail was designed for use with Java EE,
has been sent (see Figure 2). On the other hand, the error notii- it can be used with Java SE, which can make for fun projects.
cation page (b_response.xhtml) is called when the email trans-
mission fails. Both pages contain, respectively, only one web [This article, like others in the //from the vault / series, is an
component, which is a Facelets commandButton tag: updated version of an article that appeared in an earlier issue
of Java Magazine. This article irst appeared in the March/
<h:form> April 2012 issue. Ed.] </article>
<h:commandButton id="back"
value="Back" action="index"> T. Lamine Ba is the president of Real Basis and cofounder of the
</h:form> West African Java user group SeneJUG and is one of the early
members of JUG-Africa.
42
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//java 9 /

JShell: Read-Evaluate-Print Loop


for the Java Platform
Testing code snippets will be part of the JDK.
CONSTANTIN DRABO

J Shell, a new read-evaluate-print loop (REPL), will be


introduced in JDK 9. Motivated by Project Kulla (JEP 222),
JShell is intended to provide developers an API and an interac-
System.out.println("My JShell snippet");
My JShell snippet

tive tool that evaluates declarations, statements, and expres- In my examples in this article, the characters in blue indicate
sions of the Java programming language. text entered at the command line into JShell, and the result-
In this article, I present a brief overview of JShell, explain ing output is shown in black monospace font.
its use, and demonstrate its beneits for developers. Like Java code, JShell allows you to declare variables, meth-
ods, and classes:
Overview
JShell is a new tool in JDK 9 that ofers a basic shell for Java that int x, y , sum
uses a command-line interface. It is also the irst oicial REPL | Added variable x of type int
implementation for the Java platform, although this concept | Added variable y of type int
has existed in many languages (for example, Groovy and Lisp) | Added variable sum of type int
and in third-party tools (such as Java REPL and BeanShell).
JShell acts like a UNIX shell: it reads the instructions, eval- x = 10 ; y = 20 ; sum = x + y;
uates them, prints the result of the instructions, and then | Variable x has been assigned the value 10
displays a prompt while waiting for new commands. It is built | Variable y has been assigned the value 20
around several core conceptssnippets, state, wrapping, Variable sum has been assigned the value 30
instruction modiication, forward references, and snippet
dependenciesthat I explain. System.out.println("Sum of " + x + " and " + y +
A snippet corresponds to an instruction that is based on " = " + sum);
Java Language Speciication (JLS) syntax. It represents a Sum of 10 and 20 = 30
single expression, statement, or declaration. What follows is
a simple snippet. When you enter the snippet into JShell, the And now, heres an example of a valid class, which I use
line below is displayed by the REPL: later:
43
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//java 9 /
class Student { The indentation, of course, looks diferent than in Java,
private String name ; because this code was typed at the JShell command line.
private String classRoom ; Note that some normal Java statements are not allowed at
private double grade ; this initial declaration. The only permitted class modiier is
abstract. Packages are not allowed. Even public wont work:
public Student() {
public class University {
} Student student = new Student();
}
public String getName() { | Warning:
return name ; | Modifier 'public' not permitted in top-level
} declarations, ignored
| public class University {
public void setName(String name) { | ^----^
this.name = name ; | Added class University
}
State. Each statement in JShell has a state. The state deines
public String getClassRoom() { the execution status of snippets and of variables. It is deter-
return classRoom ; mined by results of the eval() method of the JShell instance,
} which evaluates code. There are seven status states:
DROPPED: The snippet is inactive.

public void setClassRoom(String classRoom) { NONEXISTENT: The snippet is inactive because it does not

this.classRoom = classRoom ; yet exist.


} OVERWRITTEN: The snippet is inactive because it has been

replaced by a new snippet.


public double getGrade() { RECOVERABLE_DEFINED: The snippet is a declaration

return grade ; snippet with potentially recoverable unresolved references


} or other issues in its body.
RECOVERABLE_NOT_DEFINED: The snippet is a declara-

public void setGrade(double grade) { tion snippet with potentially recoverable unresolved refer-
ences or other issues. (I discuss the diference between this
this.grade = grade ; and the previous state shortly.)
} REJECTED: The snippet is inactive because it failed com-

} pilation upon initial evaluation and it is not capable of


| Added class Student becoming valid with further changes to the JShell state.
VALID: The snippet is valid.
44
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//java 9 /
When a snippet is not declared, it is considered inactive creates an instance of JShell, evaluates a snippet, and
and not part of the state of the JShell instance nor is it vis- provides the status of the instructions.
ible to the compilation of other snippets. At this stage, it is a
NONEXISTENT snippet. import java.util.List;
If the snippet is submitted to the eval() method and import jdk.jshell.*;
there are no errors, it becomes part of the state of the JShell import jdk.jshell.Snippet.Status;
instance and the status is VALID. Querying JShell gives
isDefined == true and isActive == true. public class JShellStatusSample {
In the case where the signature of the snippet is valid but public static void main(String... args) {
the body contains issues or unresolved references, the
status is RECOVERABLE_DEFINED and a JShell query states //Create a JShell instance
isDefined == true and isActive == true. JShell shell = JShell.create();
If the signature of the snippet is wrong and the body also
contains issues or unresolved references, the snippets //Evaluate the Java code
status is RECOVERABLE_NOT_DEFINED and the status is List<SnippetEvent> events =
isDefined == false even though the snippet stays active shell.eval( "int x, y, sum; " +
(isActive == true). "x = 15; y = 23; sum = x + y; " +
A snippet becomes REJECTED when compilation fails, and it "System.out.println(sum)" );
is no longer a valid snippet. This is a inal status and will not for(SnippetEvent event : events) {
change again. At this stage, both isDefined and isActive are //Create a snippet instance
set to false. Snippet snippet = event.snippet();
You can also deactivate and remove a snippet from the //Store the status of the snippet
JShell state with an explicit call to the JShell.drop(jdk Snippet.Status snippetstatus =
.jshell.PersistentSnippet) method. At that point, the snip- shell.status(snippet);
pet status changes to DROPPED. This is also a inal status and if(snippetstatus == Status.VALID) {
will not change in the future. System.out.println("Successful");
Sometimes a snippet type declaration matches another }
one. In this case, the previous snippet is inactive and it is }
replaced by the new one. The status of the old snippet }
becomes OVERWRITTEN and the snippet is no longer visible
to other snippets (isActive == false). OVERWRITTEN is The result of the execution of this code is
also a inal status.
java JShellStatusSample
Using JShell from a Program Successful
OpenJDK ofers APIs to developers access to JShell program- Successful
matically rather than by using the REPL. The following code Successful
45
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//java 9 /
Wrapping unique namespace, modiications can be applied at any time
You are not obliged to declare variables or deine a method without disturbing the overall functioning of the code.
within a class. Classes, variables, methods, expressions, and
statements evolve within a synthetic class (as an artiicial Forward References and Dependencies
block). You can deine them in the top-level context or within Within the body of a class, you can refer to members that will
a class body, as you wish. be deined later. During evaluation of the code, the references
produce errors. But because JShell works sequentially, the
String firstName , lastName ; issue can be resolved by writing the missing member before
| Added variable firstName of type String actually calling the snippets.
| Added variable lastName of type String When a snippet A depends on a second snippet B, any
changes in snippet B are immediately propagated in A. Then,
String concatName(String firstName, if the dependent snippet is updated, the main snippet is also
String lastName) { updated. If the dependent snippet is invalid, the main snippet
return firstName + lastName ; becomes invalid.
}
| Added method concatName(String,String) How to Run JShell
To run JShell, you need to download and install the latest
The following code shows the declaration of variables and a early-access preview build for JDK 9 for your environment.
method in the top-level context. As discussed previously, you Then, set your JAVA_HOME environment variable and run
cannot modify classes at the top level; however, as seen in java -version to verify your installation. The output of the
the following code, you can modify methods within classes. command should show something like the following:

class Person { java version "9-ea"


Java(TM) SE Runtime Environment (build 9-ea+100-2016-
private String firstName ; 01-06-195905.javare.4235.nc)
private String lastName ; Java HotSpot(TM) 64-Bit Server VM
...
public String concatName(String firstName,
String lastName) { To run JShell, type jshell at the command line:
return firstName + lastName;
} [pandaconstantin@localhost ~]$ jshell
| Welcome to JShell -- Version 9-ea
} | Type /help for help
| Added class Person
When the prompt is available, you can get help on several
Because each statement or expression is created in its own useful commands by typing /help at the command line.
46
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//java 9 /
Figure 1 shows the truncated output from that command. firstname = "Wolfgang" ;
If you declare variables and then initialize them, you can | Variable firstname has been assigned the
see them by using the list command, for example: value "Wolfgang"

String firstname; lastname = "Mozart";


| Added variable firstname of type String | Variable lastname has been assigned the
value "Mozart"
String lastname;
| Added variable lastname of type String System.out.println("Hello " +
getStudentFullName(firstname,lastname));
double grade; Hello Wolfgang Mozart
| Added variable grade of type double
The output of the list command shows the following:
String getStudentFullName(String firstname,
String lastname) { 1 : String firstname ;
return firstname + " " + lastname ; } 2 : String lastname ;
| Added method getStudentFullName(String,String) 3 : double grade ;

/list [all|start|history|<name or id>] -- list the source you have typed


/seteditor <executable> -- set the external editor command to use
/edit <name or id> -- edit a source entry referenced by name or id
/drop <name or id> -- delete a source entry referenced by name or id
/save [all|history|start] <file> -- save: <none> - current source;
all - source including overwritten, failed,
and start-up code;
history - editing history;
start - default start-up definitions
/open <file> -- open a file as source input
/vars -- list the declared variables and their values
/methods -- list the declared methods and their signatures
/classes -- list the declared classes
/imports -- list the imported items
/exit -- exit the REPL
/reset -- reset everything in the REPL
/feedback <level> -- feedback information: off, concise, normal, verbose,
default, or ?

Figure 1. Partial list of JShell commands


47
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//java 9 /
4 : String getStudentFullName /edit 6
(String firstname, String lastname) { | Variable lastname has been assigned
return firstname + " " + lastname ; the value "Drabo"
}
5 : firstname = "Wolfgang" ; When I rerun snippet 7, the output is updated accordingly:
6 : lastname = "Mozart" ;
7 : System.out.println("Hello " + /7
getStudentFullName(firstname,lastname)); System.out.println("Hello " +
getStudentFullName(firstname, lastname));
The numbers in the output are the snippet identiiers. They Hello Constantin Drabo
are useful for manipulating a snippet (editing, dropping,
and so on.) You can also list all the variables, methods, and The /save command enables you to save your snippets to a
classes that are in the code. Heres an example of listing all ile, and the /open command enables you to open and run
the variables: the ile:

/vars /save StudentName.jsh


| String firstname = "Wolfgang" /open StudentName.jsh
| String lastname = "Mozart"
| double grade = 0.0 JShell also ofers some keyboard shortcuts. You can obtain the
navigation history by using the up and down arrow keys or
If you decide to change the values of variables or edit a spe- the Enter key. Use the tab key to perform snippet completion,
ciic snippet, you run /edit with the snippet identiier, and interrupt a snippet by using Control-C.
for example:
Conclusion
/edit 5 JShell has many possible uses: for testing code, especially
APIs; for educational purposes; and for doing quick mock-ups
A dialog box appears, which allows you to modify the value. in JavaFX.
After you make the change in the dialog box, you will see Whether it is called from the command line or program-
output that looks like this: matically, JShell is likely to become one of the most widely
used features of JDK 9. </article>
| Variable firstname has been assigned
the value "Constantin" Constantin Drabo is a software engineer living in Burkina Faso.
He is a NetBeans Dream Teamer and a Fedora Ambassador for the
Heres another example: Fedora Project. He is also the founder of FasoJUG, the irst Java
user group in Burkina Faso (the former Upper Volta).
48
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /

Modern Java I/O


NIO.2 makes many things easier, including monitoring directories for changes.

J ava 7 brought in a brand-new I/O APIusually called


NIO.2and it should be considered almost a complete
replacement for the original File approach to I/O. The new
Path source, target;
Attributes attr;
Charset cs = StandardCharsets.UTF_8;
classes are contained in the java.nio.file package.
The new API is considerably easier to use for many use // Creating files
cases. It has two major parts. The irst is a new abstraction //
called Path (which can be thought of as representing a ile // Example of path --> /home/ben/.profile
location, which may or may not have anything actually at that // Example of attributes --> rw-rw-rw-
BENJAMIN EVANS AND location). The second piece is lots of new convenience and Files.createFile(target, attr);
DAVID FLANAGAN utility methods to deal with iles and ilesystems. These are
contained as static methods in the Files class. // Deleting files
For example, when using the new Files functionality, a Files.delete(target);
basic copy operation is now as simple as boolean deleted = Files.deleteIfExists(target);

File inputFile = new File("input.txt"); // Copying/Moving files


try (InputStream in = Files.copy(source, target);
new FileInputStream(inputFile)) { Files.move(source, target);
Files.copy(in, Paths.get("output.txt"));
} catch(IOException ex) { // Utility methods to retrieve information
ex.printStackTrace(); long size = Files.size(target);
}
FileTime fTime =
Lets take a quick survey of some of the major methods Files.getLastModifiedTime(target);
in Filesthe operation of most of them is pretty self- System.out.println(fTime.to(TimeUnit.SECONDS));
explanatory. In many cases, the methods have return types.
We have omitted handling these, as they are rarely useful Map<String, ?> attrs =
except for contrived examples, and for duplicating the behav- Files.readAttributes(target, "*");
ior of the equivalent C code: System.out.println(attrs);
BEN EVANS PHOTOGRAPH BY
JOHN BLYTHE
49
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
// Methods to deal with file types Path
boolean isDir = Files.isDirectory(target); Path is a type that may be used Path is an abstract
boolean isSym = Files.isSymbolicLink(target); to locate a ile in a ilesystem. It concept; it isnt
represents a path that is
// Methods to deal with reading and writing System-dependent
necessarily bound to
List<String> lines = Hierarchical any physical file path, so
Files.readAllLines(target, cs); Composed of a sequence of
you can talk easily about
byte[] b = Files.readAllBytes(target); path elements
Hypothetical (may not exist
the locations of files
BufferedReader br = yet, or may have been deleted) that dont exist yet.
Files.newBufferedReader(target, cs); It is therefore fundamentally
BufferedWriter bwr = diferent from a File. In par-
Files.newBufferedWriter(target, cs); ticular, the system dependency
is manifested by Path being an interface, not a class. This
InputStream is = Files.newInputStream(target); enables diferent ilesystem providers to each implement the
OutputStream os = Files.newOutputStream(target); Path interface and provide for system-speciic features while
retaining the overall abstraction.
Some of the methods on Files provide the opportunity to The elements of a Path consist of an optional root com-
pass optional arguments, to provide additional (possibly ponent, which identiies the ilesystem hierarchy that this
implementation-speciic) behavior for the operation. instance belongs to. Note that, for example, relative Path
Some of the API choices here produce occasionally annoy- instances may not have a root component. In addition to the
ing behavior. For example, by default, a copy operation will root, all Path instances have zero or more directory names
not overwrite an existing ile, so we need to specify this and a name element.
behavior as a copy option: The name element is the element farthest from the root of
the directory hierarchy and represents the name of the ile or
Files.copy(Paths.get("input.txt"), directory. The Path can be thought of consisting of the path
Paths.get("output.txt"), elements joined together by a special separator or delimiter.
StandardCopyOption.REPLACE_EXISTING); Path is an abstract concept; it isnt necessarily bound to any
physical ile path. This allows us to talk easily about the loca-
StandardCopyOption is an enum that implements an interface tions of iles that dont exist yet. Java ships with a Paths class
called CopyOption. This is also implemented by LinkOption. that provides factory methods for creating Path instances.
So Files.copy() can take any number of either LinkOption or Paths provides two get() methods for creating Path objects.
StandardCopyOption arguments. LinkOption is used to specify The usual version takes a String and uses the default ilesys-
how symbolic links should be handled (provided the underly- tem provider. The URI version takes advantage of the ability
ing operating system supports symlinks, of course). of NIO.2 to plug in additional providers of bespoke ilesys-
tems. This is an advanced usage, and interested developers
50
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
should consult the primary documentation: Were making use of the StandardOpenOption enum, which
provides similar capabilities to the copy options but for open-
Path p = Paths.get("/Users/ben/cluster.txt"); ing a new ile instead.
Path p = In the next example, we manipulate a JAR ile as a
Paths.get(new URI( FileSystem in its own right, modifying it to add an additional
"file:///Users/ben/cluster.txt")); ile directly into the JAR. JAR iles are just ZIP iles, so this
System.out.println(p2.equals(p)); technique will also work for .zip archives:

File f = p.toFile(); Path tempJar = Paths.get("sample.jar");


System.out.println(f.isDirectory()); try (FileSystem workingFS =
Path p3 = f.toPath(); FileSystems.newFileSystem(tempJar, null)) {
System.out.println(p3.equals(p)); Path pathForFile =
workingFS.getPath("/hello.txt");
This example also shows the easy interoperation between List<String> ls = new ArrayList<>();
Path and File objects. The addition of a toFile() method ls.add("Hello World!");
to Path and a toPath() method to File allows the developer
to move efortlessly between the two APIs and allows for a Files.write(pathForFile, ls,
straightforward approach to refactoring the internals of code Charset.defaultCharset(),
based on File to use Path instead. StandardOpenOption.WRITE,
We can also make use of some useful bridge methods StandardOpenOption.CREATE);
that the Files class also provides. These provide conve- }
nient access to the older I/O APIsfor example, by provid-
ing convenience methods to open Writer objects to speciied This shows how we use a FileSystem to make the Path objects
Path locations: inside it, via the getPath method. This enables the developer
to efectively treat FileSystem objects as black boxes.
Path logFile = Paths.get("/tmp/app.log"); One of the criticisms of Javas original I/O APIs was the
try (BufferedWriter writer = lack of support for native and high-performance I/O. A solu-
Files.newBufferedWriter( tion was initially added in Java 1.4, the Java New I/O (NIO)
logFile, API, and it has been successively reined in successive
StandardCharsets.UTF_8, Java versions.
StandardOpenOption.WRITE)) {
writer.write("Hello World!"); NIO Channels and Bufers
// ... NIO bufers are a low-level abstraction for high-performance
} catch (IOException e) { I/O. They provide a container for a linear sequence of elements
// ... of a speciic primitive type. Well work with the ByteBuffer
} (the most common case) in our examples.
51
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
ByteBufer. This is a sequence of bytes, and can conceptu- To get data in or out of a bufer, we have two types of opera-
ally be thought of as a performance-critical alternative to tionsingle value, which reads or writes a single value, and
working with a byte[]. To get the best possible performance, bulk, which takes a byte[] or ByteBuffer and operates on a
ByteBuffer provides support for dealing directly with the (potentially large) number of values as a single operation. It
native capabilities of the platform the JVM is running on. is from the bulk operations that performance gains would
This approach is called the direct bufers case, and it expect to be realized:
bypasses the Java heap wherever possible. Direct bufers are
allocated in native memory, not on the standard Java heap, b.put((byte)42);
and they are not subject to garbage collection in the same way b.putChar('x');
as regular on-heap Java objects. b.putInt(0xcafebabe);
To obtain a direct ByteBuffer, call the allocateDirect()
factory method. An on-heap version, allocate(), is also b.put(data);
provided, but in practice this is not often used. b.put(b2);
A third way to obtain a byte bufer is to wrap an existing
byte[]this will give an on-heap bufer that serves to pro- double d = b.getDouble();
vide a more object-oriented view of the underlying bytes: b.get(data, 0, data.length);

ByteBuffer b = ByteBuffer.allocateDirect(65536); The single value form also supports a form used for absolute
ByteBuffer b2 = ByteBuffer.allocate(4096); positioning within the bufer:

byte[] data = {1, 2, 3}; b.put(0, (byte)9);


ByteBuffer b3 = ByteBuffer.wrap(data);
Bufers are an in-memory abstraction. To afect the outside
Byte bufers are all about low-level access to the bytes. This world (for example, the ile or network), we need to use a
means that developers have to deal with the details manually Channel, from the package java.nio.channels. Channels rep-
including the need to handle the endianness of the bytes resent connections to entities that can support read or write
and the signed nature of Javas integral primitives: operations. Files and sockets are the usual examples of chan-
nels, but we could consider custom implementations used for
b.order(ByteOrder.BIG_ENDIAN); low-latency data processing.
Channels are open when theyre created, and can subse-
int capacity = b.capacity(); quently be closed. Once closed, they cannot be reopened.
int position = b.position(); Channels are usually either readable or writable, but not both.
int limit = b.limit(); The key to understanding channels is that reading from a
int remaining = b.remaining(); channel puts bytes into a bufer, and writing to a channel
boolean more = b.hasRemaining(); takes bytes from a bufer. For example, suppose we have a
large ile that we want to checksum in 16 MB chunks:
52
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
FileInputStream fis = getSomeStream(); byte[] b = new byte[(int)fc.size()];
boolean fileOK = true; mbf.get(b, 0, b.length);
for (int i=0; i<fc.size(); i++) {
try (FileChannel fchan = fis.getChannel()) { b[i] = 0; // Won't be written back to the
ByteBuffer buffy = // file, we're a copy
ByteBuffer.allocateDirect(16 * 1024 * 1024); }
while(fchan.read(buffy) != -1 || mbf.position(0);
buffy.position() > 0 || mbf.put(b); // Zeroes the file
fileOK) { }
fileOK = computeChecksum(buffy);
buffy.compact(); Even with bufers, there are limitations to what can be done
} in Java for large (for example, transferring 10 GB between
} catch (IOException e) { ilesystems) I/O operations that perform synchronously on a
System.out.println("Exception in I/O"); single thread. Before Java 7, these types of operations would
} typically be done by writing custom multithreaded code and
managing a separate thread for performing a background
This will use native I/O as far as possible, and will avoid copy. Lets move on to look at the new asynchronous I/O fea-
a lot of copying of bytes on and of the Java heap. If the tures that were added with JDK 7.
computeChecksum method has been well implemented, then
this could be a very performant implementation. Async I/O
Mapped byte bufers. These are a type of direct byte bufer The key to the new asynchronous functionality is some new
that contain a memory-mapped ile (or a region of one). They subclasses of Channel that can deal with I/O operations that
are created from a FileChannel object, but note that the File need to be handed of to a background thread. The same
object corresponding to the MappedByteBuffer must not be functionality can be applied to large, long-running opera-
used after the memory-mapped operations, or an exception tions, and to several other use cases.
will be thrown. To mitigate this, we again use try-with- In this section, well deal exclusively with Asynchronous
resources, to scope the objects tightly: FileChannel for ile I/O, but there are a couple of other
asynchronous channels. There are two diferent ways to
try (RandomAccessFile raf = interact with an asynchronous channelFuture style, and
new RandomAccessFile( callback style.
new File("input.txt"), "rw"); Future-based style. The Future interface is beyond the scope
FileChannel fc = raf.getChannel();) { of this article, but it can be thought of as an ongoing task that
may or may not have completed yet. It has two key methods:
MappedByteBuffer mbf = isDone(), which returns a Boolean indicating whether the
fc.map(FileChannel.MapMode.READ_WRITE, 0, task has inished, and get(), which returns the result. If the
fc.size()); task is inished, it returns immediately. If not inished, it
53
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
blocks until done. public void failed(Throwable x, Object o) {
Here is an example of a program that reads a large ile System.out.println(
(possibly as large as 100 MB) asynchronously: "Async write failed: "+ x.getMessage());
}
try (AsynchronousFileChannel channel = };
AsynchronousFileChannel.open(
Paths.get("input.txt"))) { try (AsynchronousFileChannel channel =
ByteBuffer buffer = AsynchronousFileChannel.open(
ByteBuffer.allocateDirect(1024 * 1024 * 100); Paths.get("primes.txt"),
Future<Integer> result = channel.read(buffer, 0); StandardOpenOption.CREATE,
StandardOpenOption.WRITE)) {
while(!result.isDone()) {
// Do some other useful work.... channel.write(buffy, 0, null, h);
} Thread.sleep(1000); // So we don't exit too quickly
}
System.out.println("Bytes read: " + result.get());
} The AsynchronousFileChannel object is associated with a
background thread pool, so that the I/O operation proceeds,
Callback-based style. The callback style for asynchronous I/O while the original thread can get on with other tasks.
is based on a CompletionHandler, which deines two methods, By default, this uses a managed thread pool that is provided
completed() and failed(), that will be called back when the by the runtime. If required, it can be created to use a thread
operation either succeeds or fails. pool that is managed by the application (via an overloaded
This style is useful if you want immediate notiication of form of AsynchronousFileChannel.open()), but this is not
events in asynchronous I/Ofor example, if there are a large often necessary.
number of I/O operations in light, but failure of any single Finally, for completeness, lets touch upon NIOs support
operation is not necessarily fatal: for multiplexed I/O. This enables a single thread to manage
multiple channels and to examine those channels to see
byte[] data = {2, 3, 5, 7, 11, 13, 17, 19, 23}; which are ready for reading or writing. The classes to sup-
ByteBuffer buffy = ByteBuffer.wrap(data); port this are in the java.nio.channels package and include
SelectableChannel and Selector.
CompletionHandler<Integer,Object> h = These nonblocking multiplexed techniques can be
new CompletionHandler() { extremely useful when writing advanced applications that
public void completed(Integer written, Object o) { require high scalability, but a full discussion is outside the
System.out.println("Bytes written: " + written); scope of this article.
}
54
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
Watch Services and Directory Searching Paths.get("/opt/projects"), "*.java")) {
The last class of asynchronous services we will consider for (Path p : stream) {
watch a directory or visit a directory (or a tree). The watch System.out.println(p +": "+ Files.size(p));
services operate by observing everything that happens in a }
directoryfor example, the creation or modiication of iles: }

try { One drawback of this API is that this will only return elements
WatchService watcher = that match according to glob syntax, which is sometimes
FileSystems.getDefault().newWatchService(); insuiciently lexible. We can go further by using the new
Files.find and Files.walk methods to address each element
Path dir = obtained by a recursive walk through the directory:
FileSystems.getDefault().getPath("/home/ben");
WatchKey key = final Pattern isJava = Pattern.compile(".*\\.java$");
dir.register(watcher, final Path homeDir = Paths.get("/Users/ben/projects/");
StandardWatchEventKinds.ENTRY_CREATE, Files.find(homeDir, 255,
StandardWatchEventKinds.ENTRY_MODIFY, (p, attrs) -> isJava.matcher(p.toString()).find())
StandardWatchEventKinds.ENTRY_DELETE); .forEach(
q -> {System.out.println(q.normalize());});
while(!shutdown) {
key = watcher.take(); It is possible to go even further and construct advanced solu-
for (WatchEvent<?> event: key.pollEvents()) { tions based on the FileVisitor interface in java.nio.file,
Object o = event.context(); but that requires the developer to implement all four meth-
if (o instanceof Path) { ods on the interface rather than just using a single lambda
System.out.println("Path altered: "+ o); expression as done here.
} In sum, you can see that the NIO.2 library provides a lot of
} useful functionality and saves you a lot of code. If youre still
key.reset(); working with preJava 7 ile handling, youre doing far more
} work than necessary. </article>
}
This article was adapted with permission from Java in a Nutshell,
By contrast, the directory streams provide a view into all iles by Benjamin Evans and David Flanagan.
currently in a single directory. For example, to list all the Java
source iles and their size in bytes, we can use code like Benjamin Evans is the cofounder of jClarity, a Java Champion and
Rock Star, and a frequent contributor to Java Magazine. David
try(DirectoryStream<Path> stream = Flanagan is a software engineer at Mozilla, best known for his
Files.newDirectoryStream( master work JavaScript: the Definitive Guide (OReilly, 2011).
55
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /

Generics: The Hard Parts


Wildcards, subtyping, and type erasure in generics

MICHAEL KLLING
W elcome back to the discussion of generic types in Java.
In my previous article, I started discussing generics
typeswhy they are useful, what you can do with them, and
deined in Person and redeined appropriately in the sub-
types). All seems well.
The problem becomes apparent when you consider that
how to use them. The introductory part of this topic was quite the printList method could also modify the list. It could, for
straightforward, but at the end of that discussion I mentioned example, include the following line:
a problem: generic collections and subtyping.
In short, I wanted to write a general printList method such list.add(new Faculty());
as this:
Because the static type of the list variable (the formal
private void printList(List<Person> list) parameter to the method) is List<Person>, and Faculty is a
subtype of Person, adding this object causes no type prob-
And I wanted it to print out lists of subtypes of Person, such lems. However, if the actual list passed to the printList
as List<Student> or List<Faculty>. In other words, given that method were a list of students, then I have now added a
Student is a subtype of Person, I wanted to call the method Faculty object to the Student list! This is a clear error and
above like this: should not be allowed to happen.
The only solution is to declare that List<Student> is not a
List<Student> students = getStudentList(); subtype of List<Person>, and to prevent student lists from
printList(students); being passed in to the printList method. Type safety is pre-
served, but I am back to square one: How can I now write my
This does not work in Java. The reason is that List<Student> general printList method?
is not considered a subtype of List<Person> even though
Student is a subtype of Person. Wildcards to the Rescue
The solution to this problem is the use of wildcards. I can
Whats the Problem? write my printList method like this:
So why is List<Student> not a subtype of List<Person>? If
you think only about printing out the list, there seems to be private void printList(List<?> list)
no problem. The printList method could call, for instance,
PHOTOGRAPH BY
JOHN BLYTHE a print method on all the lists elements (which might be Note the question mark in place of the element type of
56
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
the list. The question mark is the wildcard symbol, and it every type is a subtype of Object). So I cannot treat element
denotes a type called unknown. My parameter is now a list of types as Persons.
unknown type. Not knowing much about the element type can still be OK
There is an obvious beneit to this construct. I can now do in some cases. I could still use all list operations that do not
what I intended to do: I can call my printList method with depend on the element type, such as size() and clear(). I
both List<Student> and List<Faculty> as parameters: could also do anything that I can do with the Object type,
such as using the toString method (maybe implicitly by call-
List<Student> students = getStudentList(); ing System.out.println).
List<Faculty> professors = getFacultyList(); But to call type-speciic methods, I need something else.
printList(students); In using the wildcard, I went from saying that my parameter
printList(professors); is exactly a List of Person to saying that it is a List of anything.
Instead, I would like to say that it is a List of any subtype of
Every list type is considered to be a subtype of the list of this Person. I can do this with a bounded wildcard.
unknown type, so this code now works. The trade-of is that I
cannot add to the list when the element type is unknown, so Bounded Wildcards
I avoid the type problem discussed earlier when I tried to add Generic parameters can have bounds, which restrict what
to the list. kind of actual types can be used for them. Consider this next
version of my printList method:
What Is Known About the Unknown Type?
The wildcard is a good step forward, but it does not solve all private void printList(List<? extends Person> list)
my problems. You can see this if you think about what I can
do with my list elements now. What if my Person superclass This deinition now allows lists of Person or subtypes of
had a method printAddressDetails that I want to use as part Person (and only these) as parameters, just as I intended.
of my printList method: Because I am using a wildcard, I am still not allowed to add to
the list, but I know that all elements are of type Person (or its
private void printList(List<?> list) { subtypes). I can now treat elements as Person objects and call
for (Person p: list) { the appropriate methods. This inally solves my problem.
...
p.printAddressDetails(); Other Bounded Types
} Wildcards are not the only place where bounds can be used
} and are useful. Type bounds can also be employed in the dec-
laration of generic types and in methods without wildcards.
This will now not work. The advantage of using the unknown For example, I can deine a generic type PersonList that
type is that you can pass in lists of any type, but you pay by accepts only Person and its subtypes as parameters:
virtue of the fact that you dont know much about that type.
All you know, in fact, is that it is a subtype of Object (because class PersonList<T extends Person>
57
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
This is similar to the deinition of ArrayList that I showed in so no type parameter has previously been declared. To use a
the last issue of Java Magazine, but this time only subtypes of generic type in the parameter list, I need to declare this type
Person can be used to instantiate the type: irstthat is the efect of writing the type <T> in the header.
This code will fail, however, because the less-than operator
PersonList<Student> students = cannot be applied to any unspeciied type T. Instead, I can
new PersonList<Students>(); use the compareTo method, but this works only when T is a
PersonList<Faculty> professors = subtype of Comparable. I can enforce this by changing my
new PersonList<Faculty>(); method as follows:

In return, all methods from the Person type can now be used public <T extends Comparable<T>> void underLimit(
on objects of type T in my implementation of the PersonList List<T> myList, T limit) {
class, because I have a guarantee that any concrete instantia- for (T e : myList) {
tion of T will have these methods. if (e.compareTo(limit) < 0)
System.out.println(e);
Generic Methods }
This is a good time to introduce another generic feature: }
generic methods. In the previous examples, the generic
type parameter was introduced in the class header when Here, I have declared that I only accept types for type T that
we declared a generic class. It is also possible to have single are subtypes of Comparable so that the methods needed are
generic methods, without making the whole class generic. In guaranteed to be available.
that case, the single method can handle generic types. Generic
methods are often combined with bounded generic types. Upper Bounds and Lower Bounds
Consider the following example. Here, I attempt to write a So far, I have discussed bounded types only by showing an
method that prints all elements from a list that are smaller upper bound to establish a supertype (an upper bound) for the
than a given limit: wildcard parameter, for example:

public <T> void underLimit(List<T> myList, T limit) { List<? extends Person>


for (T e : myList) {
if (e < limit) The efect is that only the named type or its subtypes can
System.out.println(e); be used to instantiate the type. In other words, the concrete
} type at the point of use must extend (or implement) Person.
} If we were to draw a typical inheritance hierarchy around
Person, only Person or the classes below it in the hierarchy
The new syntax here is the type parameter <T> in the header can be used.
after the keyword public and before the return type. I am I can also restrict the type in the other direction, by declar-
assuming that this method is in a class that is not generic, ing a lower bound:
58
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
List<? super Person> parameter type in the add method becomes String. For
List<Integer>, each T would be replaced by Integer, and
By using the super keyword for my declaration, I am stating so on.
that the type has to be Person or a supertype of Person. If you This is a useful mental model to start understanding
picture this in an inheritance hierarchy, you can use Person generics, but it is ultimately false. It is useful, because it is
or the types above it in the hierarchy. This is less often used easy to understand, and it gives a good approximation of
than upper bounds but can be helpful in some situations. how generics behave. It is important to know, however, how
things really work, because sometimes that makes a notice-
Implementation able diference.
In addition to knowing how to use generic types, it is also Generic types are never expanded into their concrete
useful to know a little bit about how they are implemented instantiations: not in source code, not in binary code, not on
in the Java compiler and the JVM. If you ever talked with disk, and not in memory. This is diferent than templates in
anyone about the implementation, it is likely that the term C++, for example, where this expansion actually happens. In
type erasure came up at some stage. It is important to know Java, the generated code will just insert Object as the type for
what this means, because it afects not only the eiciency of each unbounded type parameter, or the bounding type for
implementation but also the semantics of your code in cer- types that have bounds. Thus, List<String>, List<Integer>,
tain cases. and List<Person> are all represented by a single class
List<Object> by the time your program executes. By then,
Type Erasure the compiler has made sure that you used the class in a type-
At the core of type erasure is the fact that type parameters safe manner, and type problems have been prevented. You
exist only at compile time; they are completely removed used many types but get only one class.
at runtime. They are a construct exclusively used for type Discarding type parameter information at runtime has
checking during compilation to ensure type safety, but they advantages and disadvantages. One of the advantages is that
are not carried through into the Java bytecode. it saves time and space: the class ile needs to exist only once
To understand generics at irst, it is often helpful to think of for every generic class. It does not need to be stored or com-
generic classes as expanded at instantiation time. For exam- piled multiple times. This is a clear beneit.
ple, consider the following type: On the downside, type erasure makes life harder for tool
writers, such as creators of development environments. It
class List<T> { is hard, for example, for a debugger to igure out the correct
public void add(T elem); type for an object at runtime if that type is derived from a
... generic class. No information is kept in the class ile about
} the full type information.
More important for you as a programmer is the fact that type
If it is then instantiated by using the concrete type erasure can inluence the behavior of your code. The following
List<String>, it can be thought of as having every occur- sections describe examples where it is necessary to understand
rence of T in the source text replaced by String, so that the type erasure to understand the behavior of the Java system.
59
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
No instanceof for Types with Type Parameters have to be aware of this to write correct code. A side efect
The instanceof operator cannot be used with parameterized of this is that it is not possible to declare a static ield of a
types. Consider the following attempt to use List<T> as generic parameter type:
deined in the previous section:
class MyClass<T> {
if (list instanceof List<Person>) { private static T value; // error
List<Person> pl = (List<Person>) list; ...
} }

This code looks entirely reasonable, but if you consult the Because this ield is shared between all variants of the type, it
previous section on type erasure, you will see why it does cannot refer to the type parameter of speciic instantiations.
not work: the runtime system has no idea whether a type
is List<Person>, because it does not keep this information Java Trivia: Arrays and Type Safety
around. (All it knows about is List<Object> but nothing more If you are interested in the details of Java and type safety, you
speciic.) So it cannot perform this check and give you the might like this little bit of Java trivia: the implementation of
answer. You will see an error saying illegal generic type arrays in Java has a hole in its type system. This is one of the
for instanceof. rare cases where Java is not statically type-safe.
The same problem shows up when you use the getClass The problem is the same problem I discussed earlier in
method: this article: If B is a subtype of A, is then List<B> a subtype of
List<A>? For lists, the answer is no. Earlier in this article, I
List<Student> sl = new ArrayList<Student>(); explained why this is and how it could go wrong if we were to
List<Faculty> fl = new ArrayList<Faculty>(); consider List<B> a subtype. However, for arrays (a very simi-
if (sl.getClass() == fl.getClass()) lar situation), Java does consider the list to be a subtype. This
... introduces a potential type problem. Consider the following
code:
At irst glance, you might think that the condition in the if-
statement is false, but because of type erasure, it will actually A[] aa;
evaluate to true. As far as the runtime system is concerned, B[] ba = new B[3];
the class of both objects is ArrayList.
aa = ba; // allowed! B[] is subtype of A[]
Generic Classes and Static Attributes aa[0] = new B();
One of the areas where type erasure becomes most visible aa[1] = new A(); // java.lang.ArrayStoreException: A
in source code is when you use static attributes in generic
classes. Static methods and static ields are shared between The last line in this example represents a type error: I am
all instantiations of a generic class. The reason is again the trying to insert an A object into an array of B. The problem is
same: only one copy of the generic class actually exists. You that the assignment in the third line is allowed. This problem
60
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java / //java proposals of interest /
is picked up only at runtime, not at compile time, breaking
Javas static type safety. When it designed generic classes,
the Java team decided to be more conservative and detect the FEATURED JDK ENHANCEMENT PROPOSAL
equivalent problem at compile time.
JEP 282 jlink: The Java Linker
Conclusion
Generic types are easy to understand in principle and gener- For most readers, the idea of a linker for Java might
ally quite easy to use. However, when you start writing more seem very peculiar indeed. Linker functions, which are
sophisticated codeparticularly if youre writing libraries part of a build tool associated with native languages, are
you might run into a whole range of situations where you need performed by the JVM in its class-loading mechanism.
to understand the advanced constructs in generics. In particular, these functions are executed in the algo-
When you put all of the concepts together, the class and rithms for inding JARs that contain referred-to classes
method deinitions can become quite tricky to read even for and methods and then loading them into the current JVM
experienced programmers. Have a look at the max method of memory space. [For more information on this process,
class Collections in the standard library, for example, or the download a PDF of our article How the JVM Locates,
deinition of methods in the Class class. You will see that it Loads, and Runs Libraries by Oleg elajev. Ed.]
can take some time to get your head around the combination What JEP 282 proposes is not the traditional linker but,
of all the constructs. Do not let this discourage you; these rather, a generic tool that runs where a linker does in the
complex constructs are rare, and with the concepts I have build processafter the compiler but before creation of
discussed here and some practice, you should be able to work the executable. The tool would deine a plugin interface,
out most of it. More importantly, you should be able to write by which a variety of tools could be inserted into the build
correct and lexible code yourself. </article> process. The most obvious of these would be an optimizer,
especially a whole-program optimizer that could iden-
Michael Klling is a Java Champion and a professor at the tify opportunities to improve performance and reduce
University of Kent, England. He has published two Java textbooks code size that are not visible to the compiler on a class
and numerous papers on object orientation and computing educa- basis. Other plugins suggested in the JEP document could
tion topics, and he is the lead developer of BlueJ and Greenfoot, remove debug information, reorder resources so that they
two educational programming environments. Klling is also a can be loaded faster, and even compress generated iles.
Distinguished Educator of the ACM. In theory, many other reinements to generated code
could be performedincluding those from third parties.
Some examples are insertion of instrumentation data,
supplementation of debugging data, conversion of byte-
learn more codes to other formats, intraclass optimization, and so
on. All of this could be done through plugins to the pro-
The Java Tutorial on generic types posed jlink technology.

61
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /

JRuby 9000: Beautiful Language,


Powerful Runtime
A simple language that inspired Ruby on Rails and can greatly facilitate complex Java coding,
CHARLES NUTTER such as JavaFX development, using native libraries

I n May, the JRuby team released JRuby 9.1, the latest


version in the JRuby 9000 line. The team put a lot of hard
work into making JRuby 9000 the best implementation of
99 percent of Ruby features. As much as possible, the JRuby
team has tried to ensure that JRuby remains compatible with
CRuby, all while leveraging the JVMs power.
Ruby available. As a member of the team, I will demonstrate JRubys garbage collector is the JVMs garbage collector,
why you might want to take a look at Ruby on the JVM, spe- and there are a lot of excellent garbage collectors available
ciically using JRuby. for todays JVMs. [For a comparison of several JVM garbage
collectors, see The New Garbage Collectors in OpenJDK by
What Is Ruby? Christine Flood in the March/April issue of this year. Ed.]
Ruby is a dynamically typed, object-oriented language inspired JRubys threads are JVM threads, which means true paral-
by Smalltalk, Perl, and Lisp. It was created in 1995 by Yukihiro lel execution of Ruby code. JRuby compiles Ruby code to JVM
Matz Matsumoto; Ruby 2.3 is the current version. Over the bytecode, which the JIT can then compile to native machine
past 10 years, it has become one of the top 10 languages in use, code. In fact, JRuby was the irst Ruby implementation to
driven in part by the success of the Ruby on Rails web frame- have any native JIT capabilities.
work. These days, Ruby is used by some of the biggest compa- These features all combine to create an extremely power-
nies in the world, and not just for web development. ful tool: all the beauty and fun of programming Ruby with the
Unfortunately, the standard implementation of Ruby best of the JVM. So, what can you do with this tool?
usually referred to as CRuby or MRI (Matzs Ruby Implemen-
tation)lacks some features modern developers want and Getting Started
often need such as a high-speed just-in-time (JIT) compiler; JRuby, like most JVM-based libraries and applications, is dis-
scalable, low-pause garbage collection; and true parallel exe- tributed in a number of prebuilt binary forms.
cution. Thats where JRuby comes in. Most users will want a full JRuby distribution, available at
http://jruby.org, which includes command-line utilities (like
What Is JRuby? the ruby and gem commands), the Ruby standard library, and
JRuby is an implementation of Ruby atop the JVM, written a ilesystem layout similar to CRuby. I recommend the use of
mostly in Java (but a growing amount in Ruby) and supporting so-called Ruby switchers such as RVM, which will down-
62
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
load and install the latest JRuby implementation. jruby-9.1.2.0 :001 > puts "hello"
hello
$ rvm install jruby-9.1.2.0 ...
Searching for binary rubies, this might take some time
Found remote file /Users/headius/.rvm/... Ruby on Rails
Checking requirements for osx. Every web developer should have heard of Ruby on Rails by
Requirements installation successful. now. It changed the way developers do web development,
jruby-9.1.2.0 - #configure from introducing the idea of sensible defaults (convention
jruby-9.1.2.0 - #download over coniguration) to rich code generation (scafolding) and
jruby-9.1.2.0 - #validate archive database-agnostic schema versioning (migrations). Most web
jruby-9.1.2.0 - #extract frameworks today copy some aspect of Rails, in some cases
jruby-9.1.2.0 - #validate binary even mimicking the ilesystem layout of Rails applications or
jruby-9.1.2.0 - #setup reusing Rails-inspired terms for similar features.
... Next, I walk through getting a simple Rails app running on
JRuby.
See RVMs home page for more details, or try out one of the But irst, I need to install Rails using the gem install
other Ruby switchers. command. Most libraries for Ruby are distributed as gems
For folks who prefer a more direct approach, you can simply hosted on RubyGems.org. From a Java perspective, think of a
download a tarball (.tar.gz) or a zip ile containing a full JRuby Ruby gem as a Maven library plus some executable scripts for
distribution. Unpack it, add the bin directory to your PATH, the command line.
and youre of to the races. JRuby also comes in a Windows
installer that can optionally install a JRE for you as well. $ gem install rails
JRuby also publishes a full complement of Maven artifacts Fetching: rack-1.6.4.gem (100%)
under the org.jruby group, which is useful for embedded Successfully installed rack-1.6.4
applications that will not need a complete on-ilesystem Fetching: sprockets-3.6.0.gem (100%)
JRuby distribution. Successfully installed sprockets-3.6.0
Once installed, JRubys command line matches CRubys: ...
Fetching: rails-4.2.6.gem (100%)
$ jruby -v Successfully installed rails-4.2.6
jruby 9.1.2.0 (2.3.0) 2016-05-26... 23 gems installed
$ jruby -e "puts 'Hello, Ruby'"
Hello, Ruby $ rails new my_app
create
And Rubys interactive console, IRB, is available as well: create README.rdoc
create Rakefile
$ irb ...
63
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
create vendor/assets/stylesheets => Booting WEBrick
create vendor/assets/stylesheets/.keep => Rails 4.2.6 application starting in
run bundle install development on http://localhost:3000
Fetching gem metadata from https://rubygems.org/ => Run 'rails server -h' for more startup options
Fetching version metadata from https://rubygems.org/ => Ctrl-C to shutdown server
Fetching dependency metadata from https://rubygems.org/ [2016-06...] INFO WEBrick 1.3.1
Resolving dependencies.............. [2016-06...] INFO ruby 2.3.0 (2016-06-06) [java]
Using i18n 0.7.0 [2016-06...] INFO WEBrick::HTTPServer#start:
Using json 1.8.3 pid=37393 port=3000
Installing minitest 5.9.0
... Lets quickly scafold some basic functionality for our appli-
Installing sass-rails 5.0.4 cation. In Rails, scafolding is code generated at development
Installing turbolinks 2.5.3 time that provides a rough structure for your application. You
Bundle complete! 11 Gemfile dependencies, can tell Rails to generate models, views, controllers, tests,
54 gems now installed. and more. The following example generates the basic code for
Use 'bundle show [gemname]' to see where CRUD operations against a post with a title and a body.
a bundled gem is installed.
$ rails generate scaffold post title body:text
[Due to width constraints, some lines in this output and invoke active_record
in other output shown in this article have been truncated, create
folded, or had unnecessary data removed. Ed.] db/migrate/20160606083900_create_posts.rb
Now the magic of Rails starts to kick in. By using the create app/models/post.rb
rails new command, I get a fully functional, bare-bones invoke test_unit
application, complete with a welcome page, a convention- create test/models/post_test.rb
based ilesystem layout, and a basic database coniguration create test/fixtures/posts.yml
using sqlite3 (you can specify a diferent database with the invoke resource_route
-d lag). Rails constructs the application and then runs the route resources :posts
bundle command. Bundler is a gem-based dependency man- invoke scaffold_controller
agement tool for applications; Rails builds a Gemile contain- create app/controllers/posts_controller.rb
ing a list of all libraries required for the app, and Bundler invoke erb
makes sure theyre installed. create app/views/posts
At this point, I can start up the Rails application, even create app/views/posts/index.html.erb
though I havent written any logic. create app/views/posts/edit.html.erb
create app/views/posts/show.html.erb
$ cd my_app create app/views/posts/new.html.erb
$ rails server create app/views/posts/_form.html.erb
64
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
invoke test_unit before, perhaps JRuby can be your excuse to try it now. Check
create out the excellent documentation and tutorials on the Rails
test/controllers/posts_controller_test.rb site, or pick up one of the many Rails books out there.
... OK, Ive built a killer app. Now, how do I deploy it with JRuby?

In addition to the actual application code and tests, the scaf- Deploying Rails on JRuby
folding generated whats called a database migration. This is a In CRuby, if you want to handle any requests in parallel, you
short script that can take one version of the database scheme need to spin up separate processes that is, completely inde-
and apply changes needed to migrate to the next version. pendent VMs that share no resources. As a result, even small
These migrations allow you to roll schemas back and forth in applications will consume more memory, and if they need to
a database-agnostic way. do any communication, youre forced to use some interpro-
Then I just need to roll the database migration forward and cess communication. Data sharing has to be done in a third
start the server again. process, such as a database or memcached, because those
processes share only read-only application structure. Now
$ rake db:migrate you have a whole bunch of Ruby virtual machines running,
== 20160606083900 CreatePosts: migrating ========= each with its own heap and garbage collectorthis is not the
-- create_table(:posts) best use of resources in this multicore era.
-> 0.0075s In JRuby, you can take that same Rails application and han-
-> 0 rows dle your entire load inside a single process, with a single gar-
== 20160606083900 CreatePosts: migrated (0.0099s) bage collector tuned for concurrency and scalable heaps. That
one process can be a standalone server, or you can deploy
$ rails server JRuby on Rails as a Java WAR ile to any standard web con-
=> Booting WEBrick tainer such as Tomcat or WildFly. Whether youre coming to
... JRuby from Ruby or Java, deployments of JRuby applications
it your world and make better use of your hardware.
Here I am using the rake com- For simple, standalone use, the Puma gem, which is
mand, which is roughly equiva-
JRuby supports the most popular pure-Ruby web server, is generally
lent to using Ant or Maven, two-way integration recommended.
minus the dependency manage- with other JVM
ment. Once Rails has migrated $ gem install puma
to the latest database schema,
languages, so all Fetching: puma-3.4.0-java.gem (100%)
I can start up the server and, those Java libraries Successfully installed puma-3.4.0-java
presto, I have a basic web GUI for youre familiar with can 1 gem installed
CRUD operations. $ puma
Rails is still the killer app for
still be in your toolbox. Puma starting in single mode...
Ruby, and if you havent tried it * Version 3.4.0 (jruby 9.1.3.0-SNAPSHOT - ruby 2.3.0),
65
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
codename: Owl Bowl Brawl java_import java.lang.System
* Min threads: 0, max threads: 16
* Environment: development Frame = javax.swing.JFrame
* Listening on tcp://0.0.0.0:9292 Button = javax.swing.JButton
Use Ctrl-C to stop Label = javax.swing.JLabel

If you need to deploy to an existing Java app server or web frame = Frame.new("Java Home Checker")
container, use the Warbler gem to package your Rails app button = Button.new("Display Java Home")
(plus all its dependencies) into a deployable WAR ile. label = Label.new

$ gem install warbler button.add_action_listener do


Fetching: rubyzip-1.2.0.gem (100%) label.text = System.get_property('java.home')
Successfully installed rubyzip-1.2.0 end
Fetching: jruby-rack-1.1.20.gem (100%)
Successfully installed jruby-rack-1.1.20 frame.content_pane.layout = java.awt.FlowLayout.new
Fetching: jruby-jars-9.1.2.0.gem (100%) frame.content_pane.add(button)
Successfully installed jruby-jars-9.1.2.0 frame.content_pane.add(label)
Fetching: warbler-2.0.3.gem (100%)
Successfully installed warbler-2.0.3 frame.set_default_close_operation(Frame::EXIT_ON_CLOSE)
4 gems installed frame.set_size(500, 100)
$ warble frame.visible = true
rm -f my_app.war
Creating my_app.war sleep

Thats all there is to it. This simple example already shows some of JRubys advan-
tages. Speciically, imports are just plain Ruby code. The code
Scripting Java shows two ways to import a class: using the java_import
Theres another feature of JRuby that makes it even more function or simply using the fully qualiied long class name
attractive for Ruby and Rails developers: you can call (and assigning it to a short one).
any library on the JVM as if it were just another piece of Java method names are tweaked a bit to make them look
Ruby code. more like Ruby method names: snake_case is used instead of
JRuby supports two-way integration with other JVM lan- camelCase, set/get properties can omit set/get and be called
guages, so all those Java libraries youre familiar with can still by just the attribute name, parentheses are optional, and so
be in your toolbox. In fact, scripting Java libraries with JRuby on. In fact, you might not even know this code calls a Java
is often much more fun and much easier than writing Java library if you werent familiar with Swing.
code. Lets have a look at a few examples. Simple interfaces can be implemented on the ly by passing
66
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
a block of code, similar to Java 8 lambdas. But JRuby can also libraries are installed on the local ilesystem as Ruby sources,
dynamically add an interface implementation to any object, but occasionally they will bring along extensions written in
and it doesnt have to implement all methods (usually by other languages.
including a method_missing fallback). On line 3, I have a Ruby class deinition extending the
Theres a lot less noise and ceremony in this code than JRubyFX::Application class. Classes in Ruby are declared
there would be in the Java version. with the class keyword, just as in Java, but instead of having
Lets take a look at a few more-advanced examples of what an extends keyword Ruby uses the less-than symbol (<). The
you can do with JRubys Java integration. double colons are Rubys way to indicate namespacing.
The irst method deinition is on line 4. Because Ruby
JRubyFX is dynamically typed, there are no type declarations for a
In late 2008, Sun Microsystems released the irst version of method return or method parameters.
JavaFX, a new GUI toolkit inspired by web technologies and Lines 5 through 8 set up the stage. I set a title and window
destined to be the replacement for Swing. JavaFX initially had size (using Ruby-style attribute assignment rather than Javas
its own language, JavaFX Script, but in an already tight world set methods), and then I tell JavaFX to show the stage.
of language options, only the GUI Toolkit survives to this Lines 9 and 10 end the method and the class deinition.
day. That means youll be writing your JavaFX logic in Java. Most lexical scopes in Ruby are closed with the end keyword,
Perhaps a little JRuby can help here, too. although short blocks (lambdas) frequently use curly braces.
Enter JRubyFX, a Ruby API and wrapper for writing JavaFX And inally, on line 12, I tell the new JRubyFX application to
applications. Lets walk through a simple example. launch itself. Its that easy.
Now lets look at how Ruby can really make the application
01 require 'jrubyfx' fun and easy to write.
02
03 class HelloWorldApp < JRubyFX::Application def start(stage)
04 def start(stage) with(stage, title: "Hello World!") do
05 stage.title = "Hello World!" layout_scene(800, 600) do
06 stage.width = 800 label("Hello World!")
07 stage.height = 600 end
08 stage.show() end
09 end stage.show # you can also put the
10 end # method call inside the block
11 end
12 HelloWorldApp.launch
Here, the start method is a bit more complicated. The most
On line 1, I require jrubyfx, which is a set of bindings for obvious change is the call to with, which takes a block of code
the JavaFX library, so I can use its features. In Ruby, libraries using JRubyFXs scene-building DSL. Given the Stage pro-
are brought into the process using require. Generally these vided by JavaFX and a title, I proceed to build the stages con-
67
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
tents. I tell the DSL how to lay out this scene, and then I add show
some actual content: a JavaFX label. end
What about FXML, JavaFXs XML-based markup for describ- end
ing scenes? Building the scene with Ruby is great (and cer-
tainly a lot less hassle than doing it in Java), but for larger JRuby and JavaFX work really well together, so if you havent
applications, you probably want a description of the GUI thats had a chance to try JavaFX, JRubyFX might be the most fun
separate from the application code. youll have this week. Check out the complete Getting Started
Heres an FXML deinition for my simple scene: page for JRubyFX.

<?xml version="1.0" encoding="UTF-8"?> Beyond the JVM


JRuby strives to be pure Java (and some Ruby) as much as
<?import java.lang.*?> possible, and it supports users on a wide array of platforms,
<?import java.util.*?> from Linux to OpenVMS. The platform-independence of
<?import javafx.scene.control.*?> Java serves you well here. Unfortunately, that independence
<?import javafx.scene.layout.*?> sometimes means you cant integrate with the host platform
<?import javafx.scene.paint.*?> as well as a native application can (or, in this case, as well as
<?import javafx.scene.text.*?> CRuby can).
To maintain JRubys high level of compatibility, you often
<HBox alignment="CENTER" need to call out to native libraries. Normally on the JVM this
xmlns:fx="http://javafx.com/fxml"> would mean writing a lot of Java Native Interface (JNI) code
<children> for every function to be called from Java, building the code
<Label text="Hello World!!" underline="true"> for all supported platforms, and shipping that ever-growing
<font> binary with JRuby. That approach obviously doesnt scale,
<Font size="66.0" /> so the JRuby team took a diferent approach: it uses the Java
</font> Native Runtime (JNR) to load and bind libraries dynamically
</Label> at runtime.
</children> JNRsimilar to Java Native Access (JNA), which you might
</HBox> already be familiar withuses a low-level binding for libi
(the foreign function interface [FFI] library used by most
Using this deinition in JRubyFX is as simple as adding a call UNIX platforms) to pull a library in, ind the needed function,
to the fxml method, as shown next. and bind it to a Java interface. JRuby pulls in and binds a large
number of POSIX functions, UNIX socket support, native I/O
def start(stage) ile descriptors, and much more.
with(stage, title: "Hello World!", As a Rubyist, you can also leverage JRubys native support
width: 800, height: 600) do via the i gem, which provides an easy-to-use Ruby API to
fxml "Hello.fxml" call native libraries.
68
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
require 'ffi' [ :pointer, :pointer ], :int
end
module POSIX
extend FFI::Library t = Timeval.new
attach_function :getuid, :getuid, [], :uint LibC.gettimeofday(t.pointer, nil)
attach_function :getpid, :getpid, [], :uint puts "t.tv_sec=#{t[:tv_sec]} \
end t.tv_usec=#{t[:tv_usec]}"

pid, uid = POSIX.getpid, POSIX.getuid JRubys FFI also provides a way to deine native data types,
puts "Process #{pid} running as user #{uid}" such as structs. In the preceding code, I deine a Timeval
struct that has an in-memory layout of two unsigned longs:
In this example, Ive created a Ruby module to hold native tv_sec and tv_usec. I bind in the libc gettimeofday function,
function bindings. Think of a module as an interface with construct a new instance of Timeval, and make the call. The
default implementations for every method. Those methods native call populates a native struct that I can then read from
can be class methods (similar to static methods in Java) or like a normal Ruby object, all without writing a line of C code.
instance methods that are added to a class hierarchy when Pretty cool, right?
the module is included (similar to implementing an interface FFI is capable of much more than this, and there are many
in Java). large production apps out there leveraging JRubys native capa-
Inside the LibC module, in the next listing, I extend the bilities. For more information, stop by the Ruby FFI project.
FFI::Library module, which injects other FFI methods I
can use to bind functions and deine native data types. Now The Future of JRuby 9000
I have access to attach_function from the previous listing, JRuby 9000 represents one of the most advanced JVM lan-
which takes as arguments the name of the function I want guage implementations available. It has its own bytecode-like
to call, an optional Ruby name to assign to the function, and intermediate representation, an optimizing compiler, and a
information about parameter types. mixed-mode interpreter plus a JIT compiler (very much like
Thats it. Run this code on JRuby, and youll see the real, live the JVM itself). The JRuby team has been pushing the limits
process ID and user ID for the host JVMsomething thats of what a language can do atop the JVM. In fact, JRuby is cur-
not possible to do with pure Java code. rently the fastest Ruby implementation available. By the end
of this year, the team hopes to utilize its internal representa-
class Timeval < FFI::Struct tion (IR) runtime to make all JRuby code perform compara-
layout :tv_sec => :ulong, :tv_usec => :ulong bly to equivalent Java code, without sacriicing any of Rubys
end unique features.
But the JRuby team is not stopping there. In late 2014,
module LibC the team partnered with Oracle Labs to open-source their
extend FFI::Library Trule-based Ruby implementation as part of the JRuby
attach_function :gettimeofday, project. Trule is a next-generation language runtime that
69
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages / //user groups /
lives alongside JVM bytecode but it uses the pure-Java Graal
JIT compiler to directly optimize a languages behavior. As a
result, JRuby plus Trule might prove to be the fastest way
BUCHAREST JUG
to run Ruby on any runtime, albeit with the requirement that Bucharest, Romania, is a
you run on a Graal-friendly JVM such as JDK 9. The JRuby regional leader in soft-
team hopes to see the JRuby plus Trule runtime production- ware development. The
ready in the next couple of years. Bucharest Java User Group
The team is very excited, both about its IR runtime and was formed to create a
about Trules potential. Ruby is no longer a slow language. strong community for all
the developers in Bucharest
Conclusion who are using Java- and
Ruby is a beautiful, fun language with a rich ecosystem and JVM-based programming
a friendly, helpful community. That community has built languages.
Rails into the powerhouse it is todaythe fastest way to get The irst meeting took
a well-structured web application deployed to production. place in May 2012 with approximately 25 participants. The
You can leverage the best of the Ruby world and the best of Java user group (JUG) is now led by Alex Proca and Alin
the Java world using JRubydeploying to the same servers, Pandichi and has more than 600 registered members. It
using the same libraries, getting the best out of the JVM organizes monthly meetings with one or two presentations,
and you just might have fun doing it. Its a great time to starting around 7 p.m.; later on, it moves to a pub for drinks.
try JRuby. </article> Occasionally, it hosts hands-on labs such as the recent work-
shops on the MVC 1.0 (JSR 371) Java EE speciication and on
Charles Nutter is a Java Champion who works at Red Hat on JavaFX. Around 50 participants usually attend the talks, and
JVM languages and bending the JVM to his whims. He has been a 10 attend the workshops.
co-lead of the JRuby project for the past 10 years, and worked as The speakers are often selected from the local pool of
a lead Java EE architect for many years before that. He hopes to talented Java developersfor instance, Eugen Paraschiv (also
keep the Java platform open and evolving, and works to expand the known as Baeldung), whose tutorials and reviews have gar-
platform to new languages and new ways of building software. nered a sizable following. From time to time, the JUG hosts
international speakers such as Java Champion Axel Fontaine,
who gave a presentation about immutable infrastructure.
Local interest in Java, catalyzed by the JUG, led to a Java
conference, Voxxed Days Bucharest, which was irst held in
learn more March 2016. The organizers are already looking forward to
next years event.
Home of the Ruby language (non-JVM) The Bucharest JUG keeps in close contact with members
Trule on the JDK of the worldwide Java communities. Contact it via email or
follow it on Twitter, Facebook, Google+, or Meetup.
70
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//ix this /

Quiz Yourself
More subtle questions from an author of the Java certification tests

SIMON ROBERTS
I ve put together more interesting problems that simulate
questions from the 1Z0-809 Programmer II exam, which is
the certiication test for developers who have been certiied
public class MultiCatch {
public void fingersCrossed()
throws OneException, TwoException,
at a basic level of Java programming knowledge and now are ThreeException { }
looking to demonstrate more-advanced expertise. [Readers
wishing basic instruction should consult the New to Java public void tryThingsOut() /* Point A */{
column, which appears in every issue. Ed.] try {
Question 1. Given this class declaration: fingersCrossed();
public class Tire { private int diameter, width; } } catch (OneException | TwoException ex) {
ex.printStackTrace();
Which two actions are normally performed to support simple use throw ex;
in the Collections framework? Choose two. } catch (ThreeException e) {
a. Add a method with the signature public boolean e.printStackTrace();
equals(Tire t). }
b. Add a method with the signature public int }
hashCode(Tire t). }
c. Add a method with the signature public boolean
equals(Object o). Which is the best change? Choose one.
d. Add a method with the signature public int a. No change is necessary; the code is ideal as shown.
hashCode(). b. The code should be modiied by adding at /* Point A */
e. Arrange that the class implements Comparable<Tire>. the text throws Exception.
c. The code should be modiied by adding at /* Point A */
Question 2. Given the following code: the text throws BaseException.
public class BaseException extends Exception {} d. The code should be modiied by adding at /* Point A */
public class OneException extends BaseException {} the text throws OneException, TwoException.
public class TwoException extends BaseException {} e. The code should be modiied by adding at /* Point A */
public class ThreeException extends Exception {} the text throws OneException, TwoException,
ThreeException.
71
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//ix this /
Question 3. Given the following code: actually depend on ordering, such as TreeSetorder isnt
System.out.println( really a fundamental part of the API as a whole. However,
Stream.empty().findAny() the idea of equality is absolutely fundamental. The basic
// Line n1 way that most collections determine whether they contain
); one particular object is by using the equals method to see
whether the object in the collection is equivalent to the one
Which two, applied independently, may be added at line n1 to being asked about.
cause the output "Empty"? Choose two. So, equals is almost certainly the irst method youll
a. .ifPresent(s->s).orElse("Empty") think about implementing for any class thats going to be
b. .orElse("Empty") stored in a collection, at least if theres any chance of need-
c. .orElseGet(() -> "Empty") ing to ind it directly. The next question is which of the
d. .orElseGet("Empty") two proposed method signatures is correct. Both will com-
e. .orElseSupply(()->"Empty") pile, but the actual signature must take an Object argu-
f. .otherwise("Empty") ment. There are two reasons. First, from a syntax perspec-
tive, this method must override the equals method deined
Question 4. Which of the following two statements, indepen- in java.lang.Object, and thats deined to take an Object
dently, might be good uses of assertions? Choose two. argument. Second, from a philosophical perspective, its
a. assert x >= 0 : "X must be non-negative"; perfectly reasonable to ask whether this apple is equal to
b. assert x++ > 0; that banana. The answer is simply no. Its tempting in
c. assert x == 0; these days of familiar generics to think that the method
d. assert (++x > 0 , "X must be non-negative"); would take an argument of the objects own type, but if that
e. assertTrue "X must be zero" : x == 0; method is implemented, it will be ignored by the Collections
API. So, option A is incorrect, and option C is the proper
equals method. Dont forget that when overriding a method,
its good practice to use the @Override annotation. That
will ensure that if you declare the argument as anything
Answers other than Object, the compiler will tell you that you made
a mistake.
Next, the documentation for equals states, Note that it is
generally necessary to override the hashCode method when-
ever this method is overridden, so as to maintain the general
Question 1. The correct answers are options C and D. In this contract for the hashCode method, which states that equal
question, there are three methods to choose among: equals, objects must have equal hash codes.
hashCode, and the compareTo method of the Comparable Given this requirement, its pretty clear that implement-
interface. While order comparisons are certainly relevant ing equals almost mandates implementing hashCode. The
to some parts of the Collections APInotably those that remaining question is what the signature should be. Given
72
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//ix this /
that this is an instance method, and it generates a represen- Finally, theres the question of whether the other answers
tative number based on the contents of this, its fairly clear are wrong or whether they could be cause for a complaint to
that no argument is needed, and indeed, the documentation the examiners. Well, its certainly true that options B, C, and E
shows that option D is correct and option B is wrong. also compile. Functionally, they work perfectly well, too, and
Its fair to note that although equals and hashCode are the that might tempt you to believe that theyre all equally valid.
most fundamental methods required of classes that partici- However, checked exceptions have two consequences.
pate in collections, the Comparable interface, with its method First, they put a burden on the programmer who writes
compareTo, is certainly relevant in some situations. Ordered the calling code, and (except with interfaces) you should not
structures, such as the implementations of SortedSet and declare more exceptions than you might throw without a
SortedMap, often use it. If this were an exam question, the good reason. Second, they should convey useful information
fact that youre told to select two answers should remove about failure modes to the caller. If you declare a more gen-
any small doubt you might have had about leaving option E eral exception, that information is diluted or lost, which is
unchecked. Its worth mentioning that its a matter of policy: unhelpful and reduces readability. Both of these reasons
Oracles Java certiication exam questions always state exactly should tell you that options B, C, and E, all of which declare
how many answers you should select. Be careful not to throw throwing more exception classes than are actually possible,
points away by ignoring this advice! are not as good as option D.
Question 2. The correct answer is option D. The essence of Of course, its possible that you dont accept the reasoning
this question has two parts. First, the exception classes are just given. Javas checked exception mechanism is the subject
all checked exceptions, which means that if you rethrow the of much debate, so its clear that opinions difer. But most of
exception caught in the multicatch (that is, in the part catch those who dislike checked exceptions would strongly sup-
(OneException | TwoException ex)), you must declare that port the notion that throwing too many exceptions is bad.
the method throws that exception type. This means that Anyway, the inal observation is that you are told to choose
option A is incorrect; the code does not compile as is. one answer. So, you know that you must distinguish among
The second part of the question relates to what the type of four compilable answers. You need to ind a plausible reason
the formal parameter ex actually is, and what the checked to make a choice, even if you dont personally like the reason.
exception mechanism demands for the declaration. This is Dont be afraid to apply a little logic to separate plausible
slightly trickier, and its where that bothersome word best in answers from better answers. Its probably the case that this
the phrase the best change comes in. question would be subject to considerable scrutiny by the
In the code, ex can really have only one type, and this is exam team. Indeed, I suspect it might be rejected. My purpose
actually the closest common parent of the types listed in in including it here is to illustrate how logic and knowledge of
the multicatch; that is BaseException. However, the checked good practices can be applied to choose one right answer
exception mechanism understands the multicatch syntax, among several answers that compile and run successfully.
and when rethrowing ex, only those exceptions speciically Question 3. The correct answers are options B and C. This
listed in the catch parameter list need to be declared in the question hinges on some knowledge about Stream API behav-
throws clause. Option D lists exactly the same exceptions as ior and the Optional class.
the catch block, and it is the correct answer. First, the findAny method returns an object from the
73
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//ix this /
stream. However, the stream might be empty, and whenever pile. Option D fails because the assert keyword is just that: a
theres a chance that a stream terminal operation might not keyword. Its not a method call, so the syntax there is bogus.
have anything to return, the Optional class is used to repre- Also, assertTrue in option E is not part of the core Java SE
sent the result. As a side note, Optional is an API mechanism API, but the name is used in tools such as JUnit. However,
intended to avoid null pointer exceptions. Tony Hoare, inven- assertTrue in JUnit is a method, so it requires parentheses
tor of null pointers, has acknowledged that these have caused and a comma rather than a colon to separate its parameters.
many bugs; he now refers to them as his billion-dollar mis- Option E is, therefore, wrong. As a side note, the Java exam is
take. To be fair, the use of special values to indicate errors or about core Java features, not third-party APIs, so if you knew
exceptional situations is now almost universally recognized what assertTrue is about, you should have rejected it from
as a bad thing, and exceptions address this issue, too. consideration for that reason.
Once you recognize that you will get an Optional from the Of the three compilable options, two are good and one
findAny terminal operation, you need to know how to interact is severely broken. Option A is the two-operand form of
with it and get the text Empty from our println method assert; the irst operand is a boolean expression, and the
call. In this case, you know that the stream is empty and, second is a text message that will become the message in the
therefore, findAny will return an empty Optional to us. AssertionError that is thrown if the boolean evaluates to
Given an empty Optional, there are two methods intended false. Option C uses the single-operand form, which executes
to directly return a value for your use. Consulting the API the boolean test and builds an AssertionError with a null
documentation, you can see that these methods are orElse message if the boolean evaluates to false. Next, lets look at
and orElseGet. Both methods return the contents of the why option B is a huge error, even though it compiles.
Optional if it is not empty or an alternative value if it is The goal of assertions is to allow the programmer to put
empty. The orElse version takes a simple value that is to be certain statements about design intent into the code, in a way
returned, matching the call in option B. The orElseGet ver- that forms documentation that cannot be wrong. The bool-
sion takes a Supplier, which is invoked in the event that ean expression that forms the required operand for an assert
the Optional is empty. Supplier is a functional interface must be true; otherwise, the assert is expected to complain.
that deines a method that takes no arguments and returns These little statements can be very helpful when picking up
a value. To create that as a lambda expression requires the code that someone else wrote; they can tell all sorts of use-
empty parentheses, followed by the arrow symbol, and then ful details about how the code works. However, because the
the expression that deines what the newly supplied value expression in the assertion seemingly must be evaluated
will be. That suggests the form () -> expression, or, to every time the program runs past the statement, its possible
return the speciic literal: () -> "Empty", which is option C. to be concerned that the CPU usage of all these little tests
The other options are syntactically incorrect. could adversely afect performance.
Question 4. The correct answers are options A and C. Heres A performance concern like that would probably discourage
that word good again. It gives you a bit of a hint that some most programmers from using assertions freely. However,
level of judgment beyond whether or not something compiles assertions have a neat trick: the code of assert statements
might be important here. can be stripped from the bytecode during classloading. If
In this case, three optionsoptions A, B, and Cwill com- this happens, the statements have zero performance impact.
74
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//ix this /
It turns out that stripping them is the default behavior.
So, you must explicitly use the command-line option -ea,
or -enableassertions, for the assertions to be executed.
(Unfortunately, IDEs also generally duplicate this default.)
The intention is that programmers always test their code
with -ea in efect and that the user runs the inal program
without it. That creates an elegant best of both worlds
situation that, in my view, gets far less use than it should.
Of course, this conditional execution also creates an
interesting potential problem. Imagine that the boolean
expression in your assertion actually does something of
computational signiicance. It has a side efect and changes
something in some way. Now you have the makings of a
disaster; the functional behavior changes depending on
whether you run in development mode (with -ea) or produc-
tion mode (without it). The documentation of assert goes to
great lengths to point out that side efects of any kind must
be avoided in an assert statement. For this reason, option B is
bad and, therefore, incorrect.
The Java Language Speciication, in section 14.10, notes,
Because assertions may be disabled, programs must not
assume that the expressions contained in assertions will be
evaluated. Thus, these boolean expressions should gener-
ally be free of side efects. You can ind more discussion
on safe and appropriate uses of assert here. Notice that in
that document, there are other dos and donts, which is why
the question in this quiz asks which might be good uses...,
rather than which are good uses.... Options B, D, and E
cannot possibly be good; the other two might be if other
conditions are met, but no information is available on those
issues. </article>

Simon Roberts created the Sun Certiied Java Programmer and


Sun Certiied Java Developer exams. He wrote several Java certii-
cation guides and is now a freelance educator at many large com-
panies. He remains involved with Oracles Java certiication.
75
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//contact us /

Comments Finally, algorithms, unusual but useful Where?


We welcome your comments, correc- programming techniques, and most other Comments and article proposals should
tions, opinions on topics weve covered, topics that hard-core Java programmers be sent to our editor, Andrew Binstock,
and any other thoughts you feel impor- would enjoy are of great interest to us, at javamag_us@oracle.com.
tant to share with us or our readers. too. Please contact us with your ideas While it will have no inluence on
Unless you speciically tell us that your at javamag_us@oracle.com and well our decision whether to publish your
correspondence is private, we reserve give you our thoughts on the topic and article or letter, cookies and edible treats
the right to publish it in our Letters to send you our nifty writer guidelines, will be gratefully accepted by our staf
the Editor section. which will give you more information at Java Magazine, Oracle Corporation,
on preparing an article. 500 Oracle Parkway, MS OPL 3A,
Article Proposals Redwood Shores, CA 94065, USA.
We welcome article proposals on all Customer Service
topics regarding Java and other JVM If youre having trouble with your Subscription application
languages, as well as the JVM itself. subscription, please contact the Download area for code and
We also are interested in proposals for folks at java@halldata.com (phone other items
articles on Java utilities (either open +1.847.763.9635), who will do Java Magazine in Japanese
source or those bundled with the JDK). whatever they can to help.

76
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016

You might also like