Some strategies for handling exceptions in Eclipse Collections before and after Java 8
The Inspiration for this post
Brian Vermeer wrote a great blog on Exception Handling in Java Streams.
Exception Handling in Java Streams
The Stream API and lambda's where a big improvement in Java since version 8. From that point on, we could work with a…
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 is a parent interface of
PrintStream and several other classes. The interface has been around since Java 5. It defines a method
append as follows:
If I create a
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:
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 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:
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 (
Procedure) there is a corresponding “throwing” type (
ThrowingProcedure). There are also corresponding methods on the factories for the the functional interfaces (
Procedures.throwing). Using the combination of these features with Java 8 or above we can now write the following:
This code works, because the
Procedure interface in Eclipse Collections extends the
Consumer interface. The code will work using as a
Stream as well.
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.
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:
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.
Shhhh! I’m going to tell you a secret. It’s something that for a few people might just change their software…
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.