You are on page 1of 72

JAVA 8 COMPACT PROFILES 56 | GRADLE INTERNALS 60 | MESSAGING WITH MQTT 46

MARCH/APRIL 2017

magazine
By and for the Java community

UI Tools
17
SCRIPTING
24
VISUAL DESIGN
30
MVC 1.0: BUILDING
40
WEB UI
JAVAFX WITH WITH SCENE WITH THE MVC CONSTRUCTION
FXML BUILDER ARCHITECTURE WITH ORACLE JET

ORACLE.COM/JAVAMAGAZINE
//table of contents /

24 30 40
SCENE BUILDER: THE MVC 1.0: A FRESH, BUILDING BROWSER-
JAVAFX UI DESIGN TOOL NEW FRAMEWORK BASED UIs WITH
By Johan Vos FOR ENTERPRISE APPS ORACLE JET
The interactive UI design tool By Josh Juneau By John Brock
originally developed by Oracle A look at a remarkably lexible Using Oracles open source
continues to advance in the framework that builds on JAX-RS JavaScript toolkit
17 open source community.

ENHANCED FXML USING


THE FXMLLOADER
By Andrs Almiray
Gain greater lexibility in deining JavaFX UIs declaratively
by exploiting the FXMLLoader mechanism.
COVER ART BY BOB MORRIS

04 46 60 59
From the Editor IoT Build User Groups
The demanding economic model for JVM Simple Messaging with MQTT Gradles Java Philly JUG
languages to be successful means that By Gastn Hillar Library Management 65
few will ever be widely adopted. Use the principal IoT messaging protocol By Peter Ledbrook
to asynchronously send and receive data
Java Proposals of Interest
06 As builds become more complex JSR 372: JSF 2.3
from devicesin this case, from drones. consider monolithic reposlibrary
Letters to the Editor 71
Comments, questions, suggestions, 56 dependencies present a special
and kudos The Road to Java 9 challenge that build tools such as Contact Us
Gradle are working at solving. Have a comment? Suggestion?
09 Exploring Compact Profiles Want to submit an article proposal?
By Ben Evans 66
Events Heres how.
Upcoming Java conferences and events
Need smaller executables? Migrate to Fix This
Java 9. Cant migrate? Then consider By Simon Roberts
14 Java 8s Compact Proiles. Our latest code quiz
Review
Review of Java 8 refactoring video
01
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
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
Karen Perkins, Jim Donahue Audience Development Manager
Technical Reviewer Jennifer Kurtz
Stephen Chin
ADVERTISING SALES
DESIGN
Senior Creative Director
Francisco G Delgadillo
Sales Director
Tom Cometa
Account Manager
The brightest minds in
Design Director
Richard Merchn
Mark Makinney
Mailing-List Rentals
tech are coming to Austin.
Senior Designer Contact your sales representative.
Arianna Pucherelli
Designer RESOURCES
Jaime Ferrand
Oracle Products
Senior Publication Designer +1.800.367.8674 (US/Canada)
Sheila Brennan
Oracle Services
Production Designer +1.888.283.0591 (US)
Kathy Cygnarowicz

ARTICLE SUBMISSION
If you are interested in submitting an article, please email the editors.
SUBSCRIPTION INFORMATION
Subscriptions are complimentary for qualified individuals who complete the
subscription form. Learn which open source models are right
MAGAZINE CUSTOMER SERVICE
java@halldata.com Phone +1.847.763.9635 for allor even partof your business at OSCON.
PRIVACY
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 May 8 11, 2017
Customer Service. oscon.com
Copyright 2017, 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
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 JAVA MAGAZINE READERS GET
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.
20% OFF WITH CODE JAVA
Java Magazine is published bimonthly and made available at no cost to qualified subscribers by
Oracle, 500 Oracle Parkway, MS OPL-3A, Redwood City, CA 94065-1600.

02
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// MARCH/APRIL 2017
Performance-Focused Developer Tool lets you
see request breakdowns, IO queries, logs and exceptions
without leaving the window or your webapp.
Real time insight,
14 DAY FREE TRIAL! faster apps
//from the editor /

The Best
Resource
The Rise and Fall of JVM Languages for Modern
A viable business model is key to language adoption. Cloud Dev
The Oracle Developer

F or the last 18 months, we at Java Magazine


have been covering all sorts of interesting JVM
languagesfrom the well known to the obscure.
guages (such as the JRuby port of Ruby and the
Jython port of Python) and those that are built
from the ground up for the JVM (Groovy, Kotlin,
Gateway is the best place
to jump-start your modern
cloud development skills
There is no doubt we could continue doing this Scala, Golo, Fantom, and many others). Those in with free trials, downloads,
for another couple of years without covering the the latter group often position themselves as an tutorials, documentation,
same language twice. Thats in many ways the improved alternative to Java the language. And and more.
glory of the JVM: it is a great platform for language indeed these languages do provide features or
back ends. syntax that Java has not implementedoften
Trials. Downloads.
The beneits of the JVM include performance, for speciic reasons. Other times, the languages
Tutorials. Start here:
wide availability and familiarity, excellent tools, lead to Javas adoption of features, in which case
developer.oracle.com
and thorough documentation. In addition, theres the Java team has the beneit of examining those
a high level of conidence that the JVM will con- implementations when formulating its own. That
tinue to be widely used, so languages that depend Oracle sees value in this dialogue is apparent
on it wont suddenly need to ind a new platform in its longtime production of the JVM Language
(as those that targeted Adobe Flash, for example, Summit at midyear, where JVM language design-
developer.oracle.com
were forced to do). ers come together to compare notes among them-
JVM languages generally fall into two major selves and with the Java team members.
categories: those that are ports of existing lan- Because of our long coverage of JVM lan- #developersrule

PHOTOGRAPH BY BOB ADLER/VERBATIM


04
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//from the editor /
guages, I am occasionally asked to cross the chasm as Groovy did lents are developing and promot-
which of them will become popu- that is, without serious inancial ing Kotlin.
lar enough to cross the chasm. backing. Writing a language is a In the process, Kotlin has
This term, which originated in very expensive proposition, as morphed into more than just
Geofrey Moores book of the same is promoting it. While originally an eiciency tool for JetBrains.
name, refers to an increase in an academic creation, Scala was Its intensely pragmatic orienta-
popularity that drives a technol- backed by the startup Typesafe tion has strongly resonated with
ogy from the exclusive domain of
visionaries and early adopters into
until the company realizedas
Pivotal did with Groovythat
a signiicant and active commu-
nity, which accelerates its move-
Level Up at
the wider embrace of pragmatists there is no revenue to be made ment across the chasm. Kotlin Oracle Code
and especially of businesses. I in selling a new language. As a thereby enables JetBrains to bring
believe there are only three lan- result, Typesafe changed its name new developers into its tool eco- Step up to modern cloud
guages that are capable of this to Lightbend and refocused on its system. But the growing user development. At the
crossing or have already done so: nonlanguage products. The break base also presents the company Oracle Code roadshow,
Groovy, Scala, and Kotlin. from being the Scala company with the challenge that success- expert developers lead
Groovy found success as a was so clean that the press release ful languages often face: manag- labs and sessions on PaaS,
quirky scripting language that announcing the name change did ing the demands of users versus Java, mobile, and more.
has illed numerous niches where not even mention the language in the companys own desires for
quick but expressive coding is the body of the announcement. the language.
needed. It is the scripting language As I said, theres just no money Because economics support
Get on the list
for many testing frameworks and in languages. Kotlins evolution and JetBrains
for event updates:
go.oracle.com/oraclecoderoadshow
is used for writing build scripts Kotlin relies on a rather dif- longstanding knowledge of devel-
in Gradle. It is also unique among ferent model. The language was opers will help it work with the
the primary JVM languages (the devised in part for JetBrains community, I expect that within
three mentioned above plus Java) internal use. Its design is prag- the next few years Kotlin will
in that it did not require corporate matic and aimed at helping the fully cross the chasm and emerge
sponsorship to become popular. company reduce costs in develop- as aor possibly theprimary
(Even though Pivotal did support it ing its extensive line of developer non-Java JVM language, so prov-
for a few years, Groovy was popu- tools. The beneits of developing ing yet again the robustness of the
lar long before Pivotals acquisi- and promoting Kotlin outweigh JVM ecosystem.
tion and has continued to be since its costs and, crucially, JetBrains
developer.oracle.com
Pivotal stopped sponsorship.) This derives its income from products Andrew Binstock, Editor in Chief
is testament to the community other than Kotlin. The costs, how- javamag_us@oracle.com
skills of the projects longtime ever, are signiicant. According to #developersrule
@platypusguy
leader, Guillaume Laforge. Andrey Breslav at JetBrains, more
Today, no language can hope than two dozen full-time equiva-
05
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//letters to the editor /
LOCAL-VARIABLE TYPE INFERENCE 60 | SCALA 47 | BLOCKCHAIN 36
JavaScript in Java Magazine guages are compiling to JavaScript. It has been exactly
We received more than 30 replies to our request in the two years since Scala.js went from a science proj-
JANUARY/FEBRUARY 2017

magazine January/February issue (The Polyglot Future) for com- ect to something the Scala community is actively
By and for the Java community
ments about regular coverage of JavaScript. The replies promoting. And Kotlin is gunning to be both a Java
boiled down to three principal points of view, as articulated replacement and a TypeScript replacement, which
in the following three notes. has meant making Kotlins type system able to
TOOLS impersonate JavaScript.
17 22 29 Lots of It! Im not an Android developer, but my wife is an
POLYGLOT: INSIDE THE BUILD YOUR OWN

Yes, please include a regular column on JavaScript. It iOS developer who works closely with Android and
MOVING MAVEN ARCHITECTURE JVM DEBUGGING
PAST XML OF BUILD TOOLS TOOLS

can be arbitrarily large! web developers to keep their code in sync. Naturally
ORACLE.COM/JAVAMAGAZINE

I have been a Java programmer for 16 years. Two they use JavaScript on all three platforms, and Ive
JANUARY/FEBRUARY 2017
years ago, I landed in a job that required client-side suggested they look into React Native to help unify
JavaScript coding. After a frustrating six months, I the codebase. React is something you could cover
learned to respect JavaScript: it is a language and an without even mentioning JavaScript.
ecosystem capable of producing quality software and If anything, the argument against covering
fantastic tooling. JavaScript is that theres just too much to do it justice.
Despite seeing the elegance of libraries and per- It seems that every time you dip your toe in, some
formance of runtimes like Node, I am wondering how new framework has taken over. Blink and you miss it.
large-scale development is possible with a language Id be fascinated to see a deep dive comparing the
that does not have interfaces, like Java has. tradeofs between JITs from HotSpot, Dalvik, and the
I feel really curious to learn how Java program- various JavaScript JITs. But maybe thats just me.
mers with a similar mindset ind their place in a David Leppik
world without interfaces and without a threading API
(another topic that fascinates me). No JavaScript at All
Csaba Koncz I suggest Absolutely None for the introduction of
other programming languages in Java Magazine. At
Some JavaScript, Please the same time, I suggest another magazine that cov-
My irst thought after reading your editorial was, Id ers the polyglot issues discussed in the editorial, with
read it, but I dont know how much other JVM devel- topics involving basic and advanced programming
opers want to hear about the JavaScript ecosystem. integrated with some database, such as Oracle and
But the more I think about it, the more I think it MySQL, as well as other programming languages.
would be a disservice not to cover JavaScript. Theres a
ine line between focusing on one thing and pretend- Marcos Andr Pisching
ing everything else doesnt exist. Professor de Informtica no Campus Lages do IFSC
Thats especially true when JVM-focused lan- Brazil

06
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//letters to the editor /
Editor Andrew Binstock responds: All told, the responses that, in turn, refer to multiple settings.gradle iles.
were more than 75 percent in favor of inclusion of The only way you would be referring to multiple
JavaScript on a regular basis. Based on this, well begin settings.gradle iles is if youre working with mul-
regular coverage of it in the next few issues. In the mean- tiple projects, even multiple multimodule projects.
time, a JavaScript article that was scheduled long ago is However, each project, whether a standalone project or
included in this issue. As we move forward, well be care- a multimodule project, only ever has a single settings
ful to keep in mind the recommendation of reader William .gradle ile.
McKenzie, who upon reassurance that JavaScript would not In addition, the text makes it seem like this new
come to dominate the content, kindly replied: That sounds approach of Kobalt is the only one that makes it pos-
appropriate to me. I love [Java Magazine] and dont want sible to deine multiple projects in one build ile.
it to lose itself. This is also possible in Gradle, and its quite common.
I certainly think its likely that Kotlin is going
Blockchain Blockage to be the main scripting language for Gradle
I liked the article Blockchain: Using Cryptocurrency (Kobalt will likely contribute ideas for that), but its
with Java, in the January/February 2017 issue, but on important to be accurate and fair in comparisons
page 44 the call of the method of existing procedures.
David Michael Karr
Greeter.deploy(web3j, credentials,
BigInteger.ZERO, new Utf8String("...")) Author Cdric Beust responds: You are correct that most
projects usually have one settings.gradle ile, but that ile is
is not complete because you need to set the gasLimit. pretty much the only way to have multiple modules. Here
What is the value of the gasLimit when the gasPrice is the typical way to do this from Gradles project itself.
is set to zero?
Elton DePaula Contact Us
We welcome comments, suggestions, grumbles, kudos,
Author Conor Svensson responds: Its best if you refer to article proposals, and chocolate chip cookies. All but
the accompanying code in the GitHub repository. You can the last two might be edited for publication. If your
see the correct values to use at this link. If you have any note is private, please indicate this in your message.
further questions, you can also join the web3j community Please write to us at javamag_us@oracle.com. For
on Gitter to get assistance. other ways to reach us, see the last page of this issue.

Being Fair to Gradle Builds


In his article on build tools (The Design and Con-
struction of Modern Build Tools), in the January/
February 2017 issue, Cdric Beust wrote, With Gradle,
you need to manipulate multiple build.gradle iles
07
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//events /
JavaLand gies, frameworks, and tech-
MARCH 2830 niques. Past presentations
BRHL, GERMANY have included Introduction to
This annual conference fea- Reactive Applications, Reactive
tures more than 100 lectures Streams, and Options for the
on subjects such as core Java JVM, as well as Microservice
and JVM languages, enter- Standardization.
prise Java and cloud tech-
nologies, IoT, front-end and JAX DevOps
mobile computing, and much APRIL 3 AND 6, WORKSHOPS
more. Scheduled presenta- APRIL 4 AND 5, CONFERENCE
tions include Multiplexing LONDON, ENGLAND
and Server Push: HTTP/2 This event for software
in Java 9, The Dark and experts features in-depth
Light Side of JavaFX, knowledge of the latest tech-
JDK 8 Lambdas: Cool Code nologies and methodologies
that Doesnt Use Streams, for lean businesses. The focus
Migrating to Java 9 Modules, is on accelerated delivery
and Java EE 8: Java EE cycles, faster changes in func-
Security API. tionality, and increased quality
in delivery. Conference tracks
OReilly Software include agile and company
Architecture Conference culture, cloud platforms, con-
GREAT INDIAN DEVELOPER SUMMIT APRIL 23, TRAINING tainer technologies, continu-
APRIL 2528 APRIL 35, TUTORIALS ous delivery and automation,
BANGALORE, INDIA AND CONFERENCE microservices, and real-world
The Great Indian Developer Summit (GIDS), now in its 10th year, ofers NEW YORK, NEW YORK case studies. The conference
four days of content grouped by theme. April 26 focuses on Java and This event promises four is preceded and followed by
JVM languages. Other days focus on web, mobile, DevOps, and big data. days of in-depth professional a day of workshops. Theres
Register for each day separately. training that covers software also a two-in-one conference
architecture fundamentals; package that provides free
real-world case studies; and access to a parallel conference,
the latest trends in technolo- JAX Finance.

PHOTOGRAPH BY AMITH NAG PHOTOGRAPHY/GETTY IMAGES 09


ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// MARCH/APRIL 2017
//events /
and Oice, examines all aspects development models, and DevOps.
of the smart home or oice: con- Workshops are ofered on the
trol of lighting, temperature con- day preceding and the day follow-
trol, appliances, and security locks ing the conference. (No English
for gates and doors. The Things page available.)
Networka global community
whose mission is to build a global Devoxx UK
IoT data networkis hosting its MAY 1112
popular hackathon at the confer- LONDON, ENGLAND
ence again this year. Devoxx returns to the UK with a
focus on Java, web, mobile, JVM
Java Day Istanbul 2017 languages, architecture, big data,
MAY 6 and security. Attracting more than
ISTANBUL, TURKEY 1,200 attendees, the conference
With the slogan By developers, includes more than 120 sessions,
for developers, this conference with 50-minute conference ses-
organized by the Istanbul Java sions, three-hour hands-on labs,
User Group explores Java, web, and many quickie presentations.
mobile, big data, cloud, DevOps,
and more. It also provides the Riga Dev Days 2017
Devoxx France topics ranging from web security opportunity for developers to MAY 1517
APRIL 5, WORKSHOPS to cloud computing. (No English network with tech companies RIGA, LATVIA
APRIL 67, CONFERENCE page available.) and startups. The biggest tech conference in
PARIS, FRANCE the Baltic States, this three-day
Devoxx France presents work- IoT Tech Day 2017 JAX 2017 event is a joint project of Google
shops, tutorials, and keynotes APRIL 19 MAY 911, CONFERENCE Developer Group Riga, Java User
from prestigious speakers, fol- UTRECHT, THE NETHERLANDS MAY 8 AND 12, WORKSHOPS Group Latvia, and Oracle User
lowed by a cycle of eight mini Machine learning and AI, secu- MAINZ, GERMANY Group Latvia. By and for software
conferences every 50 minutes. rity, wearables, and other smart More than 200 internationally developers, Riga Dev Days focuses
You can build your own calendar technologies are among the top- renowned speakers give practical on the most-relevant topics and
and follow the sessions as you ics investigated in Europes big- and performance-oriented lec- technologies for that audience
wish. Founded by developers for gest IoT-centered conference. One tures on topics such as Java, Scala, with more than 50 sessions on
developers, Devoxx France covers timely track, Connected Living Android, web technologies, agile Java, web, and cloud programming.

PHOTOGRAPH BY GUILHEM VELLUT/FLICKR 10


ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// MARCH/APRIL 2017
//events /
GeeCON 2017 ference in Eastern Europe. The tion, web, mobile, and interactive QCon New York
MAY 1719 annual conference focuses on developers, as well as engineers, JUNE 2628, CONFERENCE
KRAKOW, POLAND Java technologies for application architects, and UI/UX designers. JUNE 2930, WORKSHOPS
The GeeCON conference focuses development. This year ofers ive Training days and tutorials round NEW YORK, NEW YORK
on Java and JVM-based tech- tracks and more than 50 speak- out the conference experience. QCon is a practitioner-driven con-
nologies, with special attention ers with an emphasis on practical ference for technical team leads,
to dynamic languages such as experience and development of EclipseCon 2017 architects, engineering directors,
Groovy and Ruby. More than 80 real projects. Topics include mod- JUNE 20, UNCONFERENCE and project managers who inlu-
conference sessions cover topics ern approaches in the develop- JUNE 2122, CONFERENCE ence innovation in their teams.
such as enterprise architectures, ment of distributed, highly loaded, TOULOUSE, FRANCE The conference covers many dif-
design patterns, distributed com- scalable enterprise systems with EclipseCon is all about the Eclipse ferent developer topics, frequently
puting, software craftsmanship, Java, among others. ecosystem. Contributors, adopt- including entire Java tracks.
mobile, and more. ers, extenders, service provid-
jPrime ers, consumers, and business and JCrete
J On The Beach MAY 3031 research organizations gather to JULY 1621
MAY 17, WORKSHOPS SOFIA, BULGARIA share their expertise. The two- KOLYMBARI, GREECE
MAY 1819, TALKS jPrime is a relatively new con- day conference is preceded by an This loosely structured uncon-
MALAGA, SPAIN ference, with two days of talks Unconference gathering. ference involves morning ses-
JOTB is an international rendez- on Java, JVM languages, mobile sions discussing all things Java,
vous for developers interested in and web programming, and best Devoxx Poland combined with afternoons spent
big data technologies. JVM and practices. The event is run by the JUNE 2123 socializing, touring, and enjoy-
.NET technologies, embedded and Bulgarian Java User Group and KRAKOW, POLAND ing the local scene. There is also a
IoT development functional pro- provides opportunities for hack- For three days, 100 Java Cham- JCrete4Kids component for intro-
gramming, and data visualization ing and networking. pions, evangelists, and thought ducing youngsters to program-
will all be discussed. Scheduled leaders inspire 2,500 developers ming and Java. Attendees often
speakers include longtime Java OReilly Fluent Conference from 20 diferent countries at bring their families.
Champion Martin Thompson and JUNE 1920, TRAINING this installment of the popular
Director of Developer Experience JUNE 2022, TUTORIALS Devoxx conferences. Tracks on berConf
at Red Hat Edson Yanaga. AND CONFERENCE server-side Java, cloud and big JULY 1821
SAN JOSE, CALIFORNIA data, JVM languages, web and DENVER, COLORADO
JEEConf Fluent ofers practical train- HTML5, and more are on ofer. berConf 2017 will be held at the
MAY 2627 ing for building sites and apps Hacking and networking round Westin Westminster in down-
KIEV, UKRAINE for the modern web. This event out the experience. town Denver. Topics include
JEEConf is the largest Java con- is designed to appeal to applica- Java 8, microservice architectures,

11
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// MARCH/APRIL 2017
//events /
Docker, cloud, security, Scala, JavaOne
Groovy, Spring, Android, iOS, OCTOBER 15 Oracle Code Events
NoSQL, and much more. SAN FRANCISCO, CALIFORNIA Oracle Code is a free event for
Whether you are a seasoned
developers to learn about the
JavaZone 2017 coder or a new Java programmer,
SEPTEMBER 12, WORKSHOPS latest development technologies,
JavaOne is the ultimate source of
SEPTEMBER 1314, CONFERENCE technical information and learn-
practices, and trends, including
OSLO, NORWAY ing about Java. For ive days, Java containers, microservices and API
JavaZone is a conference for developers gather from around applications, DevOps, databases,
Java developers created by the the world to talk about upcom- open source, development tools and low-code platforms,
Norwegian Java User Group, ing releases of Java SE, Java EE, machine learning, AI, and chatbots. In addition, Oracle
javaBin. The conference has and Java FX; JVM languages; new Code includes educational sessions for developing soft-
existed since 2001 and now con- development tools; insights into ware in Java, Node.js, and other programming languages
sists of around 200 speakers and recent trends in programming;
and frameworks using Oracle Database, MySQL, and
7 parallel tracks over 2 days, plus and tutorials on numerous related
an additional day of workshops NoSQL databases.
Java and JVM topics.
beforehand. You will be joined by
approximately 3,000 of your fel- Are you hosting an upcoming
US AND CANADA ASIA PACIFIC
low Java developers. Included in Java conference that you would
MARCH 27, Washington DC MAY 10, New Delhi, India
the ticket price is a membership like to see included in this cal- APRIL 18, Toronto, Ontario, MAY 18, Tokyo, Japan
in javaBin. endar? Please send us a link Canada JULY 14, Beijing, China
and a description of your event JUNE 22, Atlanta, Georgia JULY 18, Sydney, Australia
NFJS Boston at least 90 days in advance at AUGUST 4, Bangalore, India
SEPTEMBER 29OCTOBER 1 javamag_us@oracle.com. Other EUROPE AND MIDDLE EAST
BOSTON, MASSACHUSETTS AUGUST 30, Seoul, South
ways to reach us appear on the APRIL 20, London, England
Since 2001, the No Fluf Just Stuf Korea
last page of this issue. APRIL 24, Berlin, Germany
(NFJS) Software Symposium Tour
APRIL 28, Prague, Czech LATIN AMERICA
has delivered more than 450
Republic JUNE 27, So Paulo, Brazil
events with more than 70,000
attendees. This event in Boston MAY 22, Moscow, Russia JUNE 29, Mexico City, Mexico
covers the latest trends within JUNE 6, Brussels, Belgium
the Java and JVM ecosystem, JULY 11, Tel Aviv, Israel
DevOps, and agile development
environments.

12
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// MARCH/APRIL 2017
//review /
REFACTORING TO MODERN JAVA: GETTING THE MOST FROM JAVA 8
(LiveLessons video)
By Trisha Gee
Pearson/InformIT LiveLessons

Although this column regularly developers, and if you dont know fully understand her point because
focuses on books, in this issue we the syntax for lambdas or under- youre still trying to catch up with
look at a training video sold com- stand what functional interfaces are, what she said 15 seconds ago. My
mercially by the InformIT divi- youll quickly ind yourself stum- other complaint is that Gee lets the
sion of Pearson, the company bling as you try to follow along. In IDE (IntelliJ) ind refactorings and
behind Addison-Wesley and other this sense, the video is tremen- implement them, so theyre too
respected imprints. dously satisfying precisely because it often done in the blink of an eye.
This video is a downloadable avoids introductory material. That is, She helpfully shows before and
product (priced around US$100) that you must know Java 8 going in. after code in some examples, but
consists of DRM-free MP4 iles. All After presenting the refactor- it would be easier to follow if we
told, they represent several hours of ings, Gee cleverly spends a signii- saw her make the changes manu-
high-quality instruction. I watched cant amount of time assessing the ally rather than see code instantly
the videos on my desktop and performance impact of the code transformed by a keystroke. In this
opened the window to ill the screen changes. She does this using the Java regard, although Gee claims that
so that I could read the code and see Microbenchmarking Harness (JMH) all the refactorings are available in
the changes easily. and shows that some but not all other IDEs, I found that some were
The lecturer is Java Champion refactorings improve performance. not available in NetBeans. I did not
Trisha Gee, who is a frequent and Its kind of a fascinating process verify Eclipse.
well-respected speaker at confer- to watch. Overall, my reservations are
ences. Here she presents a variety Despite the high production about details, not about content,
of refactorings that are available values of the video and Gees prac- which is uniformly highly instruc-
because of the innovations intro- ticed delivery (she never stutters tive and full of immediately appli-
duced in Java 8. Gee focuses primar- or repeats and easily moves back- cable information. Gee has posted a
ily on lambdas, streams, Optionals, ward and forward through subjects less intense and shorter version of
and several lesser features. To follow to explain a given topic), the video this video on YouTube, so you can
along, you will need to understand has a few aspects that could bear sample the goods before buying
these features. The video is squarely improvement. At times Gee speaks this. I expect youll be as impressed
aimed at intermediate to advanced very fast, which makes it hard to as I am.Andrew Binstock
14
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// MARCH/APRIL 2017
UI TOOLS

Building User Interfaces


SCRIPTING JAVAFX 17 | DRAG-AND-DROP DESIGN 24 | MVC 1.0 30 | JAVASCRIPT UI WITH ORACLE JET 40

D
epending on how your genes are wired, you either love build- FXML. Scene Builder was originally an Oracle tool that was released to open
ing UIs or ind it to be the most annoying task in program- source and taken over by Gluon, which has been maintaining it ever since.
mingsurpassing even ixing Aunt Thelmas printer because, Front ends to web applications have their own unique needs, and we
you know, youre the computer wizard. Regardless of your cover those too in a pair of articles: one on MVC 1.0 (page 30), a web
view of UI development, there can be no denying the now framework that at one time was considered for inclusion in Java EE 8,
paramount importance of the UI or, put more lavishly, the UX (that is, and another on a JavaScript toolkit, Oracle JET (page 40), which provides
the user experience). Even the among many resources a large
most jaded developers recognize palette of useful controls with
the need for attractive apps with easy ways to wire them together.
intuitive interfaces. As a result, If UIs are not your favorite
most of us are now accustomed topic, we have you covered with
to designers sitting in on product a detailed discussion (page 46)
and app creation and providing of using MQTT, one of the main
feedback and direction as the messaging protocols in IoT.
project unfolds. Youll also ind an interesting
Coding UIs used to be an awful dive (page 60) into how the up-
chore, with endless minute and-coming build tool Gradle
adjustments having to be con- uses libraries. And inally, we
stantly recoded. Fortunately, revisit a topic weve covered
JavaFX greatly facilitated UI before: compact proiles in
construction by scripting it with Java 8 (page 56). In addition, of
FXML, which is discussed in our course, we ofer our usual quiz
irst article (page 17). Our sec- this time with the inclusion of
ond article (page 24) explores questions from the entry-level
the drag-and-drop design tool examas well as plenty of other
Scene Builder, which can generate goodness. Enjoy!
ART BY BOB MORRIS
16
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /

Enhanced FXML Using


the FXMLLoader
Gain greater flexibility in defining JavaFX UIs declaratively by exploiting
ANDRS ALMIRAY the FXML loader mechanism.

T he JavaFX UI toolkit delivers a refreshing and modern


set of APIs that can be used to build desktop and mobile
applications that target the JVM. Similar to its predecessor,
You have probably seen FXML before, but in case you
havent, heres a quick sample. The following code snippet
deines a grid in which six UI elements are placed in a
Swing, JavaFX provides a standard widget set, as well as the two-column layout:
means to extend this widget set with custom components
and new behavior. sample/app.fxml
JavaFX also adds new capabilities such as property bind- <?xml version="1.0" encoding="UTF-8"?>
ings, styling support via CSS, and a UI description format <?import javafx.scene.control.Button?>
named FXML. As the name implies, its an XML-based format <?import javafx.scene.control.Label?>
that enables developers to deine user interfaces in a declara- <?import javafx.scene.control.PasswordField?>
tive way, as opposed to deining interfaces by procedural <?import javafx.scene.control.TextField?>
meansthat is, by directly using the JavaFX APIs. <?import javafx.scene.layout.GridPane?>
The following beneits are some of the advantages of <GridPane>
choosing FXML over the programmatic API: <Label text="Username:"
FXML is a hierarchical format. The JavaFX SceneGraph is also GridPane.columnIndex="0" GridPane.rowIndex="0"/>
a hierarchical structure given that it represents the UI ele- <TextField
ments as a tree data structure. Every node in the SceneGraph GridPane.columnIndex="1" GridPane.rowIndex="0"/>
relates to a graphical element, such as a button, label, or text <Label text="Password:"
ield. As a result, it is easier to visualize the component hier- GridPane.columnIndex="0" GridPane.rowIndex="1"/>
archy in FXML than in plain code. <PasswordField
FXML can be created on the ly if need be, allowing GridPane.columnIndex="1" GridPane.rowIndex="1"/>
dynamic UI elements to be added/created at speciic points <Button text="Cancel"
during the applications runtime. GridPane.columnIndex="0" GridPane.rowIndex="2"/>
In many cases, writing FXML results in shorter UI deinitions. <Button text="Login"
17
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
GridPane.columnIndex="1" GridPane.rowIndex="2"/> For now, you only need to tell FXMLLoader the location of the
</GridPane> FXML resource that you want to load. Its important to
remember that the action of creating UI elements and attach-
Figure 1 shows how the application looks when running. ing them to the SceneGraph must happen inside the UI thread
Note that, as in Java code, you must specify import state- (known as the FX application thread). Bad things can happen
ments for the types that are used in the FXML ile. These when you do not follow this rule. Fortunately, the base type
import statements serve as a hint to the FXML loading Application provides a basic lifecycle that ensures code can
mechanism thats in charge of interpreting the declarative be called inside such a thread. In this particular case, the
UI description and turning it into a proper SceneGraph with start method is guaranteed to be called inside the UI thread,
the UI elements in it. This loading mechanism is known as which means everything is OK.
FXMLLoader. Using FXMLLoader is straightforward, as shown by
the following code: Node Properties
If you look closely at the FXML snippet in the irst example,
sample/App.java youll see that the FXML nodes Label and Button deine a
package sample; text attribute. This attribute is in turn mapped to a JavaBean
property found in the matching type. Thus when FXMLLoader
import javafx.application.Application; instantiates the irst Label it encounters, it sets the labels
import javafx.fxml.FXMLLoader; text property to the exact value of the text attribute. In other
import javafx.scene.Scene; words, its as if FXMLLoader invoked the following code on
import javafx.stage.Stage; your behalf:

import java.net.URL; Label label = new Label();


label.setText("Username:");
public class App extends Application{ // insert label into SceneGraph
@Override
public void start(Stage stage) throws Exception { Thats quite a short snippet, and this functionality doesnt
URL fxml = getClass().getClassLoader() seem to be much of an advantage right now; however, take
.getResource("sample/app.fxml"); into consideration that UI elements may have several prop-
FXMLLoader fxmlLoader = new FXMLLoader(fxml);

stage.setScene(new Scene(fxmlLoader.load()));
stage.sizeToScene();
stage.show();
}
}
Figure 1. Login screen using FXML
18
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
erties that you might want to set. As you continue to deine You can use the Node type as the irst argument because its
more nodes and attributes, the beneits of FXML will become the supertype of all JavaFX UI elements. This allows GridPane
apparent. Its worth noting that the node type (Label, in this to work with any kind of UI element, both those coming from
case) must deine properties matching the JavaBeans conven- the standard widget set and those provided by third-party
tion, resulting in a pair of methods that can be used to query libraries. Youll note that the previous method deinitions
(the getter) and mutate (the setter) the property. The property take an integer as a second argument; however, the FXML
becomes invisible to FXMLLoader if either of these methods ile deines the corresponding values as literals. That works
is missing. This should be your irst clue to understanding because FXMLLoader is capable of applying type conversions.
why a particular FXML snippet doesnt work in the way you It does so for all basic types and for enums. One more con-
expectit could be that the property youre attempting to set cern would be storing the value in relation to the supplied
is not a properly deined JavaBeans property. node. Again, the JavaFX API comes to your aid because the
You might also be wondering about the additional prop- base type Node has a handy properties map that can be used
erties on all six elements that need to be speciied to use to store any kind of value, and thats precisely what these
GridPane as a namespace. These properties do not exist on methods do.
the target nodes themselves, yet they afect the nodes. You Armed with this new knowledge, you can create your
can verify the previous statement by changing the values of own synthetic properties. Synthetic properties are properties
columnIndex and rowIndex; depending on the new values, you that are not explicitly deined in the target type; rather,
might end up with a funny layout. they relate to the target type by external means, such as a
Whats going on then? As it turns out, these properties contextual dictionary. Suppose you had the requirement to
are deined by the GridPane class and not the target nodes. limit the number of characters a user may type into either
This is why the name of the class appears as a namespace. the Username or Password ield. You could create a new util-
These two properties happen to be deined as static methods ity class that deines a pair of methods that take a Node and
on the GridPane class, which means they are not JavaBeans a number, using the provided number as a limit. The utility
properties per se, but part of a convention that FXML class could look like this:
enables. As before, each property must have a getter and a
setter pair of methods. Additionally each method must have package sample;
the static modiier. One last part of the convention is that
the methods must take the target node as their irst argu- import javafx.scene.control.TextInputControl;
ment. This results in the following method deinitions found
in GridPane: public final class InputControlUtils {
private static final String LIMIT = " limit";
public static void
setColumnIndex(Node node, int index); public static void setMaxTextLimit(
public static int getColumnIndex(Node node); TextInputControl control, int maxLength) {
public static void setRowIndex(Node node, int index); control.getProperties().put(LIMIT, maxLength);
public static int getRowIndex(Node node); control.textProperty()
19
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
.addListener((ov, oldValue, newValue) -> { <?import javafx.scene.layout.GridPane?>
if (control.getText().length() > maxLength) { <?import sample.InputControlUtils?>
String s = control.getText() <GridPane>
.substring(0, maxLength); <Label text="Username:"
control.setText(s); GridPane.columnIndex="0" GridPane.rowIndex="0"/>
} <TextField
}); GridPane.columnIndex="1" GridPane.rowIndex="0"
} InputControlUtils.maxTextLimit="10"/>
<Label text="Password:"
public static int getMaxTextLimit( GridPane.columnIndex="0" GridPane.rowIndex="1"/>
TextInputControl control) { <PasswordField
Object value = GridPane.columnIndex="1" GridPane.rowIndex="1"
control.getProperties().get(LIMIT); InputControlUtils.maxTextLimit="10"/>
if (value instanceof Number) { <Button text="Cancel"
return ((Number) value).intValue(); GridPane.columnIndex="0" GridPane.rowIndex="2"/>
} <Button text="Login"
return -1; GridPane.columnIndex="1" GridPane.rowIndex="2"/>
} </GridPane>
}
There are two other features to be mentioned when deal-
Note that this code does not take into account any invalid ing with properties in FXML. The irst is the ability to
values (such as maxLength being equal or less than zero), deine the name of a default property, which allows you to
nor does it provide the means to unregister the listener if omit the property name when deining the hierarchy. The
the setMaxTestLimit method is called more than once with name of the property must be deined in code by apply-
the same target node. This code is for illustration purposes ing the @javafx.beans.DefaultProperty annotation to
and should not be used as is in production without the target type. Many of the UI elements in the stan-
additional tweaks. dard JavaFX widget set use this annotation. For exam-
Moving on, you only need to update the FXML deinitions ple, the javafx.scene.layout.Pane type, which is the
to look like this: base type for many widget containers, is annotated with
@DefaultProperty("children"). This allows you to write
sample/app.fxml FXML as shown in the previous example instead of this:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?> sample/app.fxml
<?import javafx.scene.control.Label?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.PasswordField?> <?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?> <?import javafx.scene.control.TextField?>
20
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
<?import javafx.scene.layout.GridPane?> this.top = top;
<GridPane> this.right = right;
<children> this.bottom = bottom;
<Label text="Username:" this.left = left;
GridPane.columnIndex="0" GridPane.rowIndex="0"/> }
<!-- more elements follow -->
</children> public Insets(@NamedArg("topRightBottomLeft")
</GridPane> double topRightBottomLeft) {
this.top = topRightBottomLeft;
FXML support in popular IDEs is so well integrated that this.right = topRightBottomLeft;
the IDEs can point out if theres a default property that can this.bottom = topRightBottomLeft;
be used instead of having it spelled out in the FXML ile. this.left = topRightBottomLeft;
Speaking of tooling, its worth mentioning that you can write }
FXML by hand, or you can use a free visual tool named Scene
Builder, which is described in the accompanying article on This use of annotations enables you to deine instances in
page 24. either of the following ways:
I should also mention that you have the ability to supply
additional hints to FXMLLoader when you are instantiating a <Insets top="10" right="10" bottom="10" left="10"/>
type. So far, Ive shown only types that follow the JavaBeans
conventions by providing a no-argument constructor. This is or
what FXMLLoader expects by default. However, sometimes you
might encounter a node that deines a constructor that takes <Insets topRightBottomLeft="10"/>
arguments. Without the ability to supply additional hints,
FXMLLoader would simply fail to instantiate the node. You can Thats all I can say about properties support in FXML for now.
help it by supplying a name for the constructor arguments Next, lets examine how to conigure the FXMLLoader itself,
as if they were regular properties. To do this, you use the using internationalization as an example.
@javafx.beans.NamedArg annotation. You must deine a name
for the argument, and you may deine a default value for it Configuring FXMLLoader for Internationalization
if the attribute is omitted in the FXML ile. Heres a concrete Many languages are spoken in the world today. As a devel-
example found in the standard JavaFX APIthe Insets class oper, you must take into account the target audience of the
deines the following constructors: applications you build. Sometimes users speak a diferent
language than you speak, so you must be ready to provide a
public Insets(@NamedArg("top") double top, version thats suitable for their needs.
@NamedArg("right") double right, JavaFX widgets are aware of the locale and other regional
@NamedArg("bottom") double bottom, settings exposed by the JVM, which results in widgets being
@NamedArg("left") double left) { rendered in right-to-left or left-to-right order depending
21
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
on the situation. But you cant say the same about the string You also must change the FXML ile to relect the keys of the
literals you add to the application. It would be great if you properties you just deined. The convention is to use % as a
could somehow externalize those literals and have the FXML preix to distinguish a key value from a literal value. Your IDE
iles refer to them. Fortunately, FXMLLoader has just what might even be able to suggest key completions.
you need to solve this problem. You may supply it a Resource
Bundle at construction time or set the bundle as a property <Label text="%username.label"
before loading FXML iles. You can create this ResourceBundle GridPane.columnIndex="0" GridPane.rowIndex="0"/>
in any way you see it. My little example, sample/App.java, <TextField
can be updated as follows: GridPane.columnIndex="1" GridPane.rowIndex="0"
InputControlUtils.maxTextLimit="10"/>
ClassLoader cl = getClass().getClassLoader(); <Label text="%password.label"
URL fxml = cl.getResource("sample/app.fxml"); GridPane.columnIndex="0" GridPane.rowIndex="1"/>
String resource = "sample/messages_en.properties" <PasswordField
InputStream is = GridPane.columnIndex="1" GridPane.rowIndex="1"
cl.getResourceAsStream(resource); InputControlUtils.maxTextLimit="10"/>
ResourceBundle bundle = <Button text="%action.cancel.label"
new PropertyResourceBundle(is); GridPane.columnIndex="0" GridPane.rowIndex="2"/>
FXMLLoader fxmlLoader = new FXMLLoader(fxml, bundle); <Button text="%action.login.label"
GridPane.columnIndex="1" GridPane.rowIndex="2"/>
You also deine the following pair of properties iles: one
using English (en) as the default locale and another using If you run the application again, you should see the same
German (de): visuals as in Figure 1. Now, change the code to load the
German version of the properties ile, and youll notice the
sample/messages_en.properties ile: application looks like Figure 2.
Great! These are the irst steps to get localization sup-
username.label=Username: port in an application. As mentioned earlier, you can create
password.label=Password: the ResourceBundle in many ways that are commonly used in
action.cancel.label=Cancel regular Java programming. A further step would be to make
action.login.label=Login

sample/messages_de.properties ile:

username.label=Benutzername:
password.label=Passwort:
action.cancel.label=Abbrechen
action.login.label=Anmeldung Figure 2. German login screen
22
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
the application react to locale changes at runtime. If you
choose to do this, youll need to ind a way to let the widgets
know that a change of locale has occurred and that the new
key values must be fetched again. Im afraid that FXMLLoader
alone is not enough, but you have all the basic blocks to
get started.

Conclusion The brightest minds in tech


FXML provides a quick and easy way to deine UIs declara-
tively. The tooling support (IDEs and SceneBuilder) is good
are coming to New York.
enough to get you started writing FXML with ease. Many of
the node types that you can use inside FXML are straight-
forward, because they follow the JavaBeans conventions. But
when they dont, theres still a way to use them with FXML
given that the format provides useful extensions and hints to
its loading mechanism, FXMLLoader. You can also conigure
localization concerns on widgets via FXML, enabling a wider
audience for your applications. In an upcoming article, Ill
examine the mechanism exposed by FXMLLoader and FXML
to further customize and bind the widgets deined in the
FXML ilefor example, features such as the fx:controller
attribute and the @FXML annotation. </article>

Andrs Almiray is a Java and Groovy developer and a Java Practical training in the tools, techniques,
Champion with more than 17 years of experience in software de- and leadership skills you need for the evolving
sign and development. He has been involved in web and desktop world of software architecture.
application development since the early days of Java. He is a true
believer in open source and has participated in popular projects April 2 5, 2017
such as Groovy, JMatter, Asciidoctor, and others. Hes a founding
member and current project lead of the Grifon framework, and he softwarearchitecturecon.com/ny
is the speciication lead for JSR 377.

learn more JAVA MAGAZINE READERS GET


20% OFF WITH CODE JAVA
Oracles tutorial on FXML
23
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /

Scene Builder:
The JavaFX UI Design Tool
The interactive UI design tool originally developed by Oracle continues to
JOHAN VOS advance in the open source community.

S cene Builder is a popular tool that enables developers to


create Java user interfaces (UIs) using an intuitive drag-
and-drop approach. It was initially created and maintained
How It Works
On the JavaFX code side, the FXMLLoader class loads an FXML
ile from the JAR containing the application ile or from the
by Oracle and open-sourced. Since March 2015, Gluon has classpath:
distributed the releases of Scene Builder for Mac, Linux, and
Windows systems. In that time, there have been more than FXMLLoader.load(getClass().getResource("FXML.fxml"));
400,000 downloads of the tool. Gluon continues to develop
Scene Builder. In this article, I discuss how to use the tool. The connection between your Java code and the UI elements
For readers familiar with Scene Builder from the days when that are declared in the FXML ile is made by a controller
Oracle distributed it, this will serve as both a refresher and class. This is a regular Java class that may contain annota-
an update. tions linking the UI elements to Java classes. This approach
separates the UI declaration from the behavior of the applica-
About Scene Builder tion, while still allowing the application to access the UI ele-
UIs for Java client applications can be created programmati- ments directly.
cally using JavaFX code, or declaratively, using FXML code. The loader will ind the name of the controller class, as
The declarative approach requires FXML, which is a for- speciied by fx:controller="your.package.name.FXML
mat based on XML and well documented by Oracle. While Controller" in the FXML ile. Then the loader creates an
it is possible to create complete UIs writing directly FXML instance of that class, in which it tries to inject all the objects
code, it is a tedious process. Fortunately, you can design a that have an fx:id tag in the FXML ile and are marked with
UI interactively using Scene Builder, which then translates the @FXML annotation in the controller class. Finally, when the
your UI into FXML that can be used together with other whole FXML ile has been loaded, the FXMLLoader will call the
JavaFX code. controllers initialize method.
In practice, many applications contain both JavaFX code Although the FXML ile can be edited within any IDE as a
and FXML code. The JavaFX APIs and the FXML constructs are regular XML ile, this practice is not recommended, because
PHOTOGRAPH BY
TON HENDRIKS designed to work together. the IDE provides only basic syntax checking and autocomple-
24
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
tion but not visual guidance. A better approach is to open the installing it on Windows. (This is a new feature available in
FXML ile with Scene Builder. Scene Builder 8.3.0.) Once you have installed Scene Builder,
open your IDE so you can set its location and you can open
Installing Scene Builder any FXML ile from your IDE:
You can install Scene Builder by downloading it. Make sure to On NetBeans, select Tools -> Options (or Preferences on

download the right version for your operating system. Then Mac) -> Java -> JavaFX, and click Browse to ind the main
follow the platform-speciic instructions for installing it in Scene Builder folder.
the default location, or select a custom location if you are On IntelliJ, select File -> Settings (or Preferences on Mac)

Figure 1. Adding containers and controls


25
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
-> Languages & Frameworks -> JavaFX, and browse for the If you want to have interactions between the FXML ile
application path. and your Java code, you need to specify the name of the con-
On Eclipse, select Window -> Preferences (or Preferences on troller class. This name should be added to the FXML ile in
Mac) -> JavaFX, and browse for the application path. the Controller panel. You open the Controller panel by click-
Whenever you have an FXML ile, you will be able to edit it ing the widget in the lower left corner.
with Scene Builder simply by right-clicking it and selecting If you want to access UI elements from your Java code (via
Open with Scene Builder. the controller class), you need to make sure the value provided
in the fx:id tag is exactly the same as the value of the @FXML
Creating a Basic Interface annotation for the corresponding ield in the controller class.
You can open an existing FXML ile with Scene Builder, or To make this easier for the developer, and to avoid typos,
you can open the Scene Builder application and create a new Scene Builder can generate a sample controller skeleton for
FXML ile. you. This sample controller is auto-generated Java code that
Creating a UI with Scene Builder is easy. You can drag and contains FXML-annotated ields for all UI elements that are
drop containers and controls to your view. Lets step through tagged with fx:id.
an example. You can easily copy the diferent nodes to the controller
To begin with, open Scene Builder, and select Start New by selecting View -> Show Sample Controller Skeleton. Click
Project from the Welcome menu. For mobile projects, a built- the Copy button, and on your IDE paste the content into the
in Gluon Mobile theme is set. If you want to create a regular controller class.
JavaFX project, you can do this by selecting the Modena Typical code will look like Listing 1.
theme from Preview -> JavaFX theme -> Modena (FX8).
Add a main container for your scene. In this example, I Listing 1. Sample Skeleton
will add a BorderPane. You can drag a BorderPane from the import com.gluonhq.charm.glisten.control.AppBar;
Containers left panel to the middle of the screen or to the import com.gluonhq.charm.glisten.control.Avatar;
hierarchy panel. import javafx.fxml.FXML;
In a similar way, you can drag and drop any JavaFX built- import javafx.scene.control.ScrollPane;
in container or control (see Figure 1, previous page). You can import javafx.scene.layout.StackPane;
use the Library Manager to include libraries containing cus-
tom controls. The online documentation can help with any- public class GluonFXMLSampe {
thing thats not intuitive.
A Hierarchy panel is available. It shows the hierarchy @FXML
of containers and controls. If you want to use containers private AppBar appBar;
and controls in your Java code, you need to tag them with
fx:id. This can be done in the Code right panel. This fx:id @FXML
tag is a very important concept, because it bridges the world private StackPane stackPane;
of the designer using Scene Builder with the developer code
in an IDE. @FXML
26
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
private ScrollPane scrollPane; You can easily add CSS to the scene by providing a CSS ile
that can be included using the Stylesheets option in the
@FXML Properties panel on the right. You can add inline styling also,
private Avatar avatar; by providing style rules to any node on the scene. You can
apply new or existing style classes to any node as well.
} Features related to layout, such as position, dimensions,
margin, padding, and transforms (translation, rotation,

Figure 2. Defining anchor pane constraints in the Layout panel


27
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
scaling, and so forth), can be set in the Layout right panel, as @FXML
shown in Figure 2. private HBox hBox;
At any moment, you can preview the created scene by
clicking Preview -> Show Preview in Window. A resizable private Label label;
dialog box with the designed scene will be shown. By resizing
it, you can make sure every node behaves as expected. public void initialize() {
label = new Label();
Integrate the Basic Interface in a Java App and Show It hBox.getChildren().add(label);
Once the FXML is ready, you can integrate it into your Java titledPane1.expandedProperty()
application by calling FXMLLoader to load it. Heres how: .addListener((obs, ov, nv) -> {
if (nv) {
public class GluonSceneBuilder extends Application { label.setText("TitledPane1");
}
@Override });
public void start(Stage stage) throws Exception { . . .
Parent root = FXMLLoader.load(getClass() }
.getResource("GluonFXML.fxml"));
In a controller class, you can annotate not only ields repre-
Scene scene = new Scene(root); senting controls with the @FXML annotation, but also meth-
stage.setScene(scene); ods. As an example, I deine the following event handler in
stage.show(); the controller:
}
} @FXML
void buttonClicked(ActionEvent event) {
In the controller class, you can add the required action han- label.setText("Button");
dlers and the response to the user interaction. You can create }
new controls as well, and combine them with those injected
by the FXMLLoader. Notice that for the controls you add pro- This event handler simply sets the text of the Label to
grammatically, you need to create new instances. This is "Button". Because the event handler annotated it with @FXML,
not needed for controls that are declared in the FXML ile, Scene Builder will ind it and can assign it to a corresponding
because the FXMLLoader already creates them for you. The action for a node.
code snippet below shows a piece of a controller class that
works with two controls: an HBox control deined in the FXML Integrate the Interface with Your Favorite IDE
ile, and a Label that is not created in the FXML ile. The HBox Scene Builder is a standalone application. When FXML is
instance does not need to be created in the controller class, being edited outside Scene Builder (by directly modifying it
but the Label instance does. in your IDE, for example), Scene Builder reacts to the changes
28
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
made in the FXML itself or in the CSS iles after those trols during design time. This ability makes it much easier to
changes are saved. Scene Builder also manages to ind the work on complex controls, such as controls that at runtime
controller and the diferent nodes annotated with @FXML. require connections to external resources and databases that
If you prefer to use Scene Builder fully integrated with are not available at design time. One of the most commonly
your preferred IDE, IntelliJ ofers this option by using the ver- requested functionalities is better integration with third-
sion of Scene Builder installed in your system. Note that not party libraries that are available via public repositories. In
all options are supported. For example, there is no support for the past, developers had to manually upload those libraries
menus, and custom controls are not allowed. in Scene Builder. Starting with Gluon Scene Builder 8.2, the
For Eclipse, there is no built-in integration, but there is Maven Central repository is fully supported, allowing search-
a Preview option. On Window -> Show View -> Other select ing, downloading, and installing for any third-party library
JavaFX -> JavaFX Preview. That option works like the Preview available in Maven Central or even private repositories. You
option on Scene Builder, and you can interact with it. In addi- can access these features by selecting the JAR/FXML Manager
tion, by toggling the Load controller button, it applies the option, as shown in Figure 3.
controller and works as if you were running the application Scene Builder then inspects those libraries, and the
embedded in the Preview panel. However, it doesnt work controls it inds in the libraries are added to the Custom left
with custom controls. panel so they can be easily included in the FXML ile.

Community Enhancements in Scene Builder Conclusion


Although most of the Scene Builder code was contributed by Scene Builder is a tool originally developed by Oracle that
Oracle, the end product is really a synergy between Oracle enables developers to create UIs using an intuitive drag-and-
and the JavaFX community. The code for Scene Builder is drop interface. Thanks to the @FXML annotation and the ability
now being maintained by Gluon, but it contains contributions to assign identiiers and event handlers to controls in Scene
from many individuals and companies in Builder, the worklow between Scene Builder and your JavaFX
the JavaFX community. application code is easy. </article>
As a consequence, many major and
minor bug ixes have been applied in Scene Johan Vos (@johanvos) started working with Java in 1995. He
Builder, and new functionality has been was part of the Blackdown team, porting Java to Linux. In 2015, he
added. As with any open source project, cofounded Gluon, which enables enterprises to create mobile Java
anyone can report a bug or submit a pull client applications leveraging their existing back-end infrastruc-
request with a proposed feature or ix. ture. Gluon received a Dukes Choice Award in 2015. Vos is a Java
Among the most recent improvements Champion and a member of the BeJUG steering group, the Devoxx
to Scene Builder are that it now works with
steering group, and the JCP. He is the lead author of Pro JavaFX 8
an optimized set of imports, and other
(Apress, 2014).
new features such as a design-time lag.
The design-time lag allows developers to
Figure 3. The JAR/FXML Manager menu provide diferent behavior for their con-
29
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /

MVC 1.0: A Fresh, New Framework


for Enterprise Apps
A look at a remarkably flexible framework that builds on JAX-RS
JOSH JUNEAU

A pplications can be built using several diferent design


architectures. Developers have come a long way from
developing web applications using a single JSP page and
Why MVC 1.0?
For many of years, the most popular MVC framework for use
with Java EE has been JavaServer Faces (JSF), which follows
embedding Java source code directly into the page. Main- the MVC architecture and cleanly separates each of the three
tenance on such applications was miserable, and they were categories. The JSF framework makes web application devel-
not much fun to develop. Nowadays, developers have learned opment easy, because it takes much of the guesswork out of
that it makes sense to separate code into diferent portions to the design and, thus, allows the developer to focus on the
promote easier maintenance and development. business logic. That said, JSF makes some assumptions for the
One of the most popular application design architectures developer and is not very lexible in some areas. For instance,
is model-view-controller (MVC). This architectural pattern JSF is very targeted with regard to scoping, and each request
separates logic into three distinct categories. The model per- follows a complex set of phases through which validation and
tains to the database and any code that is used to bind data; other tasks occur. JSF can be customized, but there are certain
the view is the code that is used to generate the front end; and ceremonies that must be followed in order to do so.
the controller pertains to the application business logic and One of the key features of JSF is the bundled component
intermediate code between the data and the web view. The architecture, which allows web components to be bundled
MVC 1.0 framework follows the MVC design architecture, and and made portable for other JSF applications. This abstracts
it puts the developer into the drivers seat for making low- the details of the JavaScript and CSS from the developer, so a
level design choices and developing custom web controls. tag can simply be placed into the view to render a fully imple-
MVC 1.0 was considered for inclusion in Java EE 8 (as mented component. JSF has a large ecosystem of component
JSR 371). Since that time, Oracle has instead sought to move libraries available, which provide many options.
control of the project to the community. In this article, I exam- MVC 1.0 does not contain any components, leaving the
ine this new framework and explain why I like it, even though view completely up to the developer. However, this design
there are many other great choices. I also develop an applica- does not mean options are not available, because MVC allows
tion from the ground up using MVC 1.0 in the NetBeans IDE, just about any view technology to be used to create a front
allowing you to follow along each step of the way. end. The new framework does not contain request phases,
30
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
because requests are handled completely by the implementa- ect site and deploy it along with your
tion of controller methods. Given that view options are abun- WAR ile to a valid container, such as An MVC 1.0
dant and the request/response is completely open to custom GlassFish 4.1. For the purposes of this application is
development, the MVC framework promises to deliver a very example, I deploy to the GlassFish 5
lexible web development option. Where JSF is component- nightly build, and I include Ozark
simply a JAX-RS
based and handles much of the session management for the 1.0.0-m02 and MVC API 1.0-edr2 application that
developer, MVC leaves the developer to create applications as dependencies in the POM ile of consists of one or
using just about any view technology, and it hands over full
control of the session management.
the project.
more resources
Server and Project annotated with
Building a Project with MVC 1.0 To get started, create a new NetBeans @Controller.
The MVC framework reference implementation, named Maven web application project, and
Ozark, was deined in JSR 371. This framework is layered on name it DukeIssueTracker. Once the
top of JAX-RS. If you are familiar with JAX-RS, you will ind it project has been generated, add the
easy to use. If you are not familiar with JAX-RS, you can learn required dependencies to the POM, as shown in Listing 1.
both MVC and JAX-RS reading this article, because they both Conigure the application to run on JDK 8 and the GlassFish or
function very much the same way. Payara server of your choice.
In this article, I walk through the development of the
Duke Issue Tracker application, illustrating the basics of the Listing 1.
MVC framework along the way. To follow along, you need to <dependency>
have a solid understanding of how Java EE applications are <groupId>javax.mvc</groupId>
built. I use NetBeans 8.2 here, which already provides sup- <artifactId>javax.mvc-api</artifactId>
port for MVC 1.0, but you can follow along with the IDE of <version>1.0-edr2</version>
your choice. <scope>provided</scope>
Duke Issue Tracker is used to create and view issues for </dependency>
Dukes application. The initial view of the application lists all <dependency>
of the open issues in the upper half of the UI and displays an <groupId>org.glassfish.ozark</groupId>
issue-creation form on the lower half. An Apache Derby data- <artifactId>ozark</artifactId>
base is used to store the data, and this article demonstrates <version>1.0.0-m02</version>
how to use JAX-RS web services and Enterprise JavaBeans <scope>provided</scope>
(EJBs) to read, create, and update data. </dependency>
MVC is not quite a production-ready framework. Even
though it is fairly developed at this point, it has not yet been Next, I have created a small set of tables that needs to be
completed, nor has it been released as part of any produc- installed into the local Apache Derby database or the database
tion application server. This means you will need to obtain of your choice. To do so, run the create.sql ile that is pack-
the Ozark reference implementation JAR ile from the proj- aged with the source code against the database.
31
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
The application requires a beans.xml Contexts and Listing 3.
Dependency Injection (CDI) coniguration ile to be placed package org.mvc.dukeissuetrackermvc;
within the WEB-INF folder. The beans.xml ile should con-
igure all beans to be automatically discoverable, as shown in import java.util.HashMap;
Listing 2. import java.util.Map;
import javax.mvc.security.Csrf;
Listing 2. import javax.ws.rs.ApplicationPath;
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" import javax.ws.rs.core.Application;
xmlns:xsi= // Optionally this configuration can occur within
"http://www.w3.org/2001/XMLSchema-instance" // the web.xml deployment descriptor
xsi:schemaLocation= @ApplicationPath("tracker")
"http://xmlns.jcp.org/xml/ns/javaee public class ApplicationConfig extends Application {
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" // Additional configuration code, if needed
bean-discovery-mode="all"> }
</beans>
Entity Classes and RESTful Client
The views for the application are placed inside the WEB- This application uses entity classes that are mapped to the
INF folder because MVC 1.0 searches for view iles there and database tables that have been generated for the Apache
because the contents of WEB-INF are protected by the con- Derby database. For the purposes of this application, I use the
tainer. Create a folder named views within WEB-INF in which JAX-RS client API to invoke RESTful web services that will
to place the view iles. For the purposes of this article, I use provide the data for the application. Use NetBeans wizards
Facelets for the view engine, but you can opt for JSP or other to easily generate entity classes from the database and the
view languages if you choose. RESTful application infrastructure.
An MVC 1.0 application is simply a JAX-RS applica- Once the entity classes and web services have been
tion that consists of one or more resources annotated with generated, create a service class that uses a JAX-RS client to
@Controller. Because the MVC framework is based upon read from the web services to obtain data. Create a class in
JAX-RS, application coniguration must provide the URL a new package named org.mvc.dukeissuetracker.service,
pattern that will be used to access the controller methods and name the class DukeIssueTrackerService. This class is
or JAX-RS resources. I create a new Java class in a pack- a CDI ApplicationScoped bean, and it creates a new JAX-RS
age named org.dukeissuetrackermvc.config, and I name client in a method annotated with @PostConstruct so that
the class ApplicationConfig. The class should extend the the client is generated when the class is constructed. Once
javax.ws.rs.core.Application class. I annotate the class the client is created, it will be used to load the data from the
with @ApplicationPath("tracker") to indicate that tracker RESTful web service into a locally deined list of DukeIssues
should be applied to the end of the application path URL to objects. The full listing (due to its length, available from Java
access RESTful or MVC resources. Listing 3 contains the com- Magazines download area) contains the complete source code
plete code for this class. for the DukeIssueTrackerService class, which also includes
32
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
accessor methods that make the but it is also possible for the return type to be declared via the
JAX-RS client available to the rest of A controller class @Produces annotation.
the application. is instantiated The code in Listing 4 demonstrates a simple controller
class, which navigates to the issues.xhtml view when the
Controllers
and initialized URL http://localhost:8080/DukeIssueTracker/tracker/
Controllers are responsible for han- for each request, issues is used.
dling web requests and responses for so there is no state
an MVC application. In other words,
they bind the view to the data model
saved in between Listing 4.
@Path("/issues")
and provide the necessary business requests. @Controller
logic for the application. A controller public class IssuesController {
class is a CDI-managed plain old Java @GET
object (POJO) that contains both a public String displayIssues() {
@Path and a @Controller (javax.mvc.annotation.Controller) //Perform processing and set Model
annotation at the class level, or has at least one method return "issues.xhtml";
annotated with @Path and @Controller. It should also have at }
least one method annotated as a resource method, using @GET, }
@PUT, or @POST.
A controller is very much the same as a JAX-RS class, The return type of a controller method determines how
except that it uses diferent annotations to signify that the the request is processed. Various return types are possible,
controller class or method is used for MVC rather than for including Viewable, JAX-RS Response, Redirect, and String.
JAX-RS. If @Controller is placed at the class level, all meth- As mentioned before, the default return type is String, but
ods of the class must be used as MVC controllers. However, a the @View annotation can also be used to indicate the view to
controller class can be made hybrid by placing the annotation which the browser should be directed after processing. If it is
at the method level. Hybrid classes can contain both MVC and placed on a method, the return type should be void. Redirects
JAX-RS resource methods. are possible via the use of the JAX-RS Response objects
A controller class is instantiated and initialized for each seeOther() method, or the client redirect preix (return
request, so there is no state saved in between requests. To redirect:see/here).
save state or data to display in views, you must use models, Building the controller. I now create a class in a new org
which I cover in the next section. .dukeissuetrackermvc.web package named IssuesController.
The @Path annotation is used to determine which con- This class is annotated with @Controller, and it contains each
troller class and method is invoked when the URL including of the issue tracker resource methods.
the indicated pattern is navigated to from within a browser. Next, I create a method annotated with @GET (from
The return type of a controller method returns the String javax.ws.rs.GET) that will be used for retrieving all active
name of the view to which the browser will navigate upon issues in the tracker. I name the method displayIssues()
return. The default return type of a controller is text/html, and provide a return type of String. The @GET annotation is
33
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
used to denote a method that returns data to the view. In this }
case, the database will be queried using the JAX-RS client, return issue;
which invokes the RESTful endpoint to obtain the issues and }
stores them in a request-scoped CDI bean named IssuesBean
(see Listing 5). /**
* @param issue the issue to set
Listing 5. */
@Named public void setIssue(Issue issue) {
@RequestScoped this.issue = issue;
public class IssuesBean { }

private Issue issue; }

/** Listing 6 shows the entire code, this far, for the
* @return the issueList IssuesController class.
*/
public List<DukeIssues> getIssueList() { Listing 6.
return issueList; @Controller
} @Path("/issues")
public class IssuesController {
/**
* @param issueList the issueList to set @Inject
*/ private DukeIssueTrackerService
public void setIssueList( dukeIssueTrackerService;
List<DukeIssues> issueList) {
this.issueList = issueList; @Inject
} private IssuesBean issuesBean;

private List<DukeIssues> issueList; @GET


public String displayIssues(){
/** issuesBean.setIssueList(
* @return the issue dukeIssueTrackerService.getIssueList());
*/ return "issues.xhtml";
public Issue getIssue() { }
if(issue == null){ }
issue = new Issue();
34
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
The issues.xhtml view will be displayed in the browser after In the case of a CDI bean, the name of the bean or the value
the IssuesBean is loaded with data. provided to the @Named annotation is used to reference the
data within a view.
Models
The model of the application refers to the data binding Views
between the data store and the application logic. In the case The view pertains to the presentation layer of the applica-
of MVC 1.0, data can be made available to the application tion or the web views. The MVC framework supports two
controller, and subsequently to the views, by the injection standard view engines out of the boxJSP and Facelets
of a standard javax.mvc.Models map or via CDI beans. The although others are available. You can also create a new view
preferred technique to make data available is via CDI-based engine to support any view technology that is not already
models, which is the technique I use here. However, all MVC covered by generating a view engine that implements the
1.0 implementations support the Models instance as well. javax.mvc.engine.ViewEngine interface. A view engine is
The Models map allows data objects to be made avail- used to locate and load views, prepare required models, and
able to the views via a series of key/value pairs in the render the views back to the client. This application uses the
Models<String, Object> map. Much like a standard HashMap, Facelets view engine, along with PrimeFaces UI components.
the key can be used to access the object, which is the value Building the view. I create a folder within the WEB-INF folder
of the map. In an MVC 1.0 view, the key can be used to obtain and name it views. All the views for the application are placed
access to the data that has been placed into the Models object. within this folder, because this is the place where the frame-
In the following case, the data would be available via the view work searches for view iles. Next, I create a new Facelet view
by referencing the dukeIssues key: named issues.xhtml within the newly generated folder.
Facelets is not enabled by default, so to enable it, a web
.xml deployment descriptor or a faces-conig.xml ile must
@Inject be created for the application. Once that is generated, add
private Models models; the coniguration shown in Listing 7 to enable the Facelets
view engine.
public String displayIssues(){
Listing 7.
models.put("dukeIssues",data); <servlet>
return "issues.xhtml"; <servlet-name>Faces Servlet</servlet-name>
} <servlet-class>
javax.faces.webapp.FacesServlet
The default technique, CDI-based models, relies upon </servlet-class>
the generation and proper scoping of CDI beans to hold <load-on-startup>1</load-on-startup>
data that will be made available to views. IssuesBean, </servlet>
shown in Listing 5, is used by DukeIssueTracker to hold the <servlet-mapping>
List<DukeIssues> object and make it available to the views. <servlet-name>Faces Servlet</servlet-name>
35
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
<url-pattern>*.xhtml</url-pattern> shows an abbreviated form of the completed class. Once it
</servlet-mapping> is created, the Issue class is passed as a parameter to the
createIssue() method, and it is annotated with @BeanParam to
I open the newly created issues.xhtml ile and add the denote that parameter ields are contained within the class.
markup contained in Listing 8. (Due to its length, Listing 8
should be downloaded from Java Magazines download area Listing 9.
or from the projects GitHub repository, which is shown in the import java.math.BigDecimal;
links at the end of this article.) import javax.validation.constraints.Size;
By taking a look at the code, you can see that I can use import javax.ws.rs.FormParam;
the CDI bean containing the issues by referencing it via public class Issue {
issuesBean.issueList, as shown here:
@FormParam(value="id")
<p:dataTable id="issueTable" private BigDecimal id;
value="#{issuesBean.issueList}"
var="issue" @FormParam(value="status")
emptyMessage="No issues found"> private String status;

Finishing Up @FormParam(value="priority")
Ive now built the irst part of the application successfully. private int priority;
That is, if the application is deployed and the URL http://
localhost:8080/DukeIssueTracker/tracker/issues is vis- @FormParam(value="requestorFirstName")
ited, the displayIssues() method in IssuesController is private String requestorFirstName;
invoked, and the issues.xhtml view is rendered, displaying
the list of issues. The form to submit a new issue has not yet @FormParam(value="requestorLastName")
been attached to the IssuesController, so that needs to be private String requestorLastName;
done next.
Looking at the markup in issues.xhtml, a form is @FormParam(value="requestorEmail")
used to make submissions to http://localhost:8080/ private String requestorEmail;
DukeIssueTracker/tracker/issues/create, so a resource
method annotated with @Path("/create") must be added @Size(max = 150)
to IssuesController. I name the method createIssue and @FormParam(value="subject")
provide a String return type. The MVC framework uses the private String subject;
@FormParam annotation to bind HTML values to Java ields, just
like JAX-RS. Therefore, I create a new Java class named Issue @Size(max = 2000)
within the org.mvc.dukeissuetracker.web package, and cre- @FormParam(value="description")
ate ields to map against the issue-creation form. Listing 9 private String description;
36
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
... public String createItem(@BeanParam Issue form) {
//Accessor methods DukeIssues entity = new DukeIssues();
... entity.setId(new Long(
} dukeIssueTrackerService.getIssueList().size() + 1));

To implement the creation, a DukeIssues object should entity.setDescription(form.getDescription());


be instantiated within the createIssue() method of entity.setSubject(form.getSubject());
IssuesController, and the ields should be populated with DukeUser user = new DukeUser();
those ields from the Issue class. Corresponding DukeUser, user.setId(Long.valueOf(
DukePriority, and DukeStatus objects should also be instan- dukeUserFacade.count()+1));
tiated and populated accordingly. Finally, a DukeIssuesFacade user.setEmail(form.getRequestorEmail());
EJB createItem() method is called upon to persist the new user.setFirstName(form.getRequestorFirstName());
record. Listing 10 shows the source code for the method. user.setLastName(form.getRequestorLastName());
entity.setRequestor(user);
Listing 10. DukePriority priority = new DukePriority();
@POST priority.setId(Long.valueOf(
@Path("/create") dukePriorityFacade.count()+1));
@Controller priority.setPriority(form.getPriority());
entity.setPriority(priority);
DukeStatus status = new DukeStatus();
status.setId(Long.valueOf(
dukeStatusFacade.count()+1));
status.setStatus("OPEN");
entity.setStatus(status);
// Create record
dukeIssuesFacade.create(entity);
// Initialize issue list
dukeIssueTrackerService.setIssueList(null);
issuesBean.setIssueList(
dukeIssueTrackerService.getIssueList());

return "issues.xhtml";

Figure 1. Duke Issue Tracker main view The inal product should look like Figure 1.
37
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
Validation Listing 11.
Validation can be performed in several ways. Bean valida- import javax.inject.Inject;
tion is performed within the Duke Issue Tracker, because import javax.mvc.Models;
the ields of the Issue class are annotated with suitable bean import javax.ws.rs.core.Response;
validation annotations. During the creation of an issue, if a import javax.ws.rs.ext.ExceptionMapper;
ield does not pass validation requirements speciied in the import javax.ws.rs.ext.Provider;
bean validation constraints, the creation will fail. Annotating
a resource method argument as @Valid triggers the validation @Provider
of the bean on every form post. public class GenericExceptionMapper implements
However, controller methods can be executed even if ExceptionMapper<Exception> {
validation errors are found, as long as they are declared as
capable of handling the errors. The javax.mvc.binding @Inject
.BindingResult can be injected into a controller class to private Models models;
indicate that they are capable. The BindingResult provides
detailed information regarding any validation errors that are @Override
encountered. Therefore, custom validation algorithms can be public Response toResponse(Exception exception) {
coded into the resource methods if needed. models.put("message", exception.getMessage());

Exception Handling return Response.status(


Exceptions can be handled on a case-by-case basis using Response.Status.BAD_REQUEST)
standard try/catch methodology. Often, returning a JAX-RS .entity("/WEB-INF/error.xhtml")
Response object with an error codeas shown belowis .build();
the best way to provide the user with information regarding }
the exception: }

Return Response.status( Listing 11 also demonstrates a clean way of adding messages to


Response.Status.BAD_REQUEST) the Models map to display within the view.
.entity("error.xhtml").build();
Security
It can become cumbersome if the same exception occurs MVC 1.0 controllers are required to support cross-site request
multiple times in an application. In such cases, a global forgery (CSRF) validation of tokens. The Csrf object can be
exception handler can be created by generating a class that injected via the MvcContext type or via #{mvc.csrf} within
implements the javax.ws.rs.ext.ExceptionMapper class. expression language (EL). A form can be protected by using
Listing 11 demonstrates a global exception handler for java EL to embed a Csrf object into a form, and it will be vali-
.lang.Exception. dated upon submission. The HTTP header can also be used to
propagate the Csrf object. Automatic validation is enabled by
38
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
setting the property CsrfOptions.IMPLICIT, or manual Observers can be used for logging or other work that must
validation can be conigured by setting the property be done when a particular event occurs. An observer can be
CsrfOptions.EXPLICIT and annotating resource methods conigured by using the @Observes annotation on a resource
with @CsrfValid. method parameter, followed by the CDI event to observe.

Additional Items public void onBeforeProcessView


There are several ways to pass parameters to resource (@Observes BeforeProcessViewEvent e) {
methods, and this article covered only @FormParam. Other // do some work
techniques are the use of query and path parameters. A }
query parameter is passed to the method at the end of the
URL using the following notation: Note that CDI observers are ired in a synchronous manner, so
long-running tasks should not be handled within an observer.
/controller?param1=value&param2=value
Conclusion
Path parameters are passed to the resource method as part The MVC 1.0 framework provides a very lexible solution,
of the URL using the following notation: worthy of serious consideration for enterprise apps. There are
numerous excellent posts on MVC 1.0, and I recommend per-
/controller/param1/param2 forming web searches to read the bevy of content and exam-
ples already available on this new framework. </article>
Query parameters can be indicated using the @QueryParam
annotation, and path parameters can be indicated using the Josh Juneau (@javajuneau) is a Java Champion and an applica-
@PathParam annotation within the resource method signa- tion developer, system analyst, and database administrator. He is a
ture. Listing 12 demonstrates how to use a path parameter in technical writer for Oracle Technology Network and Java Magazine,
a resource method. and he has written several books on Java and Java EE for Apress.
Juneau is also a JCP expert group member for JSRs 372 and 378.
Listing 12.
@POST
@Path("/date/{year}/{month}")
public String pathParamDate(
@PathParam("year") int year,
learn more
@PathParam("month") int month) {
GitHub project source code
models.put("specifiedDate",
month + "/" + year); Ozark project site
return "showDate.xhtml"; MVC specification
} Adding MVC to GlassFish
39
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /

Building Browser-Based UIs


with Oracle JET
A look inside Oracles open source JavaScript toolkit
JOHN BROCK

O racle JavaScript Extension Toolkit, or Oracle JET as its


more commonly called, is a modular toolkit based on a
collection of open source libraries and open source code con-
installed on your system. (Note that Node.js is required only
for the installation.)
To install and create your own Oracle JET application,
tributed by Oracle. It helps JavaScript developers build pure open a terminal or command-prompt window and follow the
client-side user interfaces that consume and interact with web steps below.
services such as REST and WebSocket. The toolkit is designed Using npm, install the following libraries:
so you can use as little or as much as you need. Its as non-
prescriptive in nature as possible. npm install g bower grunt-cli yo
Why should a Java developer even care about a JavaScript npm install g generator-oraclejet
toolkit? With the increasing demand each year for develop-
ers to be versed in more aspects of the application stack, its Once you have the supporting libraries installed, you are
becoming critical for Java developers to understand the client ready to generate your irst Oracle JET application by typing
space as well as the traditional server space. Whether you are the following:
responsible for developing REST services that an application
will integrate with or the full application, you will inevitably yo oraclejet <application name> --template=navdrawer
need to know something about how that JavaScript client is
written. It could be only for testing purposes, but you will This command will create a subdirectory with the <application
most likely need to know how things work in the browser at name> that you provided and then install and conigure all
some point. the required iles for the Oracle JET application, using one of
Oracle JET is designed to be a comfortable toolkit for many sample application shells as a template. In this case, it
the traditional JavaScript developer. Installation is provided will use an application shell that works on both desktop and
through the Node.js npm and bower modules, while starter mobile web browsers. If everything goes correctly, you should
templates are provided by using a Yeoman generator. The see a prompt with wording similar to:
steps that follow assume that you are familiar with JavaScript
and with Node.js, and that you already have Node.js and Git Oracle JET: Your app is ready! Change to your new app
40
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
directory [application name] and try grunt build The browser opens automatically (on localhost at port 8000).
and serve The application should show a mostly empty dashboard win-
dow when the browser opens.
Now that you have your application shell created, you can run If you resize the browser window or use the browser tools
the sample app and see how it looks in a browser. To do this to render the content in mobile mode, you will see that the
from the terminal or command-prompt window, type the application shell is already conigured as a responsive appli-
following commands in your applications root directory: cation and will change layout depending on the viewport size.
Figure 1 shows this same dashboard in a simulated device
grunt build environment (here, the device toolbar in the Developer
grunt serve Tools menu of Google Chrome).

Figure 1. The sample application in a


simulated mobile environment Figure 2. Cookbook samples
41
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
Getting started is always the tricky part for anything The input ield will take a city name; the selection menu will
new. With Oracle JET, you can use a helpful feature of the allow you to select a state; and the button will call a REST ser-
Oracle JET website called the Cookbook, which has recipes vice to get all of the fueling stations ofering alternative fuels
for all kinds of display components and widgets. Figure 2 in that city and state. The chart will display the returned data.
shows some samples. The code in the Cookbook is live, so Using radio buttons, you can select whether you want to see
you can make changes to HTML, JavaScript, or CSS and see the results as a bar chart or a pie chart. You will also be able
the changes with a simple click of the Apply button. This is a to click any of the items in the legend of the chart to show or
great way to learn about the API and various options for dif- hide that particular item. Figure 3 is what the inal application
ferent UI components. looks like.
Once you are ready to add to your own code, you can Note that out of the box, all Oracle JET UI components
simply copy and paste the HTML and JavaScript to your own meet the Web Content Accessibility Guidelines (WCAG) 2.0
application and continue your development. at the AA level. While this might not mean much to some
For this example, I am going to add one text input ield, developers, it should be a goal of all developers to write soft-
a selection menu, a button, a radio button set, and a chart. ware that can be used by persons with or without disabilities.
Beyond this just being the
right thing to do, its also a
requirement for many gov-
ernment and public sector
customers, as well as many
enterprises around the world.
Lets take a look at the
code behind the sample
application. The architec-
tural structure of an Oracle
JET application follows the
Model-View-View model
(MVVM) pattern. MVVM is
derived from the model-
view-controller (MVC) pat-
tern and is designed to sepa-
rate development of the view
layer (usually HTML) from
the business logic and data
layers (usually JavaScript
and JSON, respectively). The
Figure 3. What the sample application will look like toolkit is designed to be as
42
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
modular as possible, thereby allowing developers to use as CSS in their respective /js and
little or as much of it as they like. It provides a two-way data /css folders. Build scripts are Because Oracle JET
binding method based on the open source library Knockout kept separate in their own is a pure client-side
.js. While Knockout is not required by Oracle JET, it is used
heavily in samples and documentation as a default bind-
/scripts folder. All the main
application code is placed under
toolkit, the only way to
ing mechanism. UI components are wrapped as jQuery UI the /src folder so you can sepa- consume and interact
widgets, and a custom Knockout binding integrates those rate what would be included for with remote data is via
components into the larger
MVVM pattern. jQuery UI
source code management from
what would be platform-speciic.
web services such as
was chosen because of the The starter templates pro- REST or WebSocket.
hundreds of third-party UI vided by Oracle JET are set up
components available for to allow you to build for mul-
it on the internet. These tiple platforms. You can build a
third-party components web or mobile hybrid application from the same source code.
can be used with few issues Currently Android, iOS, and Windows are supported mobile
in any Oracle JETbased platforms. At build time, native themes are added for the
application. platform that you have selected, so the applications form
The inclusion of elements and other platform-speciic theming automatically
RequireJS with Oracle JET is look like those of a native app. You can see a lot of this in
to provide lazy loading of action by changing the themes in the Cookbook on the Oracle
resources through the use of JET website.
the Asynchronous Module In addition to the accessibility features mentioned earlier
Deinition (AMD) API. With (which also carry over to mobile apps), all Oracle JET UI com-
large enterprise-ready ponents are touch- and gesture-enabled out of the box. If you
applications, which might have a touchscreen on your laptop, Oracle JETbased applica-
have hundreds of JavaScript tions will work properly.
libraries, it is critical to per- Looking at the code itself, you will notice that the index
formance to have the ability .html ile provides the shell of the application, while the
to manage the dependen- main content is actually loaded using a feature called
cies among those librar- ojModule. This design enables developers to think of their
ies as well as to load only pages as separate modules that are loaded into the content
speciic libraries when they area asynchronously when they are needed. This approach
are needed. allows for more-distributed work on an application, because
The directory structure diferent teams can work on diferent modules without step-
Figure 4. The default directory shown in Figure 4 is a com- ping on each others code. An ojModule binding consists of its
structure mon one with JavaScript and own HTML (view) and JavaScript (viewModel) ile. As shown
43
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
in Figure 4, there are separate directories for views and view- Notice that the getData method is bound to the click event
Models as part of the app structure. In this sample applica- for the Search button. The values for the input ield and
tion, all code was added to the dashboard module (dashboard selection menu are also bound to values that are deined in
.html and dashboard.js iles). the viewModel. This data binding functionality is provided
The dashboard view ile is where you focus on writing by Knockout.
your HTML code. Oracle JET is what is often referred to as an Looking at the viewModel, you can see that the Knockout
HTML forward toolkit. This means that you use the semantics observables are deined, along with their default values in the
of HTML5 itself to provide layout and structure to your appli- following code:
cation. This is in contrast to a JavaScript forward framework,
where you would write JavaScript to generate your HTML. The self.handleActivated = function (info) {
business logic is handled in the dashboard viewModel ile. self.cityVal = ko.observable('San Jose');
The following code excerpt is an example of what the self.chartType = ko.observable('pie');
view looks like: self.selectVal = ko.observableArray(['CA']);
self.pieSeriesValue = ko.observableArray([]);
<div class="oj-flex-item"> self.groupsValue = ko.observableArray(['Fuel Types']);
<label id="groupLabel">Enter City and State</label> self.seriesValue = ko.observable();
<div role="group" aria-labelledby="groupLabel" . . .
class="oj-form-control-group">
<input id="text-input" aria-label="city" Knockout observables are special variables to which Knockout
type="text" attaches listeners for the purpose of two-way data binding.
data-bind= You will recognize these variables because they are deined
"ojComponent: {component: 'ojInputText', by ko.observable or ko.observableArray. If you change
value: cityVal}"/> the value of one of these variables, anything bound to it on
<input id="text-input" aria-label="state" the view side of the application is automatically updated to
type="text" the new value. The reverse is also true if you have bound
data-bind= the value of an editable component such as an input ield.
"ojComponent: {component: 'ojSelect', Once the user updates that ield, the variable is updated
options: States, and anything else bound to that same variable will be noti-
value: selectVal}"/> ied and updated as well. This is what two-way data bind-
<button data-bind= ing is all about. You dont need to worry about doing any
"ojComponent: {component: 'ojButton', kind of Document Object Model (DOM) manipulation in your
label:'Search'}, JavaScript code to update the value of your UI components.
click:getData"> The getData() method that is called when the Search
</button> button is clicked is shown in the following code:
</div>
</div> self.getData = function () {
44
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ui tools /
// using a Promise to allow the chart to (CRUD) dataOracle JET
// render only once the data is available. provides a Common Model Oracle has used Oracle JET
self.seriesValue(new Promise( API that simpliies working as the foundation for more
function (resolve, reject) {
var url =
with multiple types of data
sources. You can read more
than 70 percent of its
"https://api.data.gov/nrel/alt-fuel-stations" + about the Common Model new cloud service oferings.
"/v1/nearest.json?location=" + API in the Framework
+ self.cityVal() + "+" + self.selectVal()+ section of the Oracle JET
"&api_key=<your api key goes here>"; Cookbook.
$.getJSON(url).then(function (data) { If you would like to take a closer look at the sample
var fuels = data.station_counts.fuels; application and run it in your own development environ-
var seriesData = []; ment, you can clone the project from GitHub. Installation
for (var prop in fuels) { and coniguration steps are included in the README ile for
if (fuels[prop].total > 0) { the project.
seriesData.push({name: getFuelName(prop),
items: [fuels[prop].total] }) Conclusion
} While Oracle JET has actually been around for more than
} three years, it has been available to the open source commu-
resolve(seriesData); nity for only about one year. Oracle has used Oracle JET as the
}); foundation for more than 70 percent of its new cloud service
})) oferingsso you know that it meets the needs of very large
}; enterprise-scale applications.
Oracle JET is most powerful when you understand the
This code uses a JavaScript Promise to return the results of concepts and ideas behind its creation. To get that under-
the call to the REST service after the data is actually ready. standing, you can read the developers guide or take the
The Promise object is a new addition in the ECMAScript 2015 free online training course (login required). Both are great
language speciication (also known as ES6) that helps when resources for beginners and developers. For announce-
you are working with asynchronous data such as REST calls. ments and interaction with others using Oracle JET, follow
Because Oracle JET is a pure client-side toolkit, the only @oraclejet on Twitter or engage with other developers on
way to consume and interact with remote data is via web the Oracle JET Community site. </article>
services such as REST or WebSocket. You can use any method
you like for making the web service call. The most common John JB Brock has spoken at JavaOne, Oracle OpenWorld, and
way is to use jQuery Ajax methods or jQuery.getJSON, but many Developer Days events over the last decade. He is a coauthor
you can use plain JavaScript XMLHttpRequest API calls as well. of Java EE and HTML5 Enterprise Application Development
For more-complex data interactionssuch as those used (McGraw-Hill, 2014), a two-time winner of the JavaOne Rock Star
in applications that need to create, read, update, and delete Award, and the senior product manager for Oracle JET.
45
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//iot /

Simple Messaging with MQTT


Use the principal IoT messaging protocol to asynchronously send and receive data
from devicesin this case, from drones.

GASTN HILLAR
M Q Telemetry Transport (MQTT) is a lightweight publish-
subscribe messaging protocol, especially suitable for
small devices but also useful for any device that requires mes-
Things (IoT), and it is gaining popularity in mobile and web
applications. MQTT is a protocol that works with a publish-
subscribe mechanism and runs on top of the TCP/IP protocol.
saging over a network. In this article, I describe how to pub- It is lighter than the HTTP protocol and, therefore, it is a very
lish and receive messages with Java through the Mosquitto interesting option whenever you need to send and receive
broker with the asynchronous API provided by the Eclipse data in real time with a publish-subscribe model and you
Paho project Java client. need the lowest possible footprint. However, as always hap-
In this article, I develop and explain a project in which pens, the reduced footprint comes at a price: MQTT does not
three drones use a Mosquitto broker to publish and receive ofer great extensibility.
text messages. Some of these messages provide only infor- Mosquitto is an open source message broker that imple-
mation to a channel and others specify a command and ments two versions of the MQTT protocol: 3.1 and 3.1.1. You
a destination by which they tell speciic drones to dis- can use Mosquitto to make any device subscribe to a spe-
play their altitude in feet. I use the asynchronous methods ciic channel, known as a topic in MQTT terminology. All
included in the Eclipse Paho Java Client to connect to the subscribed devices will receive all the messages published
broker, publish messages, and subscribe to topics. This way, by other devices to this topic. Mosquitto, with its publish-
you can see how to work with MQTT in Java using a non- subscribe model, is an iot.eclipse.org project, also known as
blocking behavior. Eclipse IoT, and it is provided under the Eclipse Distribution
License (EDL). It is important to know that, at the time of
The Pieces of the Puzzle this writing, MQTT version 5 has reached the working
I will shortly explain how to include the necessary refer- draft stage.
ences to work with the latest version of the Eclipse Paho Java The Eclipse Paho project ofers an open source imple-
Client. However, before moving forward, it is necessary to mentation of an MQTT client library that is capable of work-
understand the diferent pieces of this puzzle: the MQTT pro- ing with the same two versions of the MQTT protocol sup-
tocol, Mosquitto, the Eclipse Paho project, and Eclipse Paho ported by Mosquitto: 3.1 and 3.1.1. The Eclipse Paho Java Client
Java Client. provides both a synchronous and an asynchronous API. As
The MQTT protocol is a machine-to-machine (M2M) previously explained, I will demonstrate how to work with
connectivity protocol used extensively in the Internet of its asynchronous API. However, bear in mind that there is
46
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//iot /
a synchronous version you broker. I provide many useful links to allow you to learn more
can use if you dont need You will never connect about Mosquitto and MQTT at the end of this article.
the nonblocking features one client to another client You need to make sure that your software and hardware
and you want to keep your
code simpler.
through a direct connection. irewalls allow the application or the IDE to work with TCP in
port 1883.
It is important to under- The dialogue is always
stand that the MQTT con- between a client and Using the Java Client for MQTT
nection is always between At the time of this writing, the latest release of Paho Java
a client and the brokerin
the MQTT broker. Client is 1.1.0. I will use this version to include the necessary
this case, between Paho Java dependencies. The easiest way to use the Java client is to start
Client and Mosquitto. You a Maven project in your favorite Java IDE and add the follow-
will never connect one client ing lines before </project> in the pom.xml ile. Im assum-
to another client through a direct connection. The dialogue is ing that you are working with an empty Maven project. If you
always between a client and the MQTT broker. In my example, have other repositories or dependencies, make sure you edit
each drone establishes a connection with Mosquitto, and a the pom.xml ile to include the new entries, as shown next.
master drone sends messages with commands that are meant You can also use the features included in your favorite IDE or
to be processed by speciic drones. its Maven plugins to add the repository and the dependency.
It is possible for any client to subscribe to a speciic topic.
By doing so, it will receive all the messages published to that <repositories>
topic. In addition, the client can publish messages to that <repository>
speciic topic or to other topics. In my example, I work with <id>Eclipse Paho Repo</id>
just one topic, and I wont take advantage of the wildcards <url>https://repo.eclipse.org/content/
that allow you to work with many topics at the same time. repositories/paho-releases/</url>
However, once you understand how to work with the Java </repository>
client, you can use the sample code to take advantage of the </repositories>
additional features, based on your speciic needs. <dependencies>
I dont want to focus on the coniguration of a Mosquitto <dependency>
message browser. Instead, I want to put my eforts into dem- <groupId>org.eclipse.paho</groupId>
onstrating how to publish and receive messages. Eclipse allows <artifactId>
you to use a publicly accessible sandbox server for the Eclipse org.eclipse.paho.client.mqttv3
IoT projects at iot.eclipse.org port 1883 identiied with the fol- </artifactId>
lowing URI: tcp://iot.eclipse.org:1883. I will use this sandbox <version>1.1.0</version>
server as the Mosquitto message broker, without any security. </dependency>
That way, you dont have to lose time setting up a Mosquitto </dependencies>
message broker to test the example. Of course, a real-life
application would require you to set up a Mosquitto message [The repository URL should be entered as a single line. Ed.]
47
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//iot /
I am going to create the following three classes. All these public class MessageActionListener
classes are included in the code bundle for this article. implements IMqttActionListener {
MessageActionListener implements the org.eclipse protected final String messageText;
.paho.client.mqttv3.IMqttActionListener interface. I use protected final String topic;
instances of this class to specify the callback that will run protected final String userContext;
code whenever a message has been successfully published
to a topic. public MessageActionListener(
Drone represents a drone that has a name and can send String topic,
and receive messages through the MQTT broker. This class String messageText,
not only encapsulates the data and logic related to drones String userContext) {
as well as the messages and the commands included in this.topic = topic;
messages, but it also implements the MqttCallback and this.messageText = messageText;
ImqttActionListener interfaces deined in org.eclipse this.userContext = userContext;
.paho.client.mqttv3. There is no type in these interface }
namesthe naming convention for interfaces in the Java
library is a bit confusing because some interfaces start with @Override
I while others dont. I use Drone instances as callbacks for public void onSuccess(
speciic events. IMqttToken asyncActionToken) {
MqttSample01 creates three instances of the Drone class, if ((asyncActionToken != null) &&
makes them connect to the MQTT broker, and sends mes- asyncActionToken.getUserContext()
sages and commands. This class declares the main static .equals(userContext))
method for the example application. {
System.out.println( String.format(
Creating a Class That Is Notified When Asynchronous "Message '%s' published to topic '%s'",
Actions Are Complete messageText, topic));
The asynchronous API requires you to work with callbacks. }
In this example, I demonstrate many ways of working }
with the necessary callbacks. The following code shows
the import statements and the code for the Message @Override
ActionListener class that implements the IMqttAction public void onFailure(
Listener interface. IMqttToken asyncActionToken,
Throwable exception) {
import exception.printStackTrace();
org.eclipse.paho.client.mqttv3.IMqttActionListener; }
import }
org.eclipse.paho.client.mqttv3.IMqttToken;
48
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//iot /
When I create an instance of that you select when you work with the MQTT protocol. The
the MessageActionListener What does it mean QoS level is the agreement between the publisher and the
class, I need to specify the topic that a message receiver of a message about the guarantees for delivering
to which the message is going the message. Delivering a message involves publishing from
to be published, the message
was successfully the client to the broker and then from the broker to the sub-
text, and a user context. The delivered by the MQTT scribed client. MQTT supports three possible QoS values:
constructor saves the received broker? It depends on the Level 0 means at most once: This level provides the same

values in immutable ields that


have the same names as the
quality of service (QoS) guarantee as the TCP protocol. The message is not acknowl-
edged by the receiver. The sender neither stores nor re-
received arguments. that you select. delivers any messages. As you might expect, this level has
The class implements the the lowest overhead.
onSuccess method required by Level 1 means at least once: This level provides a guaran-

the IMqttActionListener inter- tee that the message will be delivered at least once to the
face. Whenever an instance of the MessageActionListener receiver. The main drawback is that this QoS level might
class is used as a callback for an asynchronous action, the generate duplicates, because the message can be delivered
Java client invokes the onSuccess method when the action more than once. The sender stores the message until it
has been completed successfully, and it passes an asynchro- receives an acknowledgment. In the event the acknowledg-
nous action token (asyncActionToken) of type IMqttToken ment isnt received within a speciic time, the sender will
as an argument to specify the action that has been com- publish again.
pleted. The method makes sure that asyncActionToken Level 2 means exactly once: This level provides a guaran-

is not null and checks whether the value returned by tee that the message is delivered only once to the receiver.
asyncActionToken.getUserContext() matches the user This QoS level makes sure the message isnt delivered more
Context saved by the constructor. If they match, the success- than once and, therefore, there is no chance for duplicates.
ful event is related to the event I wanted to monitor for its However, as you might expect, it has the highest over-
successful execution, and the code displays a message con- head because it requires two lows between the sender and
taining the message text that has been published and the receiver (one to receive, the other to send acknowledgment
name of the destination topic. I use an instance of this class of receipt). Only when the entire low is completed is the
as a callback for each message that is published, and thereby I message considered to be successfully delivered.
can see all the successfully published messages. In this example, I will work with QoS level 2, because I dont
The class also implements the onFailure method, which want the possibility of receiving a command twice. Messages
is required by the IMqttActionListener interface and simply are delivered even across network and client restarts. How-
calls the printStackTrace method for the received exception. ever, for that to occur, each message needs to be stored in
a safe location until it has been successfully delivered. The
Specifying the Quality of Service Java client works with a pluggable persistence mechanism to
What does it mean that a message was successfully delivered store the messages. To keep things simple in this example,
by the MQTT broker? It depends on the quality of service (QoS) I will use memory-based persistence, which is not the best
49
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//iot /
option with QoS level 2. However, you can easily explore and protected String clientId;
conigure other pluggable persistence mechanisms to avoid protected MqttAsyncClient client;
losing messages in the event the application, the JVM, the protected MemoryPersistence memoryPersistence;
computer, or the device running the application stops work- protected IMqttToken connectToken;
ing or shuts down. protected IMqttToken subscribeToken;

Creating a Class to Represent a Drone That public Drone(String name) { this.name = name; }
Processes Messages
The following code shows the key aspects of the Drone class public String getName() { return name; }
that implements the MqttCallback and IMqttActionListener
interfaces. The full class is available in the downloadable code. It is very important that you replace the TOPIC string with
When I create an instance of the Drone class, it is nec- your own, unique topic name. The Mosquitto broker I am
essary to specify the desired name for the drone. The class using in the example is public and, therefore, I need to use a
deines many constants that I will use throughout the code unique topic to make sure I receive only the messages pub-
and determine the string that deines a command key, the lished by my code. I have speciied "java-magazine-mqtt/
separator, the command that retrieves the altitude for the drones/altitude" for TOPIC in this example. MQTT uses topic
drone, the topic to which the Java client will subscribe, the names that have a hierarchy and are separated by a slash (/).
desired QoS level, and the encoding that will be used for the Another example of a topic name is "java-client/samples/
messages, as shown below. drones/commands/altitude".
The connect method has some code that is commented
public class Drone implements MqttCallback, out just to remind you that in a production environment you
IMqttActionListener { shouldnt send messages over an insecure connection and
public static final String COMMAND_KEY = "COMMAND"; your MQTT broker should work with TLS/SSL and require the
public static final String COMMAND_SEPARATOR = ":"; appropriate authentication. The code creates an instance
public static final String of the MemoryPersistence class to use as the previously
GET_ALTITUDE_COMMAND_KEY = "GET_ALTITUDE"; explained pluggable persistence, generates a unique client ID,
// Replace with your own topic name and creates an instance of MqttAsyncClient named client.
public static final String TOPIC = This way, I create the entry point for the Java client with the
"java-magazine-mqtt/drones/altitude"; asynchronous API.

public static final String ENCODING = "UTF-8"; public void connect() {


try {
// Quality of Service = Exactly once MqttConnectOptions options =
// I want to receive all messages exactly once new MqttConnectOptions();
public static final int QUALITY_OF_SERVICE = 2; // options.setUserName(
protected String name; // "replace with your username");
50
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//iot /
// options.setPassword( that will execute speciic methods when some asynchro-
// "replace with your password" nous events occur. The setCallback method requires an
// .toCharArray()); argument of the MqttCallback type. The Drone class imple-
// Replace with ssl:// and work with TLS/SSL ments the MqttCallback interface that requires the follow-
// best practices in a ing three methods: connectionLost, messageArrived, and
// production environment deliveryComplete. Ill get back to these methods later. It is
memoryPersistence = very important to call the setCallback method before estab-
new MemoryPersistence(); lishing the connection with the MQTT broker.
String serverURI = The line that calls the client.connect method speciies
"tcp://iot.eclipse.org:1883"; this as the last argument because I will also use the actual
clientId = MqttAsyncClient.generateClientId(); instance as the callback that will execute speciic methods
client = new MqttAsyncClient( when some asynchronous events related to the connection
serverURI, clientId, occur. The fourth argument for the connect method requires
memoryPersistence); an argument of the IMqttActionListener type.
// I want to use this instance as the callback The Drone class implements the IMqttActionListener
client.setCallback(this); interface that requires these two methods: onSuccess
connectToken = client.connect( and onFailure.
options, null, this);
} catch (MqttException e) { @Override
e.printStackTrace(); public void onSuccess(
} IMqttToken asyncActionToken) {
} if (asyncActionToken.equals(connectToken)) {
System.out.println( String.format(
public boolean isConnected() { "%s successfully connected",name));
return (client != null) && try {
(client.isConnected()); subscribeToken = client.subscribe(
} TOPIC, QUALITY_OF_SERVICE,
null, this);
@Override } catch (MqttException e) {
public void connectionLost(Throwable cause) { e.printStackTrace();
// The MQTT client lost the connection }
cause.printStackTrace(); }
} else if (asyncActionToken.equals(
subscribeToken))
The line that calls the setCallback method uses this as an {
argument because I use the actual instance as the callback System.out.println( String.format(
51
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//iot /
"%s subscribed to the %s topic", IMqttActionListener type. So, after a successful subscription,
name, TOPIC)); the Java client will run the same onSuccess method, but the
publishTextMessage( String.format( code will recognize that the event is related to the subscrip-
"%s is listening.", name)); tion because the received token wont match the connection
} token and instead will match the subscription token. It is not
} necessary to make it this way. It is possible to create an anon-
ymous type to declare the methods that are necessary for
@Override the subscription callback for the asynchronous subscription.
public void onFailure(IMqttToken asyncActionToken, However, I wanted to demonstrate the usage of the tokens.
Throwable exception) The onSuccess method displays a message indicating that
{ the speciic drone has been successfully subscribed to the
// The method will run if an operation failed speciic topic. Then, the code calls the publishTextMessage
exception.printStackTrace(); method to publish a message to the topic indicating that the
} drone is listening.

I implemented the same interface in the MessageAction public MessageActionListener publishTextMessage(


Listener class. However, in this case, I will implement the String messageText)
interface to run code when the success or failure is related {
to the connection, not with messages as happened in the byte[] bytesMessage;
MessageActionListener class. try {
The code saves the IMqttToken returned by the client bytesMessage =
.connect method to the connectToken protected ield. This messageText.getBytes(ENCODING);
way, I am able to check whether the onSuccess methods MqttMessage message;
execution is related to this token or not. The connection uses message = new MqttMessage(bytesMessage);
asynchronous execution, and the onSuccess method for the String userContext = "ListeningMessage";
Drone class will be executed after the connection with the MessageActionListener actionListener =
MQTT broker has been successfully established. new MessageActionListener(
The onSuccess method displays a message indicating TOPIC, messageText, userContext);
that the speciic drone has been successfully connected. client.publish(TOPIC, message,
Then, the code calls the client.subscribe method with the userContext,actionListener);
topic to which I want to subscribe and the desired QoS level. return actionListener;
The call to this method speciies this as the last argument } catch (UnsupportedEncodingException e) {
because I will also use the actual instance as the callback e.printStackTrace();
that will execute speciic methods when some asynchronous return null;
events related to the subscription occur. The fourth argu- } catch (MqttException e) {
ment for the subscribe method requires an argument of the e.printStackTrace();
52
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//iot /
return null; Whenever a message arrives, the messageArrived method will
} be executed. The code in this method receives a String with
} the topic and an instance of MqttMessage.

The publishTextMessage method receives a String in the @Override


messageText argument with the text message that the public void messageArrived(String topic,
drone has to publish to the topic and returns an instance MqttMessage message) throws Exception
of the MessageActionListener class. The method calls the {
messageTextgetBytes method to generate a byte array that // A message has arrived from the MQTT broker
takes into account the UTF-8 encoding. The MqttMessage class // The MQTT broker doesn't send back
requires a byte array with the message to be sent as an argu- // an acknowledgment to the server until
ment to create an instance. Then, the code creates an instance // this method returns cleanly
of the MessageActionListener class named actionListener if (!topic.equals(TOPIC)) {
and calls the client.publish method to publish the mes- return;
sage on the topic with an actionListener instance as the }
last argument that speciies the desired callback. This way,
the code declared in the onSuccess method for this class will String messageText =
run after the message has been successfully published to the new String(message.getPayload(), ENCODING);
speciied topic. System.out.println( String.format(
The publishCommand method takes two String argu- "%s received %s: %s", name, topic,
ments: the command name and the destination name. The messageText));
method uses the received values to build a command and String[] keyValue =
then calls the previously explained publishTextMessage messageText.split(COMMAND_SEPARATOR);
method with this command as an argument. For example, the if (keyValue.length != 3) {
following command requests a drone whose name is Drone #1 return;
to print its altitude in feet: COMMAND:GET_ALTITUDE:DRONE #1. }
if (keyValue[0].equals(COMMAND_KEY) &&
public MessageActionListener publishCommand( keyValue[1].equals(
String commandName, String destinationName) GET_ALTITUDE_COMMAND_KEY) &&
{ keyValue[2].equals(name))
String command = String.format("%s%s%s%s%s", {
COMMAND_KEY, COMMAND_SEPARATOR, // Process the "get altitude" command
commandName, COMMAND_SEPARATOR, int altitudeInFeet = ThreadLocalRandom
destinationName); .current().nextInt(1, 6001);
return publishTextMessage(command); System.out.println( String.format(
} "%s altitude: %d feet",
53
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//iot /
name, altitudeInFeet)); Publishing Messages
} The following code lines show the code for the MqttSample01
} class that declares the main method. The main method cre-
ates three instances of the Drone classdrone1, drone2, and
First, the code makes sure that the topic is the one that masterDroneand calls the connect method for each of these
the drone is interested in. Then, the code calls the message instances. I didnt use any kind of list to work with the drones
.getPayload() method to retrieve the byte array with the because I wanted the code to be easier to read. Forgive me for
message. The code creates a String instance with the byte repeating some code in this main method.
array and the UTF-8 encoding as arguments to generate the
appropriate String. The code displays a message indicating public class MqttSample01 {
that the speciic drone has received a message in the topic. public static void main(String[] args) {
Finally, the code processes the String with the received mes- Drone drone1 = new Drone("[Drone #1]");
sage to determine whether the message is a command. If it drone1.connect();
has the command-key preix, the code decodes the command Drone drone2 = new Drone("[Drone #2]");
and if its the get altitude command, the code displays a drone2.connect();
message with a pseudorandom altitude value for the drone Drone masterDrone = new Drone("*Master Drone*");
expressed in feet. masterDrone.connect();
Whenever a message has been successfully delivered, the
deliveryComplete method is executed with a token (token) try {
of type IMqttDeliveryToken as an argument to allow you to while (true) {
identify which message has been delivered. As previously try {
explained, the meaning of a successfully delivered mes- Thread.sleep(5000);
sage will depend on the QoS level. In this case, Im working int r =
with QoS level 2 and this method will be executed after the ThreadLocalRandom.current()
acknowledgment from the receiver arrives. Here, I didnt add .nextInt(1, 11);
code to this method and I just declared it to implement all the if ((r < 5) && drone1.isConnected()) {
methods required by the interface. masterDrone.publishCommand(
Drone.GET_ALTITUDE_COMMAND_KEY,
@Override drone1.getName());
public void deliveryComplete( } else
IMqttDeliveryToken token) { if (drone2.isConnected()) {
// Delivery for a message has been completed masterDrone.publishCommand(
// and all acknowledgments have been received Drone.GET_ALTITUDE_COMMAND_KEY,
} drone2.getName());
}
54
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//iot /
} catch (InterruptedException e) { }
e.printStackTrace(); }
}
} catch(Exception e) { Then, a forever-running loop generates a pseudorandom
e.printStackTrace(); number every ive seconds and, based on that number, it
} finally { makes masterDrone publish a command to get the altitude for
if (drone1.isConnected()) { either drone1 or drone2.
try { Figure 1 shows an example of the output messages
drone1.client.disconnect(); shown in the Console window of the IDE. Notice that both
} catch (MqttException e) { Drone #1 and Drone #2 receive the same messages with the
e.printStackTrace(); GET_ALTITUDE command. However, only the drone that is the
} destination for the message processes the command and dis-
} plays its pseudorandom altitude.
...similarly for drone2 and masterDrone
Conclusion
This example demonstrates how you can use the Eclipse Paho
Java Client and a Mosquitto MQTT broker to subscribe to a
topic and publish messages to a topic. There is also a Java cli-
ent library that can run on Android, in case you need to work
with MQTT in Android. Whenever you need to exchange mes-
sages with an asynchronous, nonblocking API, you can con-
sider using MQTT and the Java client. </article>

Gastn Hillar (@gastonhillar) has been working as a software


architect with Java since its irst release. He has 20 years of expe-
rience designing and developing software. He is the author of many
books related to software development, hardware, electronics, and
the Internet of Things, and he has been awarded the Intel Black
Belt Software Developer Award eight times.

learn more
The MQTT protocol
The iot.eclipse.org project
Figure 1. Console messages
55
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//the road to java 9 /

Exploring Compact Profiles


Java 8s Compact Profiles point the way to Java 9s modularity.

BEN EVANS
J ava 8 introduced the concept of Compact Proiles, which
are reduced versions of the Java runtime environment
(JRE) that do not contain the usual full contents of rt.jar. In
Allow application developers to package their code as mod-
ules, rather than as JAR iles.
The catch is that in order to achieve the full set of goals,
this article, I explore the advantages of using Compact Proiles major surgery on the Java platform core is required. In partic-
and how they point the way toward a modular future for the ular, a new approach to classloadinginvolving a modular
JDK, which takes a big step forward in Java 9. classloaderis required. This has a lot of edge cases and is a
The current versions of the JRE are quite monolithic: complex undertaking, especially if we need to maintain back-
rt.jar is at least 60 MB on its own, without taking into ward compatibility.
account the size of native code loaded as dynamic libraries. In order to maintain the release date for Java 8, the deci-
If we can reduce the size of the Java platform footprint and sion was made to move full modularity out to Java 9, which
move to a modular view of the JDK, we can realize some will ship in July. Java 8 Compact Proiles are designed to be
great beneits: a irst step toward full modularity, with some of the basic
Faster JVM startup times advantages noted above. They build on the initial work done
Reduced resource consumption for modularity and provide a cut-down Java runtime, which
Removal of packages that, in hindsight, shouldnt be in Is fully compliant with the JVM and Java language

the core speciications


Improved security, because removing unused classes Has a substantially reduced footprint

reduces the attack surface of the platform Removes functionality that is not always needed (for exam-

Convergence of the Java ME Connected Device ple, CORBA)


Coniguration (CDC) with Java SE Works for many applications (especially server-side code)

The initial approach to this efort was a full modularization of Compact Proiles are based on packages; they contain a num-
the platform, known as Project Jigsaw. This ambitious project ber of full packages, and no partial packages are currently
also included other goals: allowed. They are also subject to two other restrictions:
Incorporate best practices for dependencies into the plat- A proile must form a closed set; references to classes not

form core, and apply lessons learned about dependency contained in the proile are not allowed.
management from tools such as Maven, Apache Ivy, OSGi If a proile contains some classes from another, smaller pro-

standard, and Linux distributions. ile, it must contain all of them, so partially overlapping pro-
PHOTOGRAPH BY JOHN BLYTHE Isolate dependenciessolve the library versioning problem. iles are not allowed. Put another way, proiles are additive.
56
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//the road to java 9 /
The smallest Compact Proile is called compact1, and it com- jdeps have been modiied to be aware of proiles.
prises the following packages: java.io, java.lang, java javac is the tool of choice for determining whether a
.lang.annotation, java.lang.invoke, java.lang.ref, java collection of source code can be safely run on a speciic pro-
.lang.reflect, java.math, java.net, java.nio, java.nio ile. This is achieved by using the new -profile switch.
.channels, java.nio.channels.spi, java.nio.charset, java javac -profile <profile> will cause a compilation error to
.nio.charset.spi, java.nio.file, java.nio.file.attribute, be generated for any usage of a class not present in the indi-
java.nio.file.spi, java.security, java.security.cert, cated proile.
java.security.interfaces, java.security.spec, java.text, In some cases, however, source code is not available or a
java.text.spi, java.time, java.time.chrono, java.time recompilation run is inconvenient. Fortunately, in this case,
.format, java.time.temporal, java.time.zone, java.util, the new jdeps tool can help.
java.util.concurrent, java.util.concurrent.atomic, java jdeps is a new static analysis tool that ships with
.util.concurrent.locks, java.util.function, java.util Java 8. It provides an analysis of the dependencies of a spe-
.jar, java.util.logging, java.util.regex, java.util.spi, ciic class or JAR ile. This tool is extremely useful (and not
java.util.stream, java.util.zip, javax.crypto, javax just for proile dependencies), and it features a -profile
.crypto.interfaces, javax.crypto.spec, javax.net, javax (or -P) switch that indicates which packages depend on
.net.ssl, javax.script, javax.security.auth, javax which proiles.
.security.auth.callback, javax.security.auth.login, Lets take a look at an example, which summarizes the
javax.security.auth.spi, javax.security.auth.x500, and package dependencies for the popular JUnit testing library.
javax.security.cert. See Listing 1, which shows good news: everyone should be able
Two other Compact Proiles are speciied in Java 8: to test their code.
compact2, which adds packages used for remote method
invocation (RMI), SQL, and XML, and compact3, which com- Listing 1.
prises all of compact2 plus tooling and management pack- jdeps -s -P junit.jar
ages (including Java Management Extensions [JMX]) as well junit.jar -> compact1
as additional cryptography libraries. The smallest proile,
compact1, occupies around 11 MB, which is a signiicant If we want more information, we can use the -v switch for
space savings. verbose output, which will give us a lot of detail about each
As currently speciied, all of these proiles are headless; class inside the JAR ile. See Listing 2 (some of the output was
they do not contain any GUI classes. Any applications requir- truncated because it was 2,152 lines long).
ing GUI support (Swing or AWT) must use a full JRE.
Listing 2.
Tools jdeps -v junit.jar
To make use of Compact Proiles, developers require tools. junit.jar -> /Library/Java/JavaVirtualMachines/openjdk8/
One important question is whether an application can run Contents/
against a speciic proile. Java 8 ships with two tools that have Home/jre/lib/rt.jar
been enhanced to help answer this question: both javac and junit.extensions.ActiveTestSuite (junit.jar)
57
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//the road to java 9 /
-> java.lang.Class packages with a name that matches a given regular expres-
-> java.lang.InterruptedException sion should be considered. It can also warn that code uses an
-> java.lang.Object internal API and is not portable between Java environments
-> java.lang.String (and might break if run against a future version of Java).
-> java.lang.Thread Finally, lets look at the NetBeans IDE. The current ver-
-> junit.extensions.ActiveTestSuite$1 junit.jar sion already has support for a wide range of JDK 8 features,
-> junit.framework.Test junit.jar including Compact Proiles. When selecting which JDK or
-> junit.framework.TestCase junit.jar JRE to use in Project Properties, for JDK 8 and later, a devel-
oper can choose whether to compile against the full JRE or
If we want a slightly more high-level view, we can use -V a proile. This makes it much easier to ensure that when
package to show dependencies between packages, as shown youre targeting a particular proile, unwanted dependen-
in Listing 3 (some of the output was truncated because it was cies dont creep in. With luck, other IDEs will follow suit
1,297 lines long). and also add support to allow developers to write code in
the IDE that checks conformance with a speciic proile at
Listing 3. development time.
jdeps -V package junit.jar
junit.jar -> /Library/Java/JavaVirtualMachines/openjdk8/ A Word About Stripped Implementations
Contents/Home/jre/lib/rt.jar In addition to Compact Proiles, there was another tech-
junit.extensions (junit.jar) nique that was proposed but ultimately not included in Java 8:
-> java.lang Stripped Implementations. A Stripped Implementation was to
junit.framework (junit.jar) be a reduced JRE, which was packaged with an application that
-> java.io had the exclusive use of it. Because the application was the
-> java.lang only possible client for the Stripped Implementation, the run-
-> java.lang.annotation time could be aggressively pruned, removing packages, classes,
-> java.lang.reflect and even methods that were not used by the application.
-> java.util This approach was advantageous in circumstances where
junit.runner (junit.jar) resource limitations were severe. It relied on extensive test-
-> java.io ing to ensure that nothing that the application could rely
-> java.lang on was removed by the stripping process. In general, it is
-> java.lang.reflect extremely diicult to get a precise accounting of an applica-
-> java.text tions dependencies. This is due in large part to the existence
-> java.util of techniques such as relection and classloading, which can
greatly complicate (or even render impossible) the task of
jdeps is also very lexible about what it will accept as input: a ascertaining the true dependencies of a set of classes.
JAR ile, a directory, or a single .class ile. It provides capa- Compact Proiles are very diferent from Stripped
bilities for recursive traversal and for specifying that only Implementationsthe former are Java runtimes designed
58
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//the road to java 9 / //user groups /
for general-purpose use and are complete implementa-
tions of the Java language speciication, whereas Stripped
Implementations were deined to be single-use, nonreusable
THE PHILLY JUG
implementations that did not have to conform to the Java The Philadelphia Area Java
language speciication at their point of delivery to the user. Users Group (the Philly
Stripped Implementations were targeted as a feature for JUG) in Philadelphia,
Java SE 8, but due to some complications with licensing and Pennsylvania, is one the
the current testing kit, they had to be dropped very close to worlds oldest, largest,
the release date. and most active JUGs.
Operating continuously
Conclusion since 2000, the JUG has
[Java 9, which ships midyear, implements a whole new modu- been recognized twice
larity system based on Project Jigsaw. In most cases, that by Sun Microsystems as
modularity system does away with the need for Compact one of the top JUGs in the
Proiles and Stripped Implementations. This article, which world. From its humble beginnings with 35 members sitting
originally appeared in 2014 and has been lightly updated, on the loor of an abandoned oice, the JUG has grown to
shows how the drive to smaller executables has been a focus more than a thousand members. JUG meetings typically see
of the Java team for a long time. Going forward, Compact 70 to 100 developers attending on a regular basis. Over the
Proiles will remain a useful option only for projects that years, the JUG has hosted many Java luminaries, such as Neal
need the reduced executables but, for one reason or another, Ford, Brian Goetz, Cameron Purdy, Rod Johnson, Gavin King,
cannot migrate to Java 9. Ed.] </article> Marc Fleury, Greg Luck, Yakov Fain, and Kito Mann. The group
has a strong roster of regular local speakers. You can follow the
Ben Evans (@kittylyst) is a Java Champion, tech fellow and JUGs activities via its meetup group and its Twitter account.
founder at jClarity, an organizer for the London Java Community Topics at JUG meetings are always of interest to the pro-
(LJC), and a member of the Java SE/EE Executive Committee. fessional Java developer. Recent topics have included Java 9,
Adopt-a-JSR, RxJava, Java on Azure, and NAO robots. The JUG
has also been known to ofer more-general technology
concepts that have a Java (or JVM language) angle, such as
Docker, Spark, and Lagom. The JUG engages speakers and
learn more topics to help keep the local software engineering community
engaged and informed.
Compact Profiles Demonstrated The Philly JUG aims to further expand its reach and con-
Compact Profiles overview tinue to serve its local community. Among these eforts, the
Hinkmond Wongs EclipseCon 2014 presentation on JUG is an active adopter of critical Java SE and Java EE JSRs,
Compact Profiles including Java EE 8, Servlet 4, and Java SE 9. The JUG is an
active partner member of the Java Community Process.
59
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//build /

Gradles Java Library Management


As builds become more complex, library dependencies present a special challenge that
build tools are working to solve.

PETER LEDBROOK
B efore the days of Apache Maven and Apache Ivy, mak-
ing use of third-party libraries was a laborious afair.
Every time you wanted to include a library, you would have to
Consuming Third-Party Libraries
In an ideal world, you would declare your projects dependen-
cies and everything would just work. But this rarely happens
download manually not only its JAR but also any other JARs except in small projects. A more likely outcome is that you
that it depended on. You would then go through a similar would encounter one or more of the following issues:
process whenever you wanted to upgrade a library. Tracking An unexpected library version that breaks the build or your

down the necessary transitive dependencies could be particu- app/library


larly painful, as could identifying any dependencies you no Multiple versions of a library on a classpath

longer needed. Multiple JARs with the same class or classes

Both Maven and Ivy simpliied the process by allowing you Unwanted or unnecessary dependencies

to declare which dependencies you needed via a set of standard Dependency resolution that works for some developers but

coordinates: a group, a name, and a version. The tools took on not others
the responsibility of locating and downloading the necessary The sources of these issues are varied, ranging from poorly
JARs for youa process known as dependency resolution. Make deined metadata to changes in the names of dependencies.
no mistake, automatic dependency management (in addition to And dont underestimate the inherent challenge of keeping
a single public Java library repositoryMaven Central) funda- a system working that relies on perhaps hundreds of moving
mentally changed the way Java developers worked. parts, with each library having its own release schedule, time
This approach has been reined over the years, but what constraints, priorities, and so on.
you are using now is still at heart the same. In fact, you might Given that youre likely to encounter problems with
be forgiven for thinking that dependency management is a dependency resolution (unless you never change or upgrade
solved problem. any of your dependencies), its crucial that you be able to
Automatic dependency management introduced its own identify the underlying issues quickly. Thats why I think
set of issues that can bedevil developers. Build tools can developers deserve better diagnostic tools.
and should do more to help, because they are best placed to
improve the situation. If youre interested in learning what Diagnosing Dependency Issues
that help looks like, then read on as I investigate several You might think that tracking down the source of a version
common challenges of working with Java librariesboth conlict or some other dependency issue is simply a case of
third-party and your own. looking at the dependency graph. You can do this with most
60
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//build /
build tools, but remember that dependency graphs can be the current build and the last
large and complex. Trying to identify the source of a problem working one? This feature is Ideally, what you
in such scenarios is often elusive and frustratingeven if you available in Gradle Enterprise, need is some way
know what youre looking for.
Imagine you have added a library to your Hibernate 4
saving developers efort and
time in diagnosing many
to declare whether a
based project that, without you realizing it, has pulled in dependency issues. dependency is exposed
Hibernate 5. If youre lucky, your project continues to work Identifying the source of a in your components
regardless of which version of Hibernate the build tool
selects. Alternatively, the build or the running project might
dependency issue is only part of
the solution, because you still
API or not.
fail in a way that makes it obvious theres an issue with the need to ix it somehow.
version of the Hibernate library. In that case, you can run
Gradles dependencyInsight command (which is a built-in Fixing Dependency Issues
task) to ind out which dependencies transitively depend Build masters and developers traditionally resolve dependency
on Hibernate. problems using exclusions, a solution that reminds me of the
What if your project falls into neither category? What adage that when all you have is a hammer, everything looks
if, instead, the build or running project fails in a distinctly like a nail. Exclusions may solve the problem in practice, but
unhelpful way? In that case, the obvious question to ask is: theyre often fragile and time-consuming to maintain.
what changed? Unfortunately, build tools havent made it What you need is an expressive way to specify rules or
easy to answer that question in the past. constraints for the dependency resolution engine. Taking the
One workaround is to disable automatic conlict resolu- earlier Hibernate example, what you probably want to say is
tion, resulting in the build tool reporting an error if there is always use version 4.3.11.Final of Hibernate. You can do this
more than one version of a library in the dependency graph. with Gradle using the following build script snippet:
You can do this in Gradle by adding the following snippet to
your build ile: configurations.all {
resolutionStrategy {
configurations.all { force
resolutionStrategy { 'org.hibernate:hibernate-core:4.3.11.Final'
failOnVersionConflict() }
} }
}
This ensures that only the speciied version of the hibernate-
This approach unfortunately forces you to resolve even minor core dependency is included on your projects classpath.
version conlicts yourself. It also fails to help if a librarys You might also want to consider what happens if Hiber-
name or group has changed. nate 3 or 5 appears in the dependency graph. Do you simply
Wouldnt it be great if you could just ask the build tool want to force their versions as previously described? Or does
to show the diferences between the dependency graphs of it make more sense to add a warning or even fail the build
61
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//build /
because the libraries that depend in order to compile, which you would specify in Gradle as
on those versions are unlikely to Managing library
work with a diferent major ver- dependencies dependencies {
sion? You can implement any of these
approaches via Gradles resolution
at the build level is }
compile 'joda-time:joda-time:2.9.7'

strategy API. deceptively hard.


There is no single correct strat- This seems simple enough, so whats the problem? The law
egy for dependency resolution that is that this simple dependency graph ignores the consumers
works for everyone, which is why perspective. It doesnt answer the question: does core (the
Gradles API is so lexible. But most of the time, you probably consumer of date-utils) need joda-time in order to compile,
wont want to deal with it at a ine-grained level. Developers or is the date-utils module enough?
at Netlix have open-sourced two plugins that help by pro- Build tools currently play it safe and always include joda-
viding higher-level abstractions. The Nebula Resolution Rules time as a compile-time dependency of App. But this sim-
Plugin enables powerful, declarative, centralized resolu- ply pollutes the compilation classpath of core if date-utils
tion rules across your whole organization, while the Nebula doesnt expose any Joda Time types in its public APIthat is,
Dependency Lock Plugin solves the issues of build instability if the use of joda-time is an internal implementation detail.
and staging when using snapshot versions and version ranges Ideally, what you need is some way to declare whether a
(known as dynamic versions). dependency is exposed in your components API or not. You
Third-party libraries are only part of the story. Most sites will be able to do so from Gradle 3.4 onward. We are introduc-
also build and reuse their own libraries, which I discuss next. ing two new conigurations (or scopes, in Maven terminology)
for Java projects: api and implementation. As part of the new
Writing and Consuming Your Own Libraries Java library plugin, these conigurations will allow you to
With the advent of multiproject or multimodule builds, it has express the efect of dependencies on consumers.
never been easier to break your systems into several compo- Going back to the example in Figure 1, imagine that
nents. Your build tool manages the dependencies between the date-utils does expose Joda Time types in its public API.
individual components automatically, avoiding any manual Then you would declare the dependency in your date-utils
installation or publishing steps. build script this way:
Intermodule dependencies generally work well, but there
are still some important issues to consider. One of them is dependencies {
how to deal with libraries outside of the multimodule build api 'joda-time:joda-time:2.9.7'
a topic tackled in the previous section. Another is a funda- }
mental law in the way dependencies are speciied. For exam-
ple, consider the module relationships in Figure 1.
The arrows represent compile-time requirements, and App core date-utils joda-time
each box is a module you own, with Joda Time being the only
third-party library. In this case, date-utils needs joda-time Figure 1. Module dependencies in a multimodule build
62
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//build /
By declaring joda-time as an API dependency, you ensure that want to work from the source code version of a library that
it is included on the compilation classpath of core, because is not part of your multimodule build.
core requires date-utils to compile.
Now consider the relationship between date-utils and Improving Versioned-Library Workflows
core from the perspective of App. Does App need to be aware There is an interesting debate going on at the moment
of date-utils at compile time? In this case, lets assume regarding the relative merits of a monolithic repository
that date-utils is used purely internally by core. You would (monorepo), which is a single source code repository for all
express this in cores build script this way: your code, versus the more usual design, which relies on
separate repositories for diferent projects. Of particular
dependencies { relevance to this discussion of libraries is one of the declared
implementation project(':date-utils') beneits of a monorepo: easier cross-project changes.
} Consider this worklow:
You discover that the project youre working on requires a

What these two dependency declarations mean for the overall ix to a library it uses.
project is You ask that librarys team to implement the ix.

core has both date-utils and joda-time on its compilation You incorporate the ixed library into your project.

classpath In the case of a monorepo, you have access to the ixed ver-
App has date-utils and joda-time on its runtime classpath sion as soon as you update your local working copy or reposi-
but not its compilation classpath tory. And if you deploy of the trunk/master, you can deploy a
App requires core at compile time new version of your project with the ix right away.
This approach has several signiicant advantages: The process is less straightforward if the library is in a
JARs dont leak onto compilation classpaths when its diferent source repository. The typical solution involves get-
unnecessary for them to do so. ting the library maintainers team to publish a new version
Changing an implementation dependency doesnt force a of the JAR, often as a snapshot. But snapshots are notori-
recompilation of consumers. ously unreliable because the actual binary can change at any
Published POMs match the requirements of consumers. moment. So there is no guarantee that a given ix will appear
The relationships between components are clearer. in the next release version.
With respect to the published POM, Gradle uses a simple Another option is to check out or clone the source
mapping of api to compile and of implementation to runtime. repository for the library and build it locally. Then you
This mapping makes sense because a transitive api depen- become less dependent on the librarys team to publish
dency is required in order to compile the consumer, but thats updated versions. On the other hand, you still end up rely-
not the case for a transitive implementation dependency. ing on locally installed or published snapshotsunless you
Ive discussed consuming libraries so far, but only in are able to make your project depend on the librarys source
the context of dependency repositories and multimodule project, and then build them together. Adding a dependency
builds. There is one other scenario to consider: when you on the source distribution (rather than just an evolving

63
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//build /
binary) would give you the following advantages: problem, but you can solve it by persisting the build inclu-
You control exactly what code youre working against, via a sion deinition in your projects settings.gradle ile. This is
commit ID, tag, or some other label. explained on the Gradle blog. Just be aware that you should
You can make ixes yourself and test them without any use something like Git submodules or Subversion externals
intermediate steps. to ensure that your team members have a local copy of the
You dont need to rely on snapshots that can easily break librarys source when they build your project. Alternatively,
your project again. you can make the inclusion conditional on the library exist-
You can easily test in-progress work by updating your work- ing locally.
ing copy/repository. Its also worth thinking about how you manage the con-
You can achieve this with Gradles composite builds feature. It tinuous integration of your own libraries and applications
enables you to incorporate any other Gradle build into your that reside in separate source repositories. With Gradle, you
own, dynamically replacing the corresponding declared can create a composite build for your continuous integra-
dependencies. tion servers that includes only the builds you needits
To understand how it works, think back to Figure 1 and otherwise emptyand runs all the integration tests. Both
imagine you need a ix for the Joda Time library. Also imag- the application and the library teams then get immediate
ine that it has a Gradle build. The maintainer is too busy to feedback on any breaking changes without having to publish
implement the ix, so you get hold of the source code project intermediate binaries.
and put it alongside or even inside your projects root direc- Composite builds smooth the development process and
tory. Then you can apply the necessary changes yourself. buy time for teams to coordinate releases where necessary.
Now, rather than building joda-time separately and While this discussion involved separate repositories, you can
installing or publishing its JAR, you can run also use this feature with a monorepo if you want to use that
architecture while retaining independently versioned libraries.
./gradlew --include-build ../joda-time-copy build
Conclusion
This will automatically build the project at ../joda-time- Managing library dependencies at the build level is decep-
copy and put its JAR on the compilation classpath of date- tively hard, as anyone who has worked extensively with them
utils when it builds that, even though the latter declares a will attest. In this article, Ive presented several of the chal-
versioned dependency of joda-time. Even better, your tests lenges that Java developers and build masters face. Many
will run against this development version of joda-time of you have probably encountered at least some of these in
as well. This approach greatly improves the development your own day-to-day work. The ultimate goal of the build
cycle for cross-project changes and works particularly well tool developer is to make dependency management truly
with the IDE support in IntelliJ and Eclipse, which uses the manageable. </article>
Buildship plugin.
One other consideration is how you share your work with Peter Ledbrook is an independent consultant who has maintained
other team members without having to publish intermedi- many builds over the years, including ones based on Make, Ant, and
ate versions of the library for them to use. Its an awkward Maven. He now does training and technical writing for Gradle Inc.
64
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//java proposals of interest /

FEATURED JAVA SPECIFICATION REQUEST

JSR 372: JSF 2.3


JavaServer Faces (JSF) 2.3, which is governed by JSR 372,
recently ended its public comment period. This event
lets us see what is new in mostly a minor update from
version 2.2. It includes the addition of incremental fea-
tures that the community requested. The community Register Now
has driven JSF 2.3 very heavily, directly committing
many of the features into the codebase of the reference
implementation, Mojarra. These are the features slated
to be in JSF 2.3:
Alignment with the Java SE 8 Date and Time API
Oracle Code
Improved CDI support
New One-Day, Free Event | 20 Cities Globally
Formal deprecation of the JSF-speciic bean subsystem

in favor of CDI
WebSocket integration Explore the Latest Developer Trends:
Ajax method invocation

Multiield validation
DevOps, Containers, Microservices & APIs
Besides these changes, there are many other smaller
MySQL, NoSQL, Oracle & Open Source Databases
updates. For details on these, check out the speciication
document itself. There is a useful change list at the very Development Tools & Low Code Platforms
beginning of the PDF document. The community has
Open Source Technologies
been doing a good job blogging about JSF 2.3 features
particularly folks such as Arjan Tijms and Anghel Machine Learning, Chatbots & AI
Leonard. In addition, the July/August 2016 issue of Java
Magazine had a detailed explanation of the new features,
written by Tijms, who is on the expert group for this JSR. Find an event near you:
Download the draft speciication from the JCP site. developer.oracle.com/code
Do your part by engaging actively. Try out the new ver-
sion and provide comments on the new features.
[Thanks to Reza Rahman for his contributions to
this write-up. Ed.]
65
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ix this /

Quiz Yourself
Intermediate and advanced test questions

SIMON ROBERTS
A s promised in my last column, with this issue, I begin to
include questions that simulate the level of diiculty of
the Oracle Certiied Associate exam, which contains questions
Which two of the following are true?
a. The array referred to by sba might be eligible for garbage
collection at line 19.
for a more preliminary level of certiication than the ques- b. The array referred to by sba might be eligible for garbage
tions that regularly have appeared here. collection at line 21.
Of course, I also include the more advanced questions c. Assigning sba = null; at line 21 would make the array
that simulate those from the 1Z0-809 Programmer II referred to by sba and the three StringBuilder objects
exam, which is the certiication test for developers who deinitely eligible for garbage collection.
have been certiied at a basic level of Java 8 programming d. The array referred to by sba and the three StringBuilder
knowledge and now are looking to demonstrate more- objects will deinitely be eligible for garbage collection
advanced expertise. when the method returns to its caller.
Because there is little value in asking easy questions, I e. The array referred to by sba and the three StringBuilder
provide only intermediate and advanced questions (and they objects might not be eligible for garbage collection even
are marked as such). These levels correlate with the two after the method returns to its caller.
exams. However, dont let the intermediate tag fool you
the questions are never trivial. Question 2 (intermediate). Given the following code:
// line n1
Question 1 (intermediate). Given this code (with line numbers switch (x) {}
at left), which is a fragment of a larger method body:
14: StringBuilder[] sba = { Which two of the following lines of code can be added success-
15: new StringBuilder("Fred"), fully at line n1? Assume that x has no declaration in scope at
16: new StringBuilder("Jim"), line n1 and assume that each line is added individually.
17: new StringBuilder("Sheila") a. boolean x = false;
18: }; b. short x = 99;
19: c. int x = 0;
20: System.out.println("sba[2] is " + sba[2]); d. long x = 0;
21: e. StringBuilder x = new StringBuilder("x");

66
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ix this /
Question 3 (advanced). Given this: Recorder$LongRecord@816f27d
public class Recorder {
class Record {} c. Changing the argument type declaration at line n1 to
class LongRecord extends Record {} Collection<? super Record> produces output in the
following form:
public List<LongRecord> gatherRecords() {
return Arrays.asList( Recorder$LongRecord@1218025c
new LongRecord(), new LongRecord() Recorder$LongRecord@816f27d
);
} d. Changing the argument type declaration at line n1 to
Collection<? extends Record> produces output in the
public void processRecords( following form:
Collection<Record> records) { // line n1
records.forEach(System.out::println); Recorder$LongRecord@1218025c
} Recorder$LongRecord@816f27d

public void gatherAndProcess() { e. Changing the variable type declaration at line n2 to


List<LongRecord> lr = gatherRecords(); // line n2 List<Record> produces output in the following form:
processRecords(lr);
} Recorder$LongRecord@1218025c
Recorder$LongRecord@816f27d
public static void main(String[] args) {
new Recorder().gatherAndProcess(); Question 4 (advanced). Given this code:
} List<String> ls = Arrays.asList("Fred", "Jim", "Sheila",
} "Fred");
Set<String> s1 = new HashSet<>(ls); // line n1
Which is true? Choose one. Set<String> s2 = new TreeSet<>(ls); // line n2
a. The code produces output in the following form: System.out.println(s1.equals(s2));

Recorder$LongRecord@1218025c What is the result? Choose one.


Recorder$LongRecord@816f27d a. Line n1 causes compilation to fail.
b. Both line n1 and line n2 cause compilation to fail.
b. Changing the argument type declaration at line n1 to c. An exception is thrown at line n1.
List<Record> produces output in the following form: d. Outputs true.
e. Outputs false.
Recorder$LongRecord@1218025c
67
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ix this /
Options D and E are, perhaps obviously, the inverses of
Answers one another, so one must be true and the other false. As a
side note, exam creators try to avoid this sort of situation
because it makes a question easierbut sometimes it is
unavoidable, so it is worth spotting inverse answers. Be sure
your logic is sound, though. For example, if option E had
Question 1. The correct answers are options C and E. The basis said deinitely not eligible, the two would not have been
on which an object is eligible for garbage collection is sim- inverses of each other, because the important possibility
ply that it cannot be reached from any live thread. In other of dont know would be a third possibility not covered
words, the program can never get hold of the object again. by either.
At line 19, sba is an entirely valid reference to the original In this case, because one or the other must be true,
array. Consequently, sba is deinitely not eligible for collec- either you can deinitely collect the objects at the return of
tion at that point. Thats really important because if it were the method or you cannot be sure. Which is it? Generally,
collected, the attempt to print sba[2] on line 20 would have local variables go out of scope and cease to exist when a
unpredictable results. Generally, Java avoids any unpredict- method returns. This would suggest that the objects referred
able behaviors (concurrent programming is the signiicant to by those variables become eligible for garbage collection.
exception to this). This means that option A is incorrect. However, in this case, you dont see the whole method body.
Similarly, although sba does not appear to be used again If a reference to the array escapes from the method, you
at or after line 21, it is deinitely not eligible for garbage col- can make no such assumption. At least three mechanisms
lection because the reference is still valid, and it could be exist by which this escape might occur, the most obvious of
used later in the method. Note that the question explicitly which is probably when the method itself returns the value
states that there is more to the method. Therefore, option B is of sba to its caller. A second possibility is that this method
also incorrect. stores the value of sba in a variable that has greater visibility
However, if line 21 executes sba = null;, the previous and longer life, such as a static variable or collection. In addi-
value of the reference is overwritten. Because the now-lost tion, passing sba as a method argument might allow the value
value in sba was the only reference to the array created to escape, because you cannot know if that method stores the
in lines 14 through 18, and that value was never stored any- value somewhere in a manner similar to the previous point.
where else (not even as an argument to a method call) As a result, you cannot know if the array and, therefore, the
between its creation and line 21, you know that there are now three StringBuilder objects are eligible for garbage collec-
zero references to that object that are available to the pro- tion. Consequently, option E is true and option D is false.
gram. As a result, the array is deinitely unreachable and is
eligible for garbage collection. Also, references to the three Question 2. The correct answers are options B and C. The
StringBuilder objects were written only into the array, and rules for a switch statement require that the argument
because the array is not reachable in the program, neither are be assignment-compatible with an int (allowing for auto-
the StringBuilder objects, and they, too, are eligible for gar- unboxing), an enum, or a String. Java Language Speciication
bage collection. Because of this, option C is correct. section 14.11 states that the type of the expression must be
68
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ix this /
char, byte, short, int, Character, Byte, Short, Integer, String, Option B suggests that by changing the argument type from
or an enum type, or a compile-time error occurs. String and Collection to List, you might ix it. However, a List is fully
enum types havent always been allowed; enum was new capable of substituting for a Collection (the List inter-
with Java 5. Therefore, it didnt apply before that and, in fact, face extends Collection, and all the methods are imple-
String was not legal until Java 7. mented). This part of the assignment is not the problem, and
Although String is a legal type for a switch statement, the change wouldnt alter the situation. Therefore, option B
StringBuilder is not; neither is it assignment-compatible is incorrect.
with String. Consider the following, because its a little less confus-
Because of these rules, options A, D, and E are all incor- ing. The compiler thinks that a List<LongRecord> is not a
rect, while both options B and C are correct. valid substitute for a List<Record>. Theres something that
you can do with a List<Record> that isnt properly sup-
Question 3. The correct answer is option D. This question ported by a List<LongRecord>. That illegal operation is
delves into one of the most startling consequences of the the addition of a Record. Think about that for a moment.
type-erasure mechanism of Javas generics system. When A List<LongRecord> can properly contain anything thats
a variable of a collection type is declared with its generic assignment-compatible with a LongRecord: that would be
speciicationas in something like List<Record>the LongRecord objects and any subclasses thereof. However, it
Record part of the information exists only at compile time. should not contain any instances of the parent class Record.
The underlying object is still a List that actually accepts And it should not contain any sibling classes of LongRecord,
any object type. The power of generics is that they allow the if they existed. However, a List<Record> can legitimately
compiler to do consistency checking that can ensure that contain such objects, and the compiler doesnt know that you
type errors cannot happen in the code. dont add any in the method declared around line n1. Imagine
As part of the consistency checking, the compiler veri- the consequences if the method, prior to looping over the
ies that all assignments are safe from the perspective of contents of Collection, invoked records.add(new Record()).
the Liskov Substitution Principle. This is a principle in object That would be bad, right?
orientation that requires that if you assign b = a, a must be The code does not actually do any such terrible opera-
capable of fully substituting for b. That is, all the behaviors tions, but the compiler doesnt analyze that; it just knows
expected of the type of b must be properly implemented, and that the code could. Fortunately, theres a syntax that lets you
work as expected, in the object referred to by a. do what you want to dothat is, iterate over the contents of
Now, the trick here is that, in fact, the compiler does the collection, safely extracting things from it while know-
not accept that assigning a List<LongRecord> to a Collection ing theyre assignment-compatible with Record. In efect, you
<Record> is a valid substitution. Because the assignment deine that Collection can be a collection of anything thats
that occurs in the invocation of the method declared around assignment-compatible with Record. Therefore, if X is a type
line n1 is not valid, the code does not compile and option A thats assignment-compatible with Y, X must be further
is incorrect. down the inheritance hierarchy (regardless of whether it is
This question really hinges on why that assignment an object or an interface) than Y. In a sense, X extends Y. And
is not valid, and how you might correct that problem. thats how the syntax comes about; the language lets you say,
69
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//ix this /
in efect, collection of something, provided that something this, both options A and B are false.
extends Record. (Note that in this sense, Record extends Option C suggests that an exception is thrown during
Record because its assignment-compatible.) That syntax, construction of the Set. This might be plausible, given that
of course, is Collection<? extends Record>. On that basis, the List has a duplicate entry, which is not permitted in a
option D is correct. Set. However, the documentation notes that all construc-
Option C is also interesting. In this situation, the pro- tors must create a set that contains no duplicate elements.
posed change would say that whatever Collection is intended The efect is that both Set objects contain only the three
to contain, Record must be assignment-compatible with distinct elements, "Fred", "Jim", and "Sheila". Its also fair
that. If you presented a collection of Object, then Object is to observe that, in general, a Set recognizes and ignores
a superclass of Record, and youd be able to insert the Record attempts to add duplicates, so an exception in this initial-
safely into Collection. However, you have no idea what types ization situation would be unhelpful and counterintuitive.
you might pull out of Collection, which might be a problem. Because no exception is thrown, option C is false.
But regardless of this, you still cannot pass List<LongRecord> As a side note, its possible for a TreeSet to throw an
into the method, because List<LongRecord> could not prop- exception during the addition of items, if the items being
erly accept assignment of a Record into List even if you added to it are not Comparable and no suitable Comparator
wanted to do that. Therefore, this syntax doesnt solve the has been provided. In this case, however, the items
problem at hand, and option C is incorrect. However, this is being added are String objects, and String implements
an important syntax when you want to assign things to the Comparable<String> as needed, so no such problem arises.
generic type of whatever is passed in. Having eliminated all the other options, options D and
Option E fails for the same reasons the code fails in E are essentially alternatives. The interesting thing here is
its unchanged form. The return type of the gatherRecords that the documentation for the equals method of Set requires
method is List<LongRecord>, and thats not assignment- that all implementations return a value that indicates only
compatible with List<Record>. Therefore, changing the vari- whether the contents of the set are the same, without regard
able type on line n2 would fail to compile, even though it to the implementing class. As the documentation notes fur-
would allow the invocation of the method around line n1 to ther, This deinition ensures that the equals method works
compile. Substituting one problem for another doesnt result properly across diferent implementations of the set inter-
in any output, though, so option E is incorrect. face. As a result, the output is the value true, and option D is
correct, while option E is incorrect. </article>
Question 4. The correct answer is option D. Options A and
B suggest compilation failures while attempting to con- Simon Roberts joined Sun Microsystems in time to teach Suns
struct and initialize the sets. This might happen if there is irst Java classes in the UK. He created the Sun Certiied Java
no constructor available that accepts a List as an argument. Programmer and Sun Certiied Java Developer exams. He wrote
However, both Set types provide such a constructor. The several Java certiication guides and is currently a freelance edu-
documentation for collections calls for collection implemen- cator who teaches at many large companies in Silicon Valley and
tations to provide constructors that accept an argument of around the world. He remains involved with Oracles Java certiica-
type Collection, and as a result, a List is valid. Because of
tion projects.
70
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017
//contact us /

magazine
By and for the Java community

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 our
Unless you speciically tell us that your at javamag_us@oracle.com and well decision whether to publish your article
correspondence is private, we reserve give you our thoughts on the topic and or letter, cookies and edible treats will
the right to publish it in our Letters to send you our nifty writer guidelines, be gratefully accepted by our staf at
the Editor section. which will give you more information Java Magazine, Oracle Corporation,
on preparing an article. 500 Oracle Parkway, MS OPL 3A-3133,
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.

71
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017

You might also like