Java suppressed exceptions with example

Suppressed exceptions, as name suggest, are exceptions thrown in the code but were ignored somehow. If you remember try-catch-finally block execution sequence and how they return any value or exceptions, you will recall that exceptions thrown in finally block are suppressed if an exception is thrown in try block also.

Before java 7, you was informed about these exceptions by logging if implemented, but you didn’t have any control over these types of exceptions once finally block is over.

Well, with new features in Java 7, you got control over these suppressed exceptions as well.

Table of contents

1. What are suppressed exceptions?
2. Suppressed exception example
3. Demonstration in different scenarios

1. What are suppressed exceptions?

In Java 7, perhaps the most common use case for encountering suppressed exceptions is when a try-with-resources statement. When we encounter an exception within the try block, application tries to close the resource. If it encounters multiple exceptions which may occur while closing AutoCloseable resources, additional exceptions are attached to a primary exception as suppressed exceptions.

To support suppressed exceptions, a new constructor and two new methods were added to the Throwable class (parent of Exception and Error classes) in JDK 7.

Throwable.getSupressed(); // Returns Throwable[]
Throwable.addSupressed(aThrowable);

2. Suppressed exception example

For example while writing to output stream, an exception can be thrown from the try block, and up to two exceptions can be thrown from the try-with-resources statement when it tries to close the stream.

If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed, and the exception thrown by the block is the one that is thrown by the closeStream() method.

You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed() method from the exception thrown by the try block.

3. Demonstration in different scenarios

For example purpose, I am writing an auto closeable resource (i.e. DirtyResource.java) which throws exceptions whether we try to access it or close it. This way we will be able to see different behavior when accessed in different manner.

public class DirtyResource implements AutoCloseable
{
	/**
	 * Need to call this method if you want to access this resource
	 * @throws RuntimeException no matter how you call this method
	 * */
	public void accessResource()
	{
		throw new RuntimeException("I wanted to access this resource. Bad luck. Its dirty resource !!!");
	}

	/**
	 * The overridden closure method from AutoCloseable interface
	 * @throws Exception which is thrown during closure of this dirty resource
	 * */
	@Override
	public void close() throws Exception
	{
		throw new NullPointerException("Remember me. I am your worst nightmare !! I am Null pointer exception !!");
	}
}

3.1. Before suppressed exceptions feature

package com.howtodoinjava.demo.core;

import static java.lang.System.err;

public class SuppressedExceptionDemoWithTryFinallyPrevious
{
	/**
    * Executable member function demonstrating suppressed exceptions
    * One exception is lost if not added in suppressed exceptions list
    */
	public static void memberFunction() throws Exception
	{
		DirtyResource resource= new DirtyResource();
		try
	    {
	    	  resource.accessResource();
	    }
		finally
		{
			resource.close();
		}
	}

	public static void main(String[] arguments) throws Exception
   {
      try
      {
    	  memberFunction();
      }
      catch(Exception ex)
      {
    	  err.println("Exception encountered: " + ex.toString());
    	  final Throwable[] suppressedExceptions = ex.getSuppressed();
    	  final int numSuppressed = suppressedExceptions.length;
    	  if (numSuppressed > 0)
    	  {
    		  err.println("tThere are " + numSuppressed + " suppressed exceptions:");
	    	  for (final Throwable exception : suppressedExceptions)
	    	  {
	    		  err.println("tt" + exception.toString());
	    	  }
    	  }
      }
   }
}

Output:

Exception encountered: java.lang.NullPointerException: Remember me. I am your worst nightmare !! I am Null pointer exception !!

As you can see that only one exception was captured and second RuntimeException was suppressed.

3.2. After suppressed exceptions support in Java 7

package com.howtodoinjava.demo.core;

import static java.lang.System.err;

public class SuppressedExceptionDemoWithTryFinallyNew
{
	/**
    * Executable member function demonstrating suppressed exceptions
    * Suppressed expression is added back in primary exception
    */
	public static void memberFunction() throws Exception
	{
		Throwable th = null;
		DirtyResource resource= new DirtyResource();
		try
	    {
	    	  resource.accessResource();
	    }
		catch(Exception e)
		{
			th = e;
		}
		finally
		{
			try
			{
				resource.close();
			}
			catch(Exception e)
			{
				if(th != null)
				{
					e.addSuppressed(th); //Add to primary exception
					throw e;
				}
			}
		}
	}
   /**
    * Executable function demonstrating suppressed exceptions.
    */
   public static void main(String[] arguments) throws Exception
   {
      try
      {
    	  memberFunction();
      }
      catch(Exception ex)
      {
    	  err.println("Exception encountered: " + ex.toString());
    	  final Throwable[] suppressedExceptions = ex.getSuppressed();
    	  final int numSuppressed = suppressedExceptions.length;
    	  if (numSuppressed > 0)
    	  {
    		  err.println("tThere are " + numSuppressed + " suppressed exceptions:");
	    	  for (final Throwable exception : suppressedExceptions)
	    	  {
	    		  err.println("tt" + exception.toString());
	    	  }
    	  }
      }
   }
}

Output:

Exception encountered: java.lang.NullPointerException: Remember me. I am your worst nightmare !! I am Null pointer exception !!
	There are 1 suppressed exceptions:
		java.lang.RuntimeException: I wanted to access this resource. Bad luck. Its dirty resource !!!

Here, in catch block we are able to access both exception. One as primary exception and second as suppressed exception.

3.3. try-with-resource block in a member function and catching the exception

package com.howtodoinjava.demo.core;

import static java.lang.System.err;

public class SuppressedExceptionDemoWithTryCatch
{
	public static void memberFunction() throws Exception
	{
		try (DirtyResource resource= new DirtyResource())
	      {
	    	  resource.accessResource();
	      }
	}
   /**
    * Executable member function demonstrating suppressed exceptions using try-with-resources
    */
   public static void main(String[] arguments) throws Exception
   {
      try
      {
    	  memberFunction();
      }
      catch(Exception ex)
      {
    	  err.println("Exception encountered: " + ex.toString());
    	  final Throwable[] suppressedExceptions = ex.getSuppressed();
    	  final int numSuppressed = suppressedExceptions.length;
    	  if (numSuppressed > 0)
    	  {
    		  err.println("tThere are " + numSuppressed + " suppressed exceptions:");
	    	  for (final Throwable exception : suppressedExceptions)
	    	  {
	    		  err.println("tt" + exception.toString());
	    	  }
    	  }
      }
   }
}

Output:

Exception encountered: java.lang.RuntimeException: I wanted to access this resource. Bad luck. Its dirty resource !!!
	There are 1 suppressed exceptions:
		java.lang.NullPointerException: Remember me. I am your worst nightmare !! I am Null pointer exception !!

Great !! We are able to see both exceptions when using try-with-resource in member function.

3.4. Default try-with-resource block

package com.howtodoinjava.demo.core;

public class SuppressedExceptionDemoWithTryWithResource
{
   /**
    * Demonstrating suppressed exceptions using try-with-resources
    */
   public static void main(String[] arguments) throws Exception
   {
      try (DirtyResource resource= new DirtyResource())
      {
    	  resource.accessResource();
      }
   }
}

Output:

Exception in thread "main" java.lang.RuntimeException: I wanted to access this resource. Bad luck. Its dirty resource !!!
	at DirtyResource.accessResource(DirtyResource.java:9)
	at SuppressedExceptionDemoWithTryWithResource.main(SuppressedExceptionDemoWithTryWithResource.java:12)
	Suppressed: java.lang.NullPointerException: Remember me. I am your worst nightmare !! I am Null pointer exception !!
		at DirtyResource.close(DirtyResource.java:19)
		at SuppressedExceptionDemoWithTryWithResource.main(SuppressedExceptionDemoWithTryWithResource.java:13)

Well, this is really great to see the output with complete information with suppressed exceptions as well.

Happy Learning !!

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

5 thoughts on “Java suppressed exceptions with example”

  1. Hi Lokesh,

    I am bit confused, in scenario 1, second RuntimeException was suppressed.
    And in scenario 4, first NullPointerException is suppressed.

    Please clarify it!!

    Reply
  2. Hi Lokesh ,
    I am bit confused with lines mentioned below . Please correct me If I’m going to wrong path. Lines are —
    ” If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed, and the exception thrown by the block is the one that is thrown by the closeStream() method.”

    By the help of these lines you are trying to say that ultimately exception of TRY block will be thrown and other exceptions occurred during closing the resources will be suppressed…… Right ??

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.