<<

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

MARCH/APRIL 2017

magazine

By and for the Java community

UI Tools 17 24 30 40 SCRIPTING VISUAL DESIGN MVC 1.0: BUILDING 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 flexible Using Oracle’s 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 Andrés Almiray Gain greater flexibility in defining 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 Gradle’s Java Philly JUG languages to be successful means that By Gastón 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 devices—in this case, from drones. consider monolithic repos—library 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 Need smaller executables? Migrate to Here’s how. Upcoming Java conferences and events Fix This Java 9. Can’t migrate? Then consider By Simon Roberts 14 Java 8’s Compact Profiles. 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 Sales Director Senior Creative Director Tom Cometa The brightest minds in Francisco G Delgadillo Account Manager Design Director Mark Makinney Richard Merchán 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 [email protected] Phone +1.847.763.9635 for all—or even part—of 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 interviewees—even if they are Oracle employees—do 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 Oracle’s products remains at the sole discretion of Oracle. Oracle and Java are registered trademarks of and/or its 20% OFF WITH CODE JAVA affiliates. Other names may be trademarks of their respective owners. Java Magazine is published bimonthly and made available at no cost to qualified subscribers by 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 or the last 18 months, we at Java Magazine guages (such as the JRuby port of Ruby and the Gateway is the best place F have been covering all sorts of interesting JVM port of Python) and those that are built to jump-start your modern languages—from the well known to the obscure. from the ground up for the JVM (Groovy, Kotlin, 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. That’s 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 implemented—often Trials. Downloads. The benefits of the JVM include performance, for specific reasons. Other times, the languages Tutorials. Start here: wide availability and familiarity, excellent tools, lead to Java’s adoption of features, in which case developer.oracle.com and thorough documentation. In addition, there’s the Java team has the benefit of examining those a high level of confidence 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 won’t suddenly need to find a new platform in its longtime production of the JVM Language (as those that targeted , 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 financial 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 Geoffrey Moore’s book of the same is promoting it. While originally an efficiency 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 until the company realized—as a significant and active commu- Level Up at visionaries and early adopters into Pivotal did with Groovy—that nity, which accelerates its move- 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 filled numerous niches where not even mention the language in the company’s own desires for quick but expressive coding is the body of the announcement. the language. Get on the list needed. It is the scripting language As I said, there’s just no money Because economics support for event updates: for many testing frameworks and in languages. Kotlin’s evolution and JetBrains’ 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 a—or possibly the—primary (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 benefits of developing ing yet again the robustness of the lar long before Pivotal’s 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- [email protected] #developersrule skills of the project’s longtime ever, are significant. According to @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 /

| | JavaScript in Java Magazine guages are compiling to JavaScript. It has been exactly LOCAL-VARIABLE TYPE INFERENCE 60 SCALA 47 BLOCKCHAIN 36 JANUARY/FEBRUARY 2017 We received more than 30 replies to our request in the two years since Scala.js went from a science proj- 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 Kotlin’s type system able to TOOLS impersonate JavaScript. 17 22 29 Lots of It! I’m not an Android developer, but my wife is an POLYGLOT: INSIDE THE BUILD YOUR OWN MOVING MAVEN ARCHITECTURE JVM DEBUGGING PAST XML OF BUILD TOOLS TOOLS Yes, please include a regular column on JavaScript. It iOS developer who works closely with Android and

ORACLE.COM/JAVAMAGAZINE can be arbitrarily large! web developers to keep their code in sync. Naturally JANUARY/FEBRUARY 2017 I have been a Java for 16 years. Two they use JavaScript on all three platforms, and I’ve 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 there’s 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 I’ be fascinated to see a deep dive comparing the that does not have interfaces, like Java has. tradeoffs between JITs from HotSpot, Dalvik, and the I feel really curious to learn how Java program- various JavaScript JITs. But maybe that’s just me. mers with a similar mindset find 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 first thought after reading your editorial was, “I’d ers the polyglot issues discussed in the editorial, with read it, but I don’t 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. There’s a fine line between focusing on one thing and pretend- —Marcos André Pisching ing everything else doesn’t exist. Professor de Informática no Campus Lages do IFSC That’s 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 files.” 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, we’ll begin settings.gradle files is if you’re 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, we’ll be care- a multi­module project, only ever has a single settings ful to keep in mind the recommendation of reader William .gradle file. 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 don’t want sible to “define multiple projects in one build file.” it to lose itself.’” This is also possible in Gradle, and it’s quite common. I certainly think it’s 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 it’s 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 Cédric Beust responds: “You are correct that most projects usually have one settings.gradle file, but that file 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 Gradle’s project itself.” is set to zero? —Elton DePaula Contact Us We welcome comments, suggestions, grumbles, kudos, Author Conor Svensson responds: “It’s 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 [email protected]. 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, Cédric Beust wrote, “With Gradle, you need to manipulate multiple build.gradle files 07

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

//events /

JavaLand gies, frameworks, and tech- MARCH 28–30 niques. Past presentations BRÜHL, 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 Doesn’t 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 O’Reilly Software include agile and company Architecture Conference culture, cloud platforms, con- GREAT INDIAN DEVELOPER SUMMIT APRIL 2–3, TRAINING tainer technologies, continu- APRIL 25–28 APRIL 3–5, TUTORIALS ous delivery and automation, BANGALORE, INDIA AND CONFERENCE microservices, and real-world The Great Indian Developer Summit (GIDS), now in its 10th year, offers 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. There’s 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 Office,” examines all aspects development models, and DevOps. of the smart home or office: con- Workshops are offered 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.) Network—a global community whose mission is to build a global Devoxx UK IoT data network—is hosting its MAY 11–12 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 15–17 APRIL 5, WORKSHOPS to cloud computing. (No English network with tech companies RIGA, LATVIA APRIL 6–7, 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 shops, tutorials, and keynotes APRIL 19 MAY 9–11, 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 Europe’s 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 17–19 annual conference focuses on developers, as well as engineers, JUNE 26–28, CONFERENCE KRAKOW, POLAND Java technologies for application architects, and UI/UX designers. JUNE 29–30, WORKSHOPS The GeeCON conference focuses development. This year offers five 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 influ- conference sessions cover topics ern approaches in the develop- JUNE 21–22, 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 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 30–31 research organizations gather to JULY 16–21 MAY 17, WORKSHOPS SOFIA, BULGARIA share their expertise. The two- KOLYMBARI, GREECE MAY 18–19, 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 21–23 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 O’Reilly Fluent Conference from 20 different countries at bring their families. Champion Martin Thompson and JUNE 19–20, TRAINING this installment of the popular Director of Developer Experience JUNE 20–22, TUTORIALS Devoxx conferences. Tracks on ÜberConf at Red Hat Edson Yanaga. AND CONFERENCE server-side Java, cloud and big JULY 18–21 SAN JOSE, CALIFORNIA data, JVM languages, web and DENVER, COLORADO JEEConf Fluent offers practical train- HTML5, and more are on offer. ÜberConf 2017 will be held at the MAY 26–27 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 1–5 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, latest development technologies, SEPTEMBER 12, WORKSHOPS JavaOne is the ultimate source of SEPTEMBER 13–14, CONFERENCE technical information and learn- practices, and trends, including OSLO, NORWAY ing about Java. For five 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 NoSQL databases. an additional day of workshops Java and JVM topics. beforehand. You will be joined by US AND CANADA ASIA PACIFIC approximately 3,000 of your fel- Are you hosting an upcoming MARCH 27, Washington DC MAY 10, New Delhi, India low Java developers. Included in Java conference that you would 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 29–OCTOBER 1 EUROPE AND MIDDLE EAST [email protected]. Other AUGUST 30, Seoul, South BOSTON, MASSACHUSETTS APRIL 20, London, England ways to reach us appear on the Korea Since 2001, the No Fluff Just Stuff 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 events with more than 70,000 JUNE 27, São Paulo, Brazil 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 don’t know fully understand her point because focuses on books, in this issue we the syntax for lambdas or under- you’re 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- you’ll quickly find yourself stum- other complaint is that Gee lets the sion of Pearson, the company bling as you try to follow along. In IDE (IntelliJ) find refactorings and behind Addison-Wesley and other this sense, the video is tremen- implement them, so they’re 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 files. All After presenting the refactor­ it would be easier to follow if we told, they represent several hours of ings, Gee cleverly spends a signifi- 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 fill 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 It’s 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 Gee’s 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 you’ll 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

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 find it to be the most annoying task in program- source and taken over by Gluon, which has been maintaining it ever since. ming—surpassing even fixing Aunt Thelma’s printer because, Front ends to web applications have their own unique needs, and we you know, you’re 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, Dparamount 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. You’ll also find 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 finally, we stantly recoded. Fortunately, revisit a topic we’ve covered JavaFX greatly facilitated UI before: compact profiles in construction by scripting it with Java 8 (page 56). In addition, of FXML, which is discussed in our course, we offer our usual quiz— first 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 exam—as 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 ANDRÉS ALMIRAY the FXML loader mechanism.

he JavaFX UI toolkit delivers a refreshing and modern You have probably seen FXML before, but in case you T set of APIs that can be used to build desktop and mobile haven’t, here’s a quick sample. The following code snippet applications that target the JVM. Similar to its predecessor, defines a grid in which six UI elements are placed in a , 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- ings, styling support via CSS, and a UI description format named FXML. As the name implies, it’s an XML-based format that enables developers to define user interfaces in a declara- tive way, as opposed to defining interfaces by procedural means—that is, by directly using the JavaFX APIs. The following benefits are some of the advantages of choosing FXML over the programmatic API:

self.getData = function () { 44

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////// MARCH/APRIL 2017 //ui tools /

// using a Promise to allow the chart to (CRUD) data—Oracle JET // render only once the data is available. provides a Common Model Oracle has used Oracle JET self.seriesValue(new Promise( API that simplifies working as the foundation for more function (resolve, reject) { with multiple types of data than 70 percent of its var url = sources. You can read more "https://api.data.gov/nrel/alt-fuel-stations" + about the Common Model new cloud service offerings. "/v1/nearest.json?location=" + API in the “Framework” + self.cityVal() + "+" + self.selectVal()+ section of the Oracle JET "&api_key="; 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 configuration steps are included in the README file 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 })) offerings—so 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 developer’s 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 specification (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 or engage with other developers on way to consume and interact with remote data is via web the Oracle JET Community site. 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 interactions—such as those used (McGraw-Hill, 2014), a two-time winner of the JavaOne Rock Star Award, and the senior product manager for Oracle JET. in applications that need to create, read, update, and delete 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 devices—in this case, from drones.

GASTÓN HILLAR Q Telemetry Transport (MQTT) is a lightweight publish- Things (IoT), and it is gaining popularity in mobile and web M subscribe messaging protocol, especially suitable for applications. MQTT is a protocol that works with a publish- small devices but also useful for any device that requires mes- 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 offer 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 specific drones to dis- can use Mosquitto to make any device subscribe to a spe- play their altitude in feet. I use the asynchronous methods cific 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 offers 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 different 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 don’t 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 through a direct connection. firewalls allow the application or the IDE to work with TCP in code simpler. 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 the MQTT broker. At the time of this writing, the latest release of Paho Java a client and the broker—in 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 in the pom.xml file. I’m 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 file 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 specific drones. its Maven plugins to add the repository and the dependency. It is possible for any client to subscribe to a specific topic. By doing so, it will receive all the messages published to that topic. In addition, the client can publish messages to that specific topic or to other topics. In my example, I work with Eclipse Paho Repo just one topic, and I won’t take advantage of the wildcards https://repo.eclipse.org/content/ that allow you to work with many topics at the same time. repositories/paho-releases/ However, once you understand how to work with the Java client, you can use the sample code to take advantage of the additional features, based on your specific needs. I don’t want to focus on the configuration of a Mosquitto message browser. Instead, I want to put my efforts into dem- org.eclipse.paho onstrating how to publish and receive messages. Eclipse allows you to use a publicly accessible sandbox server for the Eclipse org.eclipse.paho.client.mqttv3 IoT projects at iot.eclipse.org port 1883 identified with the fol- lowing URI: tcp://iot.eclipse.org:1883. I will use this sandbox 1.1.0 server as the Mosquitto message broker, without any security. That way, you don’t have to lose time setting up a Mosquitto 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 defined in org.eclipse this.userContext = userContext; .paho.client.mqttv3. There is no type in these interface } names—the naming convention for interfaces in the Java library is a bit confusing because some interfaces start with @Override I while others don’t. I use Drone instances as callbacks for public void onSuccess( specific 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 was successfully the message. Delivering a message involves publishing from to be published, the message 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 fields that quality of service (QoS) guarantee as the TCP protocol. The message is not acknowl- have the same names as the 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 isn’t received within a specific 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 isn’t 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 flows 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 flow 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 don’t 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; configure 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 defines 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 defines a command key, the lished by my code. I have specified "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 { shouldn’t 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 specific 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. I’ll 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 specifies "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 specific 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 won’t 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 specific drone has been successfully subscribed to the // The method will run if an operation failed specific 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 field. This messageText.getBytes(ENCODING); way, I am able to check whether the onSuccess method’s 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 specific 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 specifies this as the last argument } catch (UnsupportedEncodingException e) { because I will also use the actual instance as the callback e.printStackTrace(); that will execute specific 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 specifies 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); specified 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 class—drone1, drone2, and First, the code makes sure that the topic is the one that masterDrone—and calls the connect method for each of these the drone is interested in. Then, the code calls the message instances. I didn’t 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 specific 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 prefix, the code decodes the command Drone drone2 = new Drone("[Drone #2]"); and if it’s 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, I’m working int r = with QoS level 2 and this method will be executed after the ThreadLocalRandom.current() acknowledgment from the receiver arrives. Here, I didn’t 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 five 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.

Gastón Hillar (@gastonhillar) has been working as a software architect with Java since its first 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 8’s Compact Profiles point the way to Java 9’s modularity.

BEN EVANS ava 8 introduced the concept of Compact Profiles, which ■■ Allow application developers to package their code as mod- Jare reduced versions of the Java runtime environment ules, rather than as JAR files. (JRE) that do not contain the usual full contents of rt.jar. In The catch is that in order to achieve the full set of goals, this article, I explore the advantages of using Compact Profiles 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 classloading—involving a “modular JDK, which takes a big step forward in Java 9. classloader”—is 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 Profiles are designed to be great benefits: a first 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, shouldn’t be in ■■ Is fully compliant with the JVM and Java language the core specifications ■■ 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) Configuration (CDC) with Java SE ■■ Works for many applications (especially server-side code) The initial approach to this effort was a full modularization of Compact Profiles 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 profile must form a closed set; references to classes not form core, and apply lessons learned about dependency contained in the profile are not allowed. management from tools such as Maven, Apache Ivy, OSGi ■■ If a profile contains some classes from another, smaller pro- standard, and Linux distributions. file, it must contain all of them, so partially overlapping pro- PHOTOGRAPH BY JOHN BLYTHE ■■ Isolate dependencies—solve the library versioning problem. files are not allowed. Put another way, profiles are additive. 56

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////// MARCH/APRIL 2017 //the road to java 9 /

The smallest Compact Profile is called compact1, and it com- jdeps have been modified to be aware of profiles. 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 specific pro- .lang.reflect, java.math, java.net, java.nio, java.nio file. This is achieved by using the new -profile switch. .channels, java.nio.channels.spi, java.nio.charset, java javac -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 profile. 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, cific class or JAR file. This tool is extremely useful (and not java.util.stream, java.util.zip, javax.crypto, javax just for profile 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 profiles. .security.auth.callback, javax.security.auth.login, Let’s 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 Profiles are specified 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 profile, compact1, occupies around 11 MB, which is a significant 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 specified, all of these profiles are headless; class inside the JAR file. 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 Profiles, developers require tools. junit.jar -> /Library/Java/JavaVirtualMachines/openjdk8/ One important question is whether an application can run Contents/ against a specific profile. 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, let’s 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 Profiles. 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 profile. This makes it much easier to ensure that when package to show dependencies between packages, as shown you’re targeting a particular profile, unwanted dependen- in Listing 3 (some of the output was truncated because it was cies don’t 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 specific profile 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 Profiles, 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 Imple­men­tation 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 difficult to get a precise accounting of an applica- -> java.text tion’s dependencies. This is due in large part to the existence -> java.util of techniques such as reflection and classloading, which can greatly complicate (or even render impossible) the task of jdeps is also very flexible about what it will accept as input: a ascertaining the true dependencies of a set of classes. JAR file, a directory, or a single .class file. It provides capa- Compact Profiles are very different from Stripped bilities for recursive traversal and for specifying that only Implementations—the 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 specification, whereas Stripped THE PHILLY JUG Implementations were defined to be single-use, nonreusable implementations that did not have to conform to the Java The Philadelphia Area Java language specification 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 world’s 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 as modularity system does away with the need for Compact one of the top JUGs in the Profiles 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 floor of an abandoned office, 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 Profiles 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.] 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 JUG’s activ­ities 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 offer more-general technology concepts that have a Java (or JVM language) angle, such as learn more Docker, Spark, and Lagom. The JUG engages speakers and 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 efforts, the Hinkmond Wong’s 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 . 59

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////// MARCH/APRIL 2017 //build / Gradle’s Java Library Management As builds become more complex, library dependencies present a special challenge that build tools are working to solve.

PETER LEDBROOK efore the days of and Apache Ivy, mak- Consuming Third-Party Libraries Bing use of third-party libraries was a laborious affair. In an ideal world, you would declare your project’s dependen- Every time you wanted to include a library, you would have to 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 simplified 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 you—a process known as dependency resolution. Make defined metadata to changes in the names of dependencies. no mistake, automatic dependency management (in addition to And don’t underestimate the inherent challenge of keeping a single public Java library repository—Maven 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 refined 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 you’re 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), it’s crucial that you be able to Automatic dependency management introduced its own identify the underlying issues quickly. That’s 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 you’re 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 libraries—both conflict 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 frustrating—even if you available in Gradle Enterprise, need is some way know what you’re looking for. saving developers effort and to declare whether a Imagine you have added a library to your 4– time in diagnosing many based project that, without you realizing it, has pulled in dependency issues. dependency is exposed Hibernate 5. If you’re lucky, your project continues to work Identifying the source of a in your component’s regardless of which version of Hibernate the build tool dependency issue is only part of API or not. selects. Alternatively, the build or the running project might the solution, because you still fail in a way that makes it obvious there’s an issue with the need to fix it somehow. version of the Hibernate library. In that case, you can run Gradle’s dependencyInsight command (which is a built-in Fixing Dependency Issues task) to find 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: they’re often fragile and time-consuming to maintain. what changed? Unfortunately, build tools haven’t 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 conflict 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 file: configurations.all { resolutionStrategy { configurations.all { force resolutionStrategy { 'org.hibernate:hibernate-core:4.3.11.Final' failOnVersionConflict() } } } } This ensures that only the specified version of thehibernate- This approach unfortunately forces you to resolve even minor core dependency is included on your project’s classpath. version conflicts yourself. It also fails to help if a library’s 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 Wouldn’t it be great if you could just ask the build tool want to force their versions as previously described? Or does to show the differences 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 different major ver- dependencies dependencies { sion? You can implement any of these at the build level is compile 'joda-time:joda-time:2.9.7' approaches via Gradle’s resolution } strategy API. deceptively hard. There is no single correct strat- This seems simple enough, so what’s the problem? The flaw egy for dependency resolution that is that this simple dependency graph ignores the consumer’s works for everyone, which is why perspective. It doesn’t answer the question: does core (the Gradle’s API is so flexible. But most of the time, you probably consumer of date-utils) need joda-time in order to compile, won’t want to deal with it at a fine-grained level. Developers or is the date-utils module enough? at Netflix 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 doesn’t expose any Joda Time types in its public API—that 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 component’s 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 configurations (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 configurations will allow you to With the advent of multiproject or multimodule builds, it has express the effect 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 flaw in the way dependencies are specified. 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, let’s assume regarding the relative merits of a monolithic repository that date-utils is used purely internally by core. You would (), which is a single source code repository for all express this in core’s build script this way: your code, versus the more usual design, which relies on separate repositories for different projects. Of particular dependencies { relevance to this discussion of libraries is one of the declared implementation project(':date-utils') benefits of a monorepo: easier cross-project changes. } Consider this workflow: ■■ You discover that the project you’re working on requires a What these two dependency declarations mean for the overall fix to a library it uses. project is ■■ You ask that library’s team to implement the fix. ■■ core has both date-utils and joda-time on its compilation ■■ You incorporate the fixed library into your project. classpath In the case of a monorepo, you have access to the fixed 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 off the /master, you can deploy a ■■ App requires core at compile time new version of your project with the fix right away. This approach has several significant advantages: The process is less straightforward if the library is in a ■■ JARs don’t leak onto compilation classpaths when it’s different source repository. The typical solution involves get- unnecessary for them to do so. ting the library maintainer’s team to publish a new version ■■ Changing an implementation dependency doesn’t 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 fix 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 library’s team to publish dency is required in order to compile the consumer, but that’s 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 snapshots—unless you I’ve discussed consuming libraries so far, but only in are able to make your project depend on the library’s 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 you’re working against, via a sion definition in your project’s settings.gradle file. This is ID, tag, or some other label. explained on the Gradle blog. Just be aware that you should ■■ You can make fixes 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 don’t need to rely on snapshots that can easily break library’s 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. It’s also worth thinking about how you manage the con- You can achieve this with Gradle’s 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 need—it’s To understand how it works, think back to Figure 1 and otherwise empty—and runs all the integration tests. Both imagine you need a fix 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 fix, so you get hold of the source code project intermediate binaries. and put it alongside or even inside your project’s 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, I’ve 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. 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 Maven. He now does training and technical writing for Gradle Inc. ate versions of the library for them to use. It’s an awkward 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: Oracle Code ■■ Alignment with the Java SE 8 Date and Time API New One-Day, Free Event | 20 Cities Globally ■■ Improved CDI support ■■ Formal deprecation of the JSF-specific bean subsystem in favor of CDI ■■ WebSocket integration Explore the Latest Developer Trends: ■■ Ajax method invocation ■■ Multifield 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 specification 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 specification 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 //fix this / Quiz Yourself Intermediate and advanced test questions

SIMON ROBERTS s promised in my last column, with this issue, I begin to Which two of the following are true? A include questions that simulate the level of difficulty of a. The array referred to by sba might be eligible for garbage the Oracle Certified Associate exam, which contains questions collection at line 19. for a more preliminary level of certification 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 . 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 certification test for developers who definitely eligible for garbage collection. have been certified 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 definitely 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, don’t 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 //fix 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 produces output in the following form: public List 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 produces output in the public void processRecords( following form: Collection 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 lr = gatherRecords(); // line n2 List 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 ls = Arrays.asList("Fred", "Jim", "Sheila", } "Fred"); Set s1 = new HashSet<>(ls); // line n1 Which is true? Choose one. Set 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 produces output in the following form: d. Outputs true. e. Outputs false. Recorder$LongRecord@1218025c 67

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////// MARCH/APRIL 2017 //fix 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 easier—but 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 “definitely 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 “don’t 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 definitely not eligible for collec- either you can definitely collect the objects at the return of tion at that point. That’s 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 significant to by those variables become eligible for garbage collection. exception to this). This means that option A is incorrect. However, in this case, you don’t 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 definitely 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 definitely 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 Specification 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 //fix 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 fix it. However, a List is fully enum types haven’t always been allowed; enum was new capable of substituting for a Collection (the List inter- with Java 5. Therefore, it didn’t 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 wouldn’t alter the situation. Therefore, option B StringBuilder is not; neither is it assignment-compatible is incorrect. with String. Consider the following, because it’s a little less confus- Because of these rules, options A, D, and E are all incor- ing. The thinks that a List is not a rect, while both options B and C are correct. valid substitute for a List. There’s something that you can do with a List that isn’t properly sup- Question 3. The correct answer is option D. This question ported by a List. 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 Java’s generics system. When A List can properly contain anything that’s a variable of a collection type is declared with its generic assignment-compatible with a LongRecord: that would be specification—as in something like List—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 can legitimately compiler to do “consistency checking” that can ensure that contain such objects, and the compiler doesn’t know that you type errors cannot happen in the code. don’t 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 fies 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 - capable of fully substituting for b. That is, all the behaviors tions, but the compiler doesn’t analyze that; it just knows expected of the type of b must be properly implemented, and that the code could. Fortunately, there’s a syntax that lets you work as expected, in the object referred to by a. do what you want to do—that 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 to a Collection ing they’re assignment-compatible with Record. In effect, you is a valid substitution. Because the assignment define that Collection can be a collection of “anything that’s 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 that’s 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. that’s how the syntax comes about; the language lets you say, 69

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////// MARCH/APRIL 2017 //fix this /

in effect, “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 it’s assignment-compatible.) That syntax, construction of the Set. This might be plausible, given that of course, is Collection. 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 effect is that bothSet objects contain only the three to contain, Record must be assignment-compatible with distinct elements, "Fred", "Jim", and "Sheila". It’s 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 you’d 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 As a side note, it’s possible for a TreeSet to throw an into the method, because List 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 doesn’t 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 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, and that’s not assignment- that all implementations return a value that indicates only compatible with List. 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 definition ensures that the equals method works compile. Substituting one problem for another doesn’t result properly across different 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. 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 Sun’s struct and initialize the sets. This might happen if there is first Java classes in the UK. He created the Sun Certified Java no constructor available that accepts a List as an argument. Programmer and Sun Certified Java Developer exams. He wrote However, both Set types provide such a constructor. The several Java certification 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 Oracle’s Java certifica- tion projects. type Collection, and as a result, a List is valid. Because of 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 we’ve covered, topics that hard-core Java be sent to our editor, Andrew Binstock, and any other thoughts you feel impor­ would enjoy are of great interest to us, at [email protected]. tant to share with us or our readers. too. Please contact us with your ideas While it will have no influence on our Unless you specifically tell us that your at [email protected] and we’ll 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 staff 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 you’re 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 [email protected] (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