Exception Handling in Eclipse Collections

Donald Raab
Javarevisited
Published in
4 min readSep 17, 2020

Some strategies for handling exceptions in Eclipse Collections before and after Java 8

Handling checked exceptions with iteration patterns and lambdas can feel like walking on ice

The Inspiration for this post

Brian Vermeer wrote a great blog on Exception Handling in Java Streams.

The post reminded me of the exception handling support we have had in Eclipse Collections for a few years now. I thought I would show some simple examples of handling Checked Exceptions using Eclipse Collections before and after Java 8. I will also show examples that will work with Java Streams.

The Dependable Appendable

There is an interface in Java named Appendable. Appendable is a parent interface of StringBuilder, StringBuffer, PrintStream and several other classes. The interface has been around since Java 5. It defines a method append as follows:

If I create a MutableList of String, and attempt to use append as a method reference with the forEach method, my IDE gives me a warning saying there is an Unhandled Exception: java.io.IOException.

Unhandled Exception: java.io.IOException

As it turns out, StringBuilder doesn’t actually throw a java.io.IOException in its method signature for the append method. So if I change the type to StringBuilder, the exception will go away.

The StringBuilder accept method doesn’t throw java.io.IOException

The same would be true if I changed the code to use StringBuffer. However, all Appendable implementations that deal with files will most likely throw the exception. So if I use the interface, and not specific implementations, I will have to handle the exception. The ugly way of handling the exception prior to Java 8, might look as follows.

This is a common pattern, catching a checked exception and throwing a RuntimeException. It was common enough for us before Java 8 that we had specific “Checked” versions of the different functional interfaces in Eclipse Collections. There is a package named “checked” in each of the functional interface packages (function, predicate, procedure). Using a CheckedProcedure, we could simplify the code as follows:

How to deal with checked exceptions before Java 8

If an exception is thrown by the Appendable, the exception will be caught and if it is a RuntimeException, it will be bubbled up. If it is a checked exception, a RuntimeException will be created and thrown with the checked exception set as the cause.

After Java 8, we introduced new interfaces to deal with Checked Exceptions. For each Functional Interface type (Function, Predicate, Procedure) there is a corresponding “throwing” type (ThrowingFunction, ThrowingPredicate, ThrowingProcedure). There are also corresponding methods on the factories for the the functional interfaces (Functions.throwing, Predicates.throwing, Procedures.throwing). Using the combination of these features with Java 8 or above we can now write the following:

Dealing with checked exceptions with Java 8 or above

You can also use the same approach with Java Collections and Java Streams.

Using Java 8+ forEach method on Iterable which takes Consumer

This code works, because the Procedure interface in Eclipse Collections extends the Consumer interface. The code will work using as a Stream as well.

Using Stream forEach which also takes Consumer

Throwing your own RuntimeExceptions

If you want to control the type of RuntimeException that is thrown, there is an overloaded version of the throwing method that supports this.

The Function2 takes the current element, the exception caught and the RuntimeException type to rethrow

Let’s say I want to rethrow an UndependableAppendableException in case an IOException is caught in the call to append. The code might look as follows:

The UndependableAppendableException constructor matches the Function2 signature defined in throwing

Notice, I kept the code here working with Java Stream. It would work the same using forEach on a List or a MutableList from Eclipse Collections.

But wait, what about…

This is the exception handling capability that exists today in Eclipse Collections. If there are additional capabilities you would like, consider submitting issues requesting features or making contributions via pull requests to the Eclipse Collection project. We welcome new contributors to Eclipse Collections. Check out the following blog for more information on how to get started.

I am a Project Lead and Committer for the Eclipse Collections OSS project at the Eclipse Foundation. Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub.

--

--

Donald Raab
Javarevisited

Java Champion. Creator of the Eclipse Collections OSS Java library (https://github.com/eclipse/eclipse-collections). Inspired by Smalltalk. Opinions are my own.