Over a million developers have joined DZone.

Using exceptions when designing an API

DZone's Guide to

Using exceptions when designing an API

· Performance Zone
Free Resource

Many know the tradeoff of using exceptions while designing an application:

  • On one hand, using try-catch block nicely segregates between regular code and exception handling code
  • On the other hand, using exceptions has a definite performance cost for the JVM

Every time I’ve faced this quandary, I’ve ruled in favor of the former, because “premature optimization is evil”. However, this week has proved to me that exception handling in designing an API is a very serious decision.

I’ve been working to improve the performance of our application and I’ve noticed many silent catches coming from the Spring framework (with the help of the excellent dynaTrace tool). The guilty lines come from the RequestContext.initContext() method:

if (this.webApplicationContext.containsBean(REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME)) {
    this.requestDataValueProcessor = this.webApplicationContext.getBean(
    REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME, RequestDataValueProcessor.class);

Looking at the JavaDocs, it is clear that this method (and the lines above) are called each time the Spring framework h s a request. For web applications under heavy load, this means quite a lot! I provided a pass-through implementation of the RequestDataValueProcessor and patched one node of the cluster. After running more tests, we noticed response times were on average 5% faster on the patched node compared to the un-patched node. This is not my point however.

Should an exception be thrown when the bean is not present in the context? I think not… as the above snippet confirms. Other situations e.g. injecting dependencies, might call for an exception to be thrown, but in this case, it has to be the responsibility of the caller code to throw it or not, depending on the exact situation.

There are plenty of viable alternatives to exceptions throwing:

Returning null
    This means the intent of the code is not explicit without looking at the JavaDocs, and so the worst option on our list

Returning an Optional<T>
    This makes the intent explicit compared to returning null. Of course, this requires Java 8

Return a Guava’s Optional<T>
    For those of us who are not fortunate enough to have Java 8

Returning one’s own Optional<T>
    If you don’t use Guava and prefer to embed your own copy of the class instead of relying on an external library

Returning a Try
    Cook up something like Scala’s Try, which wraps either (hence its old name – Either) the returned bean or an exception. In this case, however, the exception is not thrown but used like any other object – hence there will be no performance problem.

Conclusion: when designing an API, one should really keep using exceptions for exceptional situations only.

As for the current situation, Spring’s BeanFactory class lies at center of a web of dependencies and its multiple getBean() method implementation cannot be easily replaced with one of the above options without forfeiting backward compatibility. One solution, however, would be to provide api tional getBeanSafe() methods (or a better relevant name) using one of the above options, and then replace usage of their original counterpart step by step inside the Spring framework.


Published at DZone with permission of Nicolas Frankel, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}