MAY/JUNE 2017

magazine

By and for the Java community

Libraries 10 16 34 28 LOMBOK: JDEFERRED’S DATABASE BEST PRACTICES ANNOTATIONS FOR ASYNC EVENT ACCESS WITH FOR LIBRARY CLEANER CODE MANAGEMENT STREAMS DESIGN

ORACLE.COM/JAVAMAGAZINE //table of contents /

16 22 28 JDEFERRED: SIMPLE JSOUP HTML DESIGNING AND HANDLING OF PROMISES PARSING LIBRARY IMPLEMENTING AND FUTURES By Mert Çalışkan A LIBRARY By Andrés Almiray Easily parse HTML, extract By Stephen Colebourne Asynchronous operations specified elements, validate The chief designer of Joda- without the headaches structure, and sanitize content. Time lays out best practices for writing your own library. 10 PROJECT LOMBOK: CLEAN, CONCISE CODE

By Josh Juneau Add Lombok to your project and get rid of most of your boilerplate code.

COVER ART BY PEDRO MURTEIRA

03 34 42 47 From the Editor Databases Fix This User Groups Writing your own annotations? Be Database Actions Using Java 8 By Simon Roberts The Bangladesh JUG circumspect in your design. Stream Syntax Instead of SQL Our latest code quiz 48 05 By Per Minborg 32 Contact Us Events Speedment 3.0 enables Java developers Java Proposals of Interest Have a comment? Suggestion? Want to to stay in Java when writing database Upcoming Java conferences and events JEP 262: Built-in Support for TIFF Files submit an article proposal? Here’s how. applications.

01

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 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 Francisco G Delgadillo Account Manager Design Director Mark Makinney Richard Merchán Mailing-List Rentals Senior Designer Contact your sales representative. Arianna Pucherelli Certified Professional 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. You’ve Earned It MAGAZINE CUSTOMER SERVICE [email protected] Display Your Oracle Certification Digital Badge 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 Customer Service. Certified Associate Certified Professional Certified Expert Certified Expert Certified Specialist 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 ASSOCIATE PROFESSIONAL EXPERT MASTER SPECIALIST 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 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 Oracle Corporation and/or its Claim your certification badge and validate affiliates. Other names may be trademarks of their respective owners. your skills across all online platforms. 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 //////////////////////////////////////////////// MAY/JUNE 2017 //from the editor /

Java in the Cloud

Keeping Annotations Useful Oracle Cloud delivers When designing annotations, be conservative and circumspect. high-performance and battle-tested platform and infrastructure services for the most demanding n this issue, the lead feature is about a rightly Annotations as they appear in Java itself Java apps. Iwell-regarded library named Project Lombok. follow a similar understated model. Those anno- This library enables you to avoid writing boiler- tations, first unveiled in Java 5, were elegant plate code by using annotations. For example, and concise and didn’t attempt to do too much: Oracle Cloud. add @Data to a class and Lombok will generate the @Override and @Deprecated told you something Built for modern app dev. getters and setters, plus other methods you’re about the code, while @SuppressWarnings told the Built for you. likely to want in a JavaBean-style data class— tools that you knew what you were doing. The toString() and so on. Lombok’s approach is intent was that tools, especially IDEs, would use attractive to me—and to many developers— these markers to issue warnings and reminders. in part because it’s useful, compact, and clear. None of the annotations actually changed pro- In addition, the project includes a tool called gram behavior. This conservative approach by “delombok,” which can remove the annotations the Java language team continued in Java 7, when and insert the boilerplate code into your classes. @SafeVarargs was added, and in Java 8, when In this way, you can easily remove the dependency @FunctionalInterface was delivered. Start here: on Lombok. The annotations are conservative in In addition to the qualities I’ve already men- developer.oracle.com their expression and their roles, and the project tioned, these annotations are unambiguous. This has a clean, reversible implementation. Many more is a key and often overlooked aspect of annota- annotations should follow this approach. tion design. In the quest for brevity, annotation #developersrule

PHOTOGRAPH BY BOB ADLER/THE VERBATIM AGENCY 03

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017 //from the editor /

authors too often push the respon- As the annotations became com- IntelliJ uses syntax like this: sibility of intelligibility onto plex markers for actions defined @Contract("_, null -> null"). developers. Look no further than elsewhere, you ended up chasing It means that the tagged method the lack of coordination in basic your tail just to determine what the accepts two parameters and syntax. A prime offender here is code you had right before you actu- returns a null if the second param- the family of not-null qualifiers. ally did. This was less than entirely eter is null. Much as I like this @NotNull is such an annotation, fun, which brings me to the second annotation, I feel uncomfortable and so is @NonNull. This annota- problem with many annotations: fully committing to it because it Get a Free tion has a different meaning under insufficient documentation. Unless creates a dependence on the IDE. FindBugs. Likewise, @Nullable the meaning is utterly transparent (Even though another IDE will skip Trial to means different things to the (and even then, as the preceding the annotation it doesn’t recognize, Checker Framework and FindBugs. examples demonstrated), docu- I’ve now left an unused artifact in Oracle Cloud This is not the way to go about ment the annotation thoroughly, my code that might create wasted things. If you author annotations, especially in frameworks. Err on time for downstream developers Experience modern, be clear and definitely avoid syn- the side of overcommunication. trying to understand its function.) open cloud development onyms and homonyms. Finally, I need to stress the In addition, if my whole team is with a free trial to Oracle In comparison to these short, importance of making annota- not using the same IDE, then some Cloud platform and pithy annotations, Java EE intro- tions a sound proposition for the code won’t have these tests and my infrastructure services. duced the extensive use of annota- developer and, by extension, the hope of consistent DbC enforce- tions. Soon, a series of annotations developer’s team. In this regard, ment is either compromised or Get your free trial: replaced code, and the nature of I am leery of IDE vendors’ cre- IDE-dependent. developer.oracle.com enterprise programming thereby ation of their own proprietary Annotations are an important changed. Java EE acquired a sort of annotation systems. All IDEs do part of programming in Java, and embedded syntax that straddled this to some extent, but I’ll pick their role is likely to expand. But descriptions and commands. The an example from the one I use new annotations should be devised advent of this style reinvigorated most. IntelliJ IDEA uses annota- with far greater circumspection Java EE by making it far easier tions to deliver a minimal but than in the past, named with care- to code and by getting rid of the clever implementation of design ful attention to predecessors, and heaviness of its forebears. by contract (DbC)–style enforce- documented well, and they should However, this advance inspired ment of passed parameters and avoid the introduction of restric- legions of frameworks to use and return values. I applaud JetBrains tive dependencies. developer.oracle.com overuse annotations, many of for providing a handy way to have which were uninspired formula- the IDE enforce method contracts Andrew Binstock, Editor in Chief tions. They introduced complexity (and identify potential coding [email protected] #developersrule without good enough documenta- errors that are inconsistent with @platypusguy tion by which to navigate the code. the contract requirements). 04

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017 //events /

JEEConf programming languages and MAY 26–27 methodologies, developer tooling, KIEV, UKRAINE solution architecture, and contin- JEEConf is the largest Java con- uous delivery. A product exhibi- ference in Eastern Europe. The tion is included. annual conference focuses on Java technologies for applica- JBCN Conference tion development. This year, it JUNE 19–21 offers five tracks and more than BARCELONA, SPAIN 50 speakers with an emphasis on Hosted by the Barcelona Java practical experience and devel- Users Group, this conference is opment of real projects. Topics dedicated to Java and JVM devel- include modern approaches in the opment. Share your knowledge development of distributed, highly and experiences, and discover loaded, scalable enterprise sys- how other developers are using tems with Java, among others. your favorite VM.

jPrime O’Reilly Fluent Conference MAY 30–31 JUNE 19–20, TRAINING SOFIA, BULGARIA JUNE 20–22, TUTORIALS jPrime is a relatively new con- AND CONFERENCE Devoxx Poland ference, with two days of talks SAN JOSE, CALIFORNIA KRAKOW, POLAND on Java, JVM languages, mobile Fluent offers practical train- JUNE 21–23 and web programming, and best ing for building sites and apps For three days, 100 Java Champions, evangelists, and thought leaders practices. The event is run by the for the modern web. This event inspire 2,500 developers from 20 different countries at this installment Bulgarian Java User Group and is designed to appeal to applica- of the popular Devoxx conferences. Tracks on server-side Java, cloud and provides opportunities for hack- tion, web, mobile, and interactive big data, JVM languages, web and HTML5, and more are on offer. Hacking ing and networking. developers, as well as engineers, and networking round out the experience. architects, and UI/UX designers. GeekOut Training days and tutorials round JUNE 8–9 out the conference experience. TALLINN, ESTONIA This two-day Java developer con- ference focuses on Java, the JVM,

PHOTOGRAPH BY ZARNELL/GETTY IMAGES 05

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017 //events /

demos, and Birds of a Feather ses- Java 8, microservice architectures, sions. (No English page available.) Docker, cloud, security, Scala, Groovy, Spring, Android, iOS, The Developer’s Conference (TDC) NoSQL, and much more. JULY 11–15 SÃO PAULO, BRAZIL JavaZone 2017 TDC is one of Brazil’s largest con- SEPTEMBER 12, WORKSHOPS ferences for students, developers, SEPTEMBER 13–14, CONFERENCE and IT professionals. Java-focused OSLO, NORWAY content on topics such as IoT, UX JavaZone is a conference for design, mobile development, and Java developers created by the are fea- Norwegian Java User Group, tured. (No English page available.) javaBin. The conference has existed since 2001 and now consists of JCrete around 200 speakers and 7 parallel EclipseCon 2017 architects, engineering directors, JULY 16–21 tracks over 2 days, plus an addi- JUNE 20, “UNCONFERENCE” and project managers who influ- KOLYMBARI, GREECE tional day of workshops before- JUNE 21–22, CONFERENCE ence innovation in their teams. This loosely structured “uncon- hand. You will be joined by approx- TOULOUSE, FRANCE The conference covers many dif- ference” involves morning ses- imately 3,000 of your fellow Java EclipseCon is all about the Eclipse ferent developer topics, frequently sions discussing all things Java, developers. Included in the ticket ecosystem. Contributors, adopt- including entire Java tracks. combined with afternoons spent price is a membership in javaBin. ers, extenders, service provid- socializing, touring, and enjoy- ers, consumers, and business and Java Forum ing the local scene. There is also a NFJS Boston research organizations gather to JULY 5, WORKSHOP JCrete4Kids component for intro- SEPTEMBER 29–OCTOBER 1 share their expertise. The two- JULY 6, CONFERENCE ducing youngsters to program- BOSTON, MASSACHUSETTS day conference is preceded by an STUTTGART, GERMANY ming and Java. Attendees often Since 2001, the No Fluff Just Stuff “Unconference” gathering. Organized by the Stuttgart Java bring their families. (NFJS) Software Symposium Tour User Group, Java Forum typically has delivered more than 450 QCon New York draws more than 1,000 partici- ÜberConf events with more than 70,000 JUNE 26–28, CONFERENCE pants. A workshop for Java deci- JULY 18–21 attendees. This event in Boston JUNE 29–30, WORKSHOPS sion-makers takes place on July 5. DENVER, COLORADO covers the latest trends within NEW YORK, NEW YORK The broader forum will be held on ÜberConf 2017 will be held at the the Java and JVM ecosystem, QCon is a practitioner-driven con- July 6, featuring 40 exhibitors and Westin Westminster in down- DevOps, and agile development ference for technical team leads, including lectures, presentations, town Denver. Topics include environments.

PHOTOGRAPH BY CHRISTIAN REIMER/FLICKR 06

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017 //events /

JavaOne server-side Java, cloud, big data, OCTOBER 1–5 and extensive coverage of Java 9. Oracle Code Events SAN FRANCISCO, CALIFORNIA Oracle Code is a free event for Whether you are a seasoned QCon San Francisco developers to learn about the coder or a new Java programmer, NOVEMBER 13–15, CONFERENCE latest development technologies, JavaOne is the ultimate source of NOVEMBER 16–17, WORKSHOPS technical information and learn- SAN FRANCISCO, CALIFORNIA practices, and trends, including ing about Java. For five days, Java Although the content has not containers, and API developers gather from around yet been announced, recent applications, DevOps, databases, the world to talk about upcom- QCon conferences have offered open source, development tools and low-code platforms, ing releases of Java SE, Java EE, several Java tracks along with machine learning, AI, and chatbots. In addition, Oracle and JavaFX; JVM languages; new tracks related to web develop- Code includes educational sessions for developing soft- development tools; insights into ment, DevOps, , ware in Java, Node.js, and other programming languages recent trends in programming; and more. and frameworks using Oracle Database, MySQL, and and tutorials on numerous related NoSQL databases. Java and JVM topics. Are you hosting an upcoming Java conference that you would US AND CANADA ASIA PACIFIC KotlinConf like to see included in this cal- JUNE 22, Atlanta, Georgia JULY 14, Beijing, China NOVEMBER 2–3 endar? Please send us a link SAN FRANCISCO, CALIFORNIA and a description of your event JULY 18, Sydney, Australia EUROPE AND MIDDLE EAST KotlinConf is a JetBrains event at least 90 days in advance at AUGUST 4, Bangalore, India MAY 23, Moscow, Russia that provides two days of content [email protected]. Other AUGUST 30, Seoul, South from Kotlin creators and commu- ways to reach us appear on the JUNE 6, Brussels, Belgium Korea nity members. last page of this issue. JULY 11, Tel Aviv, Israel LATIN AMERICA Devoxx JUNE 27, São Paulo, Brazil NOVEMBER 6–10 JUNE 29, Mexico City, Mexico ANTWERP, BELGIUM The largest gathering of Java developers in Europe takes place again this year in Antwerp. Dozens of expert speakers deliver hundreds of presentations on Java and the JVM. Tracks include 07

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017

LIBRARIES Writing and Using Libraries

PROJECT LOMBOK 10 | JDEFERRED 16 | JSOUP 22 | WRITING YOUR OWN LIBRARY 28

n an age of frameworks, there still remains a supreme need for which uses annotations to greatly reduce the writing of boilerplate libraries, those useful collections of classes and methods that code—leading to fewer keystrokes and much more readable code. save us a huge amount of work. For all the words spilled on the Andrés Almiray’s article on the JDeferred library (page 16) is a deep reusability of object orientation (OO), it’s clear that code reuse has dive into the concepts of , which are techniques for been consistently successful only at the library level. It’s hard to defining, invoking, and getting results from asynchronous operations. Isay whether that’s a failure of the promises of OO or whether those The built-in Java classes for futures and promises work well but can be promises were unlikely to ever deliver the hoped-for reusability. difficult to program. JDeferred removes the difficulty and, like Lombok, In Stephen Colebourne’s article (page 28), he gives best practices for leads to considerably cleaner code. writing libraries of your own. Finally, we revisit an article Colebourne is the author of the we ran a year ago on jsoup celebrated Joda-Time library, (page 22), which is one of the which was the standard non-JDK finest ways of handling HTML: time and date library prior to parsing, scraping, manipulating, Java SE 8. In the article, he gives and even generating it. best practices for architecting the If libraries are not your favorite library and shares guidelines he topic, we have you covered with has learned along the way that a detailed discussion (page 34) sometimes fly in the face of gen- of how to use streaming syntax erally accepted programming pre- rather than SQL when accessing cepts. Writing your own library? databases. In addition, we offer Then start here. our usual quiz (this time with the We also examine three well- inclusion of questions from the designed libraries that provide entry-level exam), our calendar of useful functionality but might events, and other goodness. (Note not be widely known. The first of that our next issue will be a jumbo these is Project Lombok (page 10), special issue on Java 9.) Enjoy!

ART BY PEDRO MURTEIRA 09

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017 //libraries / Project Lombok: Clean, Concise Code Add Lombok to your project and get rid of most of your boilerplate code. JOSH JUNEAU

magine that you are coding a Java application and creating a confused with the Bean Validation annotation, can be used I plain old Java object (POJO), a Java class with several private to generate a null check on a setter field. The check throws a fields that will require getter and setter methods to provide NullPointerException if the annotated class field contains a access. How many lines of code will be needed to generate null value. Simply apply it to a field to enforce the rule: getters and setters for each of the fields? Moreover, adding a constructor and a toString() method will cause even more @NonNull @Setter lines of code and clutter. That is a lot of boilerplate code. private String employeeId; How about when you are utilizing Java objects that need to be closed after use, so you need to code a finally block or use This code generates the following code: try-with-resources to ensure that the object closing occurs? Adding finally block boilerplate to close objects can add a public id setEmployeeId(@NonNull final String employeeId) significant amount of clutter to your code. { Project Lombok is a mature library that reduces boiler­ if(employeeId == null) throw plate code. The cases mentioned above cover just a few of new java.lang.NullPointerException("employeeId"); those where Project Lombok can be a great benefit. The library this.employeeId = employeeId; replaces boilerplate code with easy-to-use annotations. In this article, I examine several useful features that Project Lombok Primitive parameters cannot be annotated with @NonNull. If provides—making code easier to read and less error-prone and they are, a warning is issued and no null check is generated. making developers more productive. Best of all, the library works well with popular IDEs and provides a utility to “delom­ Concise Data Objects bok” your code by reverting—that is, adding back all the boiler- Writing a POJO can be laborious, especially if there are many plate that was removed when the annotations were added. fields. If you are developing a POJO, you should always pro­ vide private access directly to the class fields, while creating Check for Nulls accessor methods—getters and setters—to read from and Let’s start with one of the most basic utilities that Lombok write to those fields. Although developing accessor methods has to offer. The @NonNull annotation, which should not be is easy, they generally are just boilerplate code. Lombok can 10

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017 //libraries /

take care of generating these methods if a field is annotated be taken care of by annotating a class with the @EqualsAnd with @Getter and @Setter. Therefore, the following two code HashCode and @ToString annotations, respectively. These listings provide the exact same functionality. annotations cause Lombok to generate the respective meth­ Without Project Lombok: ods, and they are customizable so that you can specify field exclusions and other factors. By default, any nonstatic or private String columnName; nontransient fields are included in the logic that is used to compose these methods. These annotations use the attribute public String getColumnName(){ exclude to specify methods that should not be included in the return this.columnName; logic. The callSuper attribute accepts a true or false, and it } indicates whether to use the equals() method of the super­ public void setColumnName(String columnName){ class to verify equality. The following code demonstrates the this.columnName = columnName; use of these annotations. } @EqualsAndHashCode Using Project Lombok: @ToString(exclude={"columnLabel"}) public class ColumnBean { @Getter @Setter private String columnName; private BigDecimal id; private String columnName; As you can see, Lombok not only makes the code more con­ private String columnLabel; cise, but it also makes the code easier to read and less error- } prone. These annotations also accept an optional parameter The @Data annotation can be used to apply functionality to designate the access level if Lombok can take behind all the annotations discussed thus far in this section. needed. More good news: @Getter care of the logger That is, simply annotating a class with @Data causes Lombok and @Setter respect the proper declaration if you to generate getters and setters for each of the nonstatic class naming conventions, so gener­ fields and a class constructor, as well as the toString(), ated code for a Boolean field results place the @Log equals(), and hashCode() methods. It also creates a con­ in accessor methods beginning annotation (or an structor that accepts any final fields or those annotated with is rather than get. If they are annotation pertaining with @NonNull as arguments. Finally, it generates default applied at the class level, getters toString(), equals(), and hashCode() methods that take all and setters are generated for each to your choice of class fields and methods into consideration. This makes the nonstatic field within the class. logging API) on any coding of a POJO very easy, and it is much the same as some In many cases, data objects class that requires alternative languages, such as Groovy, that offer similar also should contain the equals(), features. Listing 1 (all listings for this article can be found in hashCode(), and toString() logging capability. Java Magazine’s download section) shows the full Java code for methods. This boilerplate can the POJO that is generated by the following code: 11

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017 //libraries /

@Data Can’t My IDE Do That? public class ColumnBean { You might be asking yourself, “Can’t my IDE already do that @NonNull sort of refactoring?” Most modern IDEs—such as NetBeans, private BigDecimal id; Eclipse, and IntelliJ—offer features such as encapsulation @NonNull of fields and auto-generation of code. These abilities are private String columnName; great because they can significantly increase productivity. @NonNull However, these capabilities do not reduce code clutter, so private String columnLabel; they can lead to refactoring down the road. Let’s say your Java } object has 10 fields. To conform to a JavaBean, it will contain 20 accessor methods (one getter and setter pair per field). Note that if you create your own getters or setters, Lombok That’s a lot of clutter. Also, what happens when you decide to does not generate the code even if the annotations are pres­ change one of your field names? You’ll have to do some refac­ ent. This can be handy if you wish to develop a custom getter toring in order to change it cleanly. If you’re using Lombok, or setter for one or more of the class fields. you simply change the field name and move on with your life. If you are merely interested in having constructors generated automatically, @AllArgsConstructor and Builder Objects @NoArgsConstructor might be of use. @AllArgsConstructor Sometimes it is useful to have the ability to develop a builder creates a constructor for the class using all the fields that object, which allows objects to be constructed using a step- have been declared. If a field is added or removed from the by -step pattern with controlled construction. For example, class, the generated constructor is revised to accommodate in some cases large objects require several fields to be popu­ this change. This behavior can be convenient for ensuring lated, which can be problematic when such an object is that a class constructor always accepts values for each of the implemented via a constructor. class fields. The disadvantage of using this annotation is that Lombok makes it simple to create builder objects in much reordering the class fields causes the constructor arguments the same way that it enables easy POJO creation. Annotating to be reordered as well, which could introduce bugs if there a class with @Builder produces a class that adheres to the is code that depends upon the position of arguments when —that is, an inner builder class is produced generating the object. @NoArgsConstructor simply generates a that contains each of the class fields. (“Builder” is pre­ no -argument constructor. ceded by the name of the class. So a class named Foo has a The @Value annotation is similar to the @Data annotation, FooBuilder class generated.) The generated builder class con­ but it generates an immutable class. The annotation is placed tains a “setter” method for each of the class fields, but the at the class level, and it invokes the automatic generation of names of the methods do not include the usual “set” prefix. getters for all private final fields. No setters are generated, and The methods themselves set the value that is passed into the the class is marked as final. Lastly, the toString(), equals(), methods, and then they return the builder object. Listing 2 in and hashCode() methods are generated, and a constructor is the downloadable code demonstrates a class that contains a generated that contains arguments for each of the fields. builder, and Listing 3 demonstrates the same object annotated with @Builder. 12

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017 //libraries /

Several variations can be used with @Builder. For exam­ some lines to manually close the resource. Listing 5 demon­ ple, the annotation can be placed on the class, on a construc­ strates the same block of code using @Cleanup. tor, or on a method. Placing the annotation on a constructor It is important to note that in a case where code throws produces the same builder object shown in Listing 2, but it an exception and then subsequent code invoked via @Cleanup generates methods for each of the constructor’s arguments in also throws an exception, the original exception will be hid­ the builder. This means that you can omit a class field from den by the subsequently thrown exception. the constructor, or you can choose to include a superclass field in the constructor. The only way to include superclass Locking Safely fields in a builder is for an object to contain a superclass. To ensure safety by having only one thread that can access a The toBuilder attribute of the @Builder annotation specified method at a time, the method should be marked as accepts true or false, and it can be used to designate whether synchronized. Lombok supplies an even safer way to ensure a toBuilder() method is included in the generated builder that only one thread can access a method at a time: the object. This method copies the contents of an existing object @Synchronized annotation. This annotation can be used only of the same type. on static and instance methods, just like the synchronized It is possible to treat one of the fields as a builder collec­ keyword. However, rather than locking on this, the annota­ tion by annotating it with @Singular. This causes two adder tion locks on a private field named $ for nonstatic methods to be generated—one to add a single element and methods and on $LOCK for static methods. This field is auto- another to add all elements. This annotation also causes a generated if it does not already exist, or you can create it clear() method to be generated, which clears the contents of yourself. You can also specify a different lock field by speci­ the collection. fying it as a parameter to @Synchronized. The following code illustrates the use of @Synchronized: Easy Cleanup Lombok makes it easy to clean up resources as well. How @Synchronized often have you either forgotten to close a resource or written public static void helloLombok(){ lots of boilerplate try-catch blocks to accommodate resource System.out.println("Lombok"); closing? Thanks to the @Cleanup annotation, you no longer } need to worry about forgetting to release a resource. Although the Java language now contains the try-with- This solution can be a safer alternative to using the resources statement to help close resources, @Cleanup can synchronized keyword, because it allows you to lock on an be a useful alternative in some cases, because it causes a instance field rather than onthis . try-finally block to be generated around the subsequent code, and then it calls the annotated resource’s close() Effortless Logging method. If the cleanup method for a given resource is not Most logging requires some declaration to set up a logger named close(), the cleanup method name can be specified within each class. This code is definitely repetitive boiler­ with the annotation’s value attribute. Listing 4 in the down­ plate code. Lombok can take care of the logger declaration loadable code demonstrates a block of code that contains if you place the @Log annotation (or an annotation pertain­ 13

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017 //libraries /

ing to your choice of logging API) on any class that requires guages such as Groovy or Jython. Take the following code, logging capability. for instance: For instance, if you wish to use a logging API—say, Log4j 2—each class that uses the logger must declare some­ final ArrayList myJobs = new ArrayList(); thing similar to the following: Using the val keyword, you can change the code to the public class ClassName(){ following: private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(ClassName.class); val myJobs = new ArrayList(); . . . // Use log variable as needed There are some considerations for using the val keyword. } First, as mentioned previously, it marks the method declara­ tion as final. Therefore, if you later need to change the value Lombok makes it possible to do the following instead: of the variable, using the val keyword is not possible. It also does not work correctly in some IDEs, so if you are trying to @Log4j2 mark local variables as final in those IDEs, they are flagged public class ClassName(){ as errors. . . . Be sneaky with exceptions. There are occasions where excep­ // Use log variable as needed tion handling can become a burden, and I’d argue that this } is typically the case when you are working with boilerplate exceptions. Most of the time, Java allows you to easily see Listing 6 in the downloadable code shows an example using where problems exist via the use of checked exceptions. Log4j 2. The name of the logger will automatically be the However, in those cases where checked exceptions are bur­ same as its containing class’ name. However, this can be densome, you can easily hide them using Lombok. customized by specifying the topic attribute of the respec­ The @SneakyThrows annotation can be placed on a method tive logging annotation. For a complete listing of supported to essentially “swallow” the exceptions, allowing you to logging APIs, refer to the Lombok documentation and the omit the try-catch block completely. The annotation allows Lombok Javadoc. a method to handle all excep­ tions quietly, or you can specify The delombok utility Other Useful Items exactly which exceptions to There are several other useful features Lombok offers that ignore by passing the excep­ can be applied to I haven’t yet covered. Let’s go through a couple of the most tion classes to the annotation as your code to convert highly used. attributes. Listing 7 in the down­ code that uses Lombok Informal declaration. The val keyword can be used in place of loadable code demonstrates the an object type when you declare a local final variable, much use of @SneakyThrows specifying back to vanilla Java. like the val keyword that you have seen in alternative lan­ which exceptions to swallow. 14

ORACLE.COM/JAVAMAGAZINE //////////////////////////////////////////////// MAY/JUNE 2017 //libraries /

I want to reiterate that this Lombok feature should be by annotating them with @Data. I suggest you play around used with caution, because it can become a real issue if too with it and see what works best for you. many exceptions are ignored. Use caution and roll back. As with the use of any library, there Lazy getters. It is possible to indicate that a field should have are some caveats to keep in mind. This is especially true a getter created once, and then the result should be cached when you are thinking about future maintenance or modifi­ for subsequent invocations. This can be useful if your get­ cations to the codebase. Lombok generates code for you, but ter method is expensive as far as performance goes. For that might cause a problem when it comes to refactoring. It instance, if you need to populate a list from a database query, is difficult to refactor code that does not exist until compile or you need to access a web service to obtain the data for time, so be cautious with refactoring code that uses Lombok. your field on the first access, it might make sense to cache You also need to think about readability. Lombok annota­ the result for subsequent calls. To use this feature, a private tions might make troubleshooting a mystery for someone final variable must be generated and initialized with the who is not familiar with the library—and even for those expensive expression. You can then annotate the field with who are—if something such as @SneakyThrows is hiding @Getter(lazy=true) to implement this functionality. an exception. IDE compatibility. Lombok plays well with the major IDEs, Fortunately, Lombok makes it easy to roll back if you so simply including Lombok in your project and annotat­ need to. The delombok utility can be applied to your code to ing accordingly typically does not generate errors in code or convert code that uses Lombok back to vanilla Java. This util­ cause errors when the generated methods are called. In fact, ity can be used via Ant or the command line. in NetBeans the class Navigator is populated with the gen­ erated methods after annotations are placed and the code is Conclusion saved, even though the methods do not appear in the code. The Lombok library was created to make Java an easier lan­ Auto -completion works just as if the methods were typed into guage in which to code. It takes some of the most common the class, even when generated properties are accessed from boilerplate headaches out of the developer’s task list. It can a web view in expression language. be useful for making your code more concise, reducing the Even more-concise Java EE. Over the past few years, Java EE chance for bugs, and speeding up development time. Try add­ has been making good headway on becoming a very produc­ ing Lombok to one of your applications and see how many tive and concise platform. Those of you who recall the labo­ lines of code you can cut out.