SlideShare a Scribd company logo
@mirocupak
The good, the bad, and the ugly
of Java API design
Miro Cupak
Co-founder & VP Engineering, DNAstack
October 31, 2019
@mirocupak 2
Features
• Collections API.
• Stack-walking API.
• Process API.
• HTTP client API.
@mirocupak
Collections API
3
@mirocupak 4
Best practices
• Take advantage of convenience factory methods for collections.
• Immutable collections via of/ofEntries and copies via copyOf.
• Less verbose, no static initializer blocks.
• Create immutable collections by default, only add mutability when needed.
• No need to worry about forgetting references to underlying collections.
• Thread-safe and can be shared freely (no need for defensive copies).
• Good performance.
• Prefer collecting into immutable collections using toUnmodifiableList,
toUnmodifiableSet, toUnmodifiableMap.
• Use toArray to convert collections to arrays.
@mirocupak 5
Antipatterns
• Obtaining collections through other data structures (Arrays.asList,
Stream.of).
• Pulling in external dependencies only to obtain immutable collections (e.g.
Guava and its Immutable*).
• Instance-initializer construct in an anonymous inner class to instantiate
collections.
• Performance over clean APIs ([List, Set, Map].of).
@mirocupak 6
Patterns
• Static factory methods to create objects (of/ofEntries/copyOf).
• Name concisely (convention: of).
• Concrete classes not as part of the public API with static methods on
interfaces returning instances (pattern for implementation flexibility).
• Static import when readability not jeopardized (java.util.Map.entry).
• Tuple wrapper objects and convenience methods to generate them when
multiple varargs needed (Map.ofEntries).
• Converting between types via copyOf.
• Constructor reference as a generating function (array in a toArray call).
• Immutability by default (collections with copies and collectors).
@mirocupak
Stack-walking API
7
@mirocupak 8
Best practices
• Take advantage of the Stream API to lazily access only certain elements.
• Be aware of StackWalker.Option.
• Don’t resolve classes manually.
• Use to show hidden and reflection frames.
@mirocupak 9
Antipatterns
• Using [Thread, Throwable].getStackTrace() to traverse selected
frames of the execution stack.
• Treating execution stack as text.
• Using strings to represent Class instances.
• Accessing things eagerly when only parts of them are needed.
• Surprising hidden method behaviour (omitting elements of the stack for
performance).
@mirocupak 10
Patterns
• Collections over arrays.
• Leveraging Stream API in API design.
• Choose suitable represetations (don’t model everything as strings).
• Good performance through lazy access via streams.
• Methods accepting functions on streams as parameters to maintain
consistent state and control (walk()).
• Obtaining configured instances via static factory methods parameterized
with enums (getInstance()).
• Work with a security manager (secure access to Class objects).
• Permission checks when constructing instead of using an object.
@mirocupak
Process API
11
@mirocupak 12
Best practices
• ProcessHandle is a clean way of obtaining information about processes.
• Take advantage of convenience methods: pid, info, command…
• Trigger actions on process termination via onExit.
• Connect ProcessBuilder with ProcessHandle via toHandle.
@mirocupak 13
Antipatterns
• Accessing process information via MXBeans or OS utilities.
• Pulling in external libraries for simple process management (e.g. Apache
Commons Exec).
• Incomplete APIs - providing functionality to start hard-to-manage resources
without providing the functionality to obtain information about them.
• APIs leading the clients to use non-portable constructs.
@mirocupak 14
Patterns
• Providing convenience methods for commonly used functionality.
• Compact fluent API to access nested information.
• Nested public interfaces to group and organize (ProcessHandle.Info).
• Using convenient static factory methods to obtain instances
(ProcessHandle.[current, of, allProcesses]).
• Returning streams instead of collections to streamline lazy processing of
many elements (allProcesses, children, descendants…).
• Returning CompletableFuture instances in asynchronous APIs
(onExit).
• Providing adapters via to* methods (toHandle).
@mirocupak
HTTP client API
15
@mirocupak 16
Best practices
• Clear organization: HttpClient, HttpRequest, HttpResponse.
• HttpURLConnection is not pleasant to use.
• The new client API is versatile, flexible and clean.
• Prefer functionality in the JDK to external libraries.
@mirocupak 17
Antipatterns
• Using HttpURLConnection directly.
• Inconsistent capitalization (HttpURLConnection).
• Overly abstract and general APIs (URLConnection).
• Unclear conceptual API model (URL).
• Type casting needed to obtain the right instance (openConnection).
• Using strings where methods or enums would be more practical
(setRequestMethod(“GET”)).
• Requiring the client to use I/O boilerplate (BufferedReader/
InputStreamReader/InputStream…).
@mirocupak 18
Antipatterns
• Mandatory blocking network I/O.
• Side effects and hidden assumptions (getInputStream).
• Inconsistent behaviour across APIs (URLConnection vs. Socket).
@mirocupak 19
Patterns
• Clear separation of concepts at the class level (HttpClient,
HttpRequest, HttpResponse).
• Builder.
• Asynchronous via CompletableFuture.
• Clear and consistent naming.
• Convenience methods to access commonly used features (statusCode,
body).
@mirocupak
Questions?
20

More Related Content

PDF
The good, the bad, and the ugly of Java API design
Miro Cupak
 
PDF
The good, the bad, and the ugly of Java API design
Miro Cupak
 
PDF
The good, the bad, and the ugly of Java API design
Miro Cupak
 
PDF
The Good, the Bad and the Ugly of Java API design
Miro Cupak
 
PDF
BigDataSpain 2016: Stream Processing Applications with Apache Apex
Thomas Weise
 
PPTX
Parallel Programming
Mindfire Solutions
 
PDF
ECMAScript 6 Overview & Comparision
Talal Suhail
 
PDF
Hibernate performance tuning
Igor Dmitriev
 
The good, the bad, and the ugly of Java API design
Miro Cupak
 
The good, the bad, and the ugly of Java API design
Miro Cupak
 
The good, the bad, and the ugly of Java API design
Miro Cupak
 
The Good, the Bad and the Ugly of Java API design
Miro Cupak
 
BigDataSpain 2016: Stream Processing Applications with Apache Apex
Thomas Weise
 
Parallel Programming
Mindfire Solutions
 
ECMAScript 6 Overview & Comparision
Talal Suhail
 
Hibernate performance tuning
Igor Dmitriev
 

What's hot (14)

PDF
Codeigniter Training Part2
Weerayut Hongsa
 
PDF
Entity Framework Core 1.x/2.x Advanced
Christian Nagel
 
PDF
Reactive Streams
Fehmi Can SAĞLAM
 
PPTX
What’s expected in Java 9
Gal Marder
 
PPTX
What’s expected in Spring 5
Gal Marder
 
PDF
Breathing new life into Apache Oozie with Apache Ambari Workflow Manager
Artem Ervits
 
PPTX
Multi-threading in the modern era: Vertx Akka and Quasar
Gal Marder
 
PDF
New in Spring Framework 5.0: Functional Web Framework
VMware Tanzu
 
PDF
Gradle - Build System
Jeevesh Pandey
 
PDF
Training Slides: 303 - Replicating out of a Cluster
Continuent
 
PPTX
FOSDEM19 MySQL Component Infrastructure
Georgi Kodinov
 
PPTX
Utilizing the OpenNTF Domino API
Oliver Busse
 
PPTX
ZZ BC#7 asp.net mvc practice and guideline by NineMvp
Chalermpon Areepong
 
PDF
Creating Modular Test-Driven SPAs with Spring and AngularJS
Gunnar Hillert
 
Codeigniter Training Part2
Weerayut Hongsa
 
Entity Framework Core 1.x/2.x Advanced
Christian Nagel
 
Reactive Streams
Fehmi Can SAĞLAM
 
What’s expected in Java 9
Gal Marder
 
What’s expected in Spring 5
Gal Marder
 
Breathing new life into Apache Oozie with Apache Ambari Workflow Manager
Artem Ervits
 
Multi-threading in the modern era: Vertx Akka and Quasar
Gal Marder
 
New in Spring Framework 5.0: Functional Web Framework
VMware Tanzu
 
Gradle - Build System
Jeevesh Pandey
 
Training Slides: 303 - Replicating out of a Cluster
Continuent
 
FOSDEM19 MySQL Component Infrastructure
Georgi Kodinov
 
Utilizing the OpenNTF Domino API
Oliver Busse
 
ZZ BC#7 asp.net mvc practice and guideline by NineMvp
Chalermpon Areepong
 
Creating Modular Test-Driven SPAs with Spring and AngularJS
Gunnar Hillert
 
Ad

Similar to The good, the bad, and the ugly of Java API design (20)

PPTX
AngularJS 1.x - your first application (problems and solutions)
Igor Talevski
 
PPTX
Show Some Spine!
Geoff Gerrietts
 
KEY
The Why and How of Scala at Twitter
Alex Payne
 
PDF
Master class in modern Java
Miro Cupak
 
PDF
Stream Processing use cases and applications with Apache Apex by Thomas Weise
Big Data Spain
 
PPTX
Apache Cayenne: a Java ORM Alternative
Andrus Adamchik
 
PPTX
Wikipedia Cloud Search Webinar
Search Technologies
 
PDF
Master class in modern Java
Miro Cupak
 
PDF
Voxxed Athens 2018 - Clean Code with Java9+
Voxxed Athens
 
PDF
Writing clean code with Java 9+
Miro Cupak
 
PDF
Ratpack Web Framework
Daniel Woods
 
PPT
2010 05-21, object-relational mapping using hibernate v2
alvaro alcocer sotil
 
PDF
Comparison between Dynamo and riak
Beatriz Aguilar Gallo
 
PPTX
Collections
Marwa Dosoky
 
PDF
Apereo OAE - Bootcamp
Nicolaas Matthijs
 
PDF
Working With Concurrency In Java 8
Heartin Jacob
 
PPT
Java EE revisits design patterns
Alex Theedom
 
PDF
Building scalbale cloud native apps with .NET 8
GillesMathieu10
 
PPT
Java EE Revisits Design Patterns
Alex Theedom
 
PDF
Apache Cayenne for WO Devs
WO Community
 
AngularJS 1.x - your first application (problems and solutions)
Igor Talevski
 
Show Some Spine!
Geoff Gerrietts
 
The Why and How of Scala at Twitter
Alex Payne
 
Master class in modern Java
Miro Cupak
 
Stream Processing use cases and applications with Apache Apex by Thomas Weise
Big Data Spain
 
Apache Cayenne: a Java ORM Alternative
Andrus Adamchik
 
Wikipedia Cloud Search Webinar
Search Technologies
 
Master class in modern Java
Miro Cupak
 
Voxxed Athens 2018 - Clean Code with Java9+
Voxxed Athens
 
Writing clean code with Java 9+
Miro Cupak
 
Ratpack Web Framework
Daniel Woods
 
2010 05-21, object-relational mapping using hibernate v2
alvaro alcocer sotil
 
Comparison between Dynamo and riak
Beatriz Aguilar Gallo
 
Collections
Marwa Dosoky
 
Apereo OAE - Bootcamp
Nicolaas Matthijs
 
Working With Concurrency In Java 8
Heartin Jacob
 
Java EE revisits design patterns
Alex Theedom
 
Building scalbale cloud native apps with .NET 8
GillesMathieu10
 
Java EE Revisits Design Patterns
Alex Theedom
 
Apache Cayenne for WO Devs
WO Community
 
Ad

More from Miro Cupak (20)

PDF
Exploring the latest and greatest from Java 14
Miro Cupak
 
PDF
Exploring reactive programming in Java
Miro Cupak
 
PDF
Exploring the last year of Java
Miro Cupak
 
PDF
Local variable type inference - Will it compile?
Miro Cupak
 
PDF
Local variable type inference - Will it compile?
Miro Cupak
 
PDF
Exploring reactive programming in Java
Miro Cupak
 
PDF
Exploring reactive programming in Java
Miro Cupak
 
PDF
Writing clean code with modern Java
Miro Cupak
 
PDF
Exploring reactive programming in Java
Miro Cupak
 
PDF
Writing clean code with modern Java
Miro Cupak
 
PDF
Exploring what's new in Java 10 and 11 (and 12)
Miro Cupak
 
PDF
Exploring what's new in Java 10 and 11
Miro Cupak
 
PDF
Exploring what's new in Java in 2018
Miro Cupak
 
PDF
Reactive programming in Java
Miro Cupak
 
PDF
Master class in Java in 2018
Miro Cupak
 
PDF
Exploring reactive programming with Java
Miro Cupak
 
PDF
Exploring reactive programming in Java
Miro Cupak
 
PDF
Writing clean code with Java in 2018
Miro Cupak
 
PDF
Exploring reactive programming in Java
Miro Cupak
 
PDF
Pushing boundaries of types with modern Java
Miro Cupak
 
Exploring the latest and greatest from Java 14
Miro Cupak
 
Exploring reactive programming in Java
Miro Cupak
 
Exploring the last year of Java
Miro Cupak
 
Local variable type inference - Will it compile?
Miro Cupak
 
Local variable type inference - Will it compile?
Miro Cupak
 
Exploring reactive programming in Java
Miro Cupak
 
Exploring reactive programming in Java
Miro Cupak
 
Writing clean code with modern Java
Miro Cupak
 
Exploring reactive programming in Java
Miro Cupak
 
Writing clean code with modern Java
Miro Cupak
 
Exploring what's new in Java 10 and 11 (and 12)
Miro Cupak
 
Exploring what's new in Java 10 and 11
Miro Cupak
 
Exploring what's new in Java in 2018
Miro Cupak
 
Reactive programming in Java
Miro Cupak
 
Master class in Java in 2018
Miro Cupak
 
Exploring reactive programming with Java
Miro Cupak
 
Exploring reactive programming in Java
Miro Cupak
 
Writing clean code with Java in 2018
Miro Cupak
 
Exploring reactive programming in Java
Miro Cupak
 
Pushing boundaries of types with modern Java
Miro Cupak
 

Recently uploaded (20)

PPT
Activate_Methodology_Summary presentatio
annapureddyn
 
PPTX
Contractor Management Platform and Software Solution for Compliance
SHEQ Network Limited
 
PPTX
classification of computer and basic part of digital computer
ravisinghrajpurohit3
 
PDF
vAdobe Premiere Pro 2025 (v25.2.3.004) Crack Pre-Activated Latest
imang66g
 
PPTX
Presentation about Database and Database Administrator
abhishekchauhan86963
 
PDF
Generating Union types w/ Static Analysis
K. Matthew Dupree
 
PPTX
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
PPTX
ConcordeApp: Engineering Global Impact & Unlocking Billions in Event ROI with AI
chastechaste14
 
PDF
New Download FL Studio Crack Full Version [Latest 2025]
imang66g
 
PDF
Bandai Playdia The Book - David Glotz
BluePanther6
 
PPT
Why Reliable Server Maintenance Service in New York is Crucial for Your Business
Sam Vohra
 
PDF
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
PDF
Adobe Illustrator Crack Full Download (Latest Version 2025) Pre-Activated
imang66g
 
PPTX
GALILEO CRS SYSTEM | GALILEO TRAVEL SOFTWARE
philipnathen82
 
PDF
Immersive experiences: what Pharo users do!
ESUG
 
PDF
Summary Of Odoo 18.1 to 18.4 : The Way For Odoo 19
CandidRoot Solutions Private Limited
 
PDF
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
PPTX
Visualising Data with Scatterplots in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PPTX
Role Of Python In Programing Language.pptx
jaykoshti048
 
PDF
lesson-2-rules-of-netiquette.pdf.bshhsjdj
jasmenrojas249
 
Activate_Methodology_Summary presentatio
annapureddyn
 
Contractor Management Platform and Software Solution for Compliance
SHEQ Network Limited
 
classification of computer and basic part of digital computer
ravisinghrajpurohit3
 
vAdobe Premiere Pro 2025 (v25.2.3.004) Crack Pre-Activated Latest
imang66g
 
Presentation about Database and Database Administrator
abhishekchauhan86963
 
Generating Union types w/ Static Analysis
K. Matthew Dupree
 
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
ConcordeApp: Engineering Global Impact & Unlocking Billions in Event ROI with AI
chastechaste14
 
New Download FL Studio Crack Full Version [Latest 2025]
imang66g
 
Bandai Playdia The Book - David Glotz
BluePanther6
 
Why Reliable Server Maintenance Service in New York is Crucial for Your Business
Sam Vohra
 
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
Adobe Illustrator Crack Full Download (Latest Version 2025) Pre-Activated
imang66g
 
GALILEO CRS SYSTEM | GALILEO TRAVEL SOFTWARE
philipnathen82
 
Immersive experiences: what Pharo users do!
ESUG
 
Summary Of Odoo 18.1 to 18.4 : The Way For Odoo 19
CandidRoot Solutions Private Limited
 
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
Visualising Data with Scatterplots in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Role Of Python In Programing Language.pptx
jaykoshti048
 
lesson-2-rules-of-netiquette.pdf.bshhsjdj
jasmenrojas249
 

The good, the bad, and the ugly of Java API design

  • 1. @mirocupak The good, the bad, and the ugly of Java API design Miro Cupak Co-founder & VP Engineering, DNAstack October 31, 2019
  • 2. @mirocupak 2 Features • Collections API. • Stack-walking API. • Process API. • HTTP client API.
  • 4. @mirocupak 4 Best practices • Take advantage of convenience factory methods for collections. • Immutable collections via of/ofEntries and copies via copyOf. • Less verbose, no static initializer blocks. • Create immutable collections by default, only add mutability when needed. • No need to worry about forgetting references to underlying collections. • Thread-safe and can be shared freely (no need for defensive copies). • Good performance. • Prefer collecting into immutable collections using toUnmodifiableList, toUnmodifiableSet, toUnmodifiableMap. • Use toArray to convert collections to arrays.
  • 5. @mirocupak 5 Antipatterns • Obtaining collections through other data structures (Arrays.asList, Stream.of). • Pulling in external dependencies only to obtain immutable collections (e.g. Guava and its Immutable*). • Instance-initializer construct in an anonymous inner class to instantiate collections. • Performance over clean APIs ([List, Set, Map].of).
  • 6. @mirocupak 6 Patterns • Static factory methods to create objects (of/ofEntries/copyOf). • Name concisely (convention: of). • Concrete classes not as part of the public API with static methods on interfaces returning instances (pattern for implementation flexibility). • Static import when readability not jeopardized (java.util.Map.entry). • Tuple wrapper objects and convenience methods to generate them when multiple varargs needed (Map.ofEntries). • Converting between types via copyOf. • Constructor reference as a generating function (array in a toArray call). • Immutability by default (collections with copies and collectors).
  • 8. @mirocupak 8 Best practices • Take advantage of the Stream API to lazily access only certain elements. • Be aware of StackWalker.Option. • Don’t resolve classes manually. • Use to show hidden and reflection frames.
  • 9. @mirocupak 9 Antipatterns • Using [Thread, Throwable].getStackTrace() to traverse selected frames of the execution stack. • Treating execution stack as text. • Using strings to represent Class instances. • Accessing things eagerly when only parts of them are needed. • Surprising hidden method behaviour (omitting elements of the stack for performance).
  • 10. @mirocupak 10 Patterns • Collections over arrays. • Leveraging Stream API in API design. • Choose suitable represetations (don’t model everything as strings). • Good performance through lazy access via streams. • Methods accepting functions on streams as parameters to maintain consistent state and control (walk()). • Obtaining configured instances via static factory methods parameterized with enums (getInstance()). • Work with a security manager (secure access to Class objects). • Permission checks when constructing instead of using an object.
  • 12. @mirocupak 12 Best practices • ProcessHandle is a clean way of obtaining information about processes. • Take advantage of convenience methods: pid, info, command… • Trigger actions on process termination via onExit. • Connect ProcessBuilder with ProcessHandle via toHandle.
  • 13. @mirocupak 13 Antipatterns • Accessing process information via MXBeans or OS utilities. • Pulling in external libraries for simple process management (e.g. Apache Commons Exec). • Incomplete APIs - providing functionality to start hard-to-manage resources without providing the functionality to obtain information about them. • APIs leading the clients to use non-portable constructs.
  • 14. @mirocupak 14 Patterns • Providing convenience methods for commonly used functionality. • Compact fluent API to access nested information. • Nested public interfaces to group and organize (ProcessHandle.Info). • Using convenient static factory methods to obtain instances (ProcessHandle.[current, of, allProcesses]). • Returning streams instead of collections to streamline lazy processing of many elements (allProcesses, children, descendants…). • Returning CompletableFuture instances in asynchronous APIs (onExit). • Providing adapters via to* methods (toHandle).
  • 16. @mirocupak 16 Best practices • Clear organization: HttpClient, HttpRequest, HttpResponse. • HttpURLConnection is not pleasant to use. • The new client API is versatile, flexible and clean. • Prefer functionality in the JDK to external libraries.
  • 17. @mirocupak 17 Antipatterns • Using HttpURLConnection directly. • Inconsistent capitalization (HttpURLConnection). • Overly abstract and general APIs (URLConnection). • Unclear conceptual API model (URL). • Type casting needed to obtain the right instance (openConnection). • Using strings where methods or enums would be more practical (setRequestMethod(“GET”)). • Requiring the client to use I/O boilerplate (BufferedReader/ InputStreamReader/InputStream…).
  • 18. @mirocupak 18 Antipatterns • Mandatory blocking network I/O. • Side effects and hidden assumptions (getInputStream). • Inconsistent behaviour across APIs (URLConnection vs. Socket).
  • 19. @mirocupak 19 Patterns • Clear separation of concepts at the class level (HttpClient, HttpRequest, HttpResponse). • Builder. • Asynchronous via CompletableFuture. • Clear and consistent naming. • Convenience methods to access commonly used features (statusCode, body).