Professional Documents
Culture Documents
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.
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
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.
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
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 /
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.
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.
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.
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)
/** 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;
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));
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());
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
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.
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 /
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
reduces the attack surface of the platform Removes functionality that is not always needed (for exam-
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 /
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
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'
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 /
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
magazine
By and for the Java community
71
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// MARCH/APRIL 2017