try-with-resources

Last modified on August 1st, 2014 by Joe.

Java 7 gave us try-with-resources, a nice feature on exception handling. This tutorial is part 3 of the exception handling series. Part I is about basics of exception handling. Part II is about exception hierarchy, stack traces, handling exception and best practices. Now in this part three of exception handling tutorial, we will see about try-with-resources (ARM) introduced in Java version 7.

Close the resources in finally block is a well know rule for all java developers. As part of exception handling mechanism, we should always ensure to close and release the resources that is used inside the block. In a block of code which is enclosed in a try-catch block, if an exception is thrown the normal flow is altered.

try {
	//code statements
	//exception thrown here
	//lines not reached if exception thrown
} catch (Exception e) {
	//lines reached only when exception is thrown
} finally {
	//always executed
	//irrespective of an exception thrown or not
}

Look at the above code block. The best place to close and release all the resources is finally block. So what is the resource we are talking about here? Resources means database connection, file connections, etc.

Auto Close

Poor Structure

As stated above, we are going to close the resources in the finally block. Look at the following code, how ugly it looks like.

...
InputStream is = null;
try {
	is = new FileInputStream("test");
	is.read();
	...
} catch (Exception e) {
	...
} finally {
	try {
		is.close();
	} catch (IOException e) {
		e.printStackTrace();
		...
	}
}

Explicitly the programmer has to close the resource and need to surround it with a try-catch block and all inside the finally. This is a standard repeated code in java projects.

We just need to put a try-catch and we don’t do anything to handle it there. Apache’s IOUtils introduced methods to use inside finally block such as above.

org.apache.commons.io.IOUtils has methods to suppress the exception thrown inside finally block when the close method is executed.

public static void closeQuietly(InputStream input)

Automatic Resource Management (ARM)

In Java 7, we got a nice feature to manage these resources automatically. Manage is really a hype word here, all it does is close the resources. Automatic resource management, helps to close the resources automatically.

Resource instantiation should be done within try(). A parenthesis () is introduced after try statement and the resource instantiation should happen within that paranthesis as below,

try (InputStream is = new FileInputStream("test")) {
	is.read();
	...
} catch(Exception e) {
	...
} finally {
	//no need to add code to close InputStream
	//it's close method will be internally called
}

try-with-resources and AutoCloseable

Custom Implementation of AutoCloseable

Let us create a custom class that implement AutoCloseable. It is not rocket science, there is only one method named ‘close’ in the interface and implementing that is sufficient.

Lion.java

package com.javapapers.exceptionhandling;

public class Lion implements AutoCloseable {
	public Lion() {
		System.out.println("LION is OPEN in the wild.");
	};

	public void hunt() throws Exception {
		throw new Exception("DeerNotFound says Lion!");
	}

	public void close() throws Exception {
		System.out.println("LION is CLOSED in the cage.");
		throw new Exception("Unable to close the cage!");
	}
}

Tiger.java

package com.javapapers.exceptionhandling;

public class Tiger implements AutoCloseable {
	public Tiger() {
		System.out.println("TIGER is OPEN in the wild.");
	};

	public void hunt() throws Exception {
		throw new Exception("DeerNotFound says Tiger!");
	}

	public void close() throws Exception {
		System.out.println("TIGER is CLOSED in the cage.");
	}
}

TryWithResourcesExample.java

package com.javapapers.exceptionhandling;


public class TryWithResourcesExample {

	public static void main(String[] args) {
		try (Lion lion = new Lion(); Tiger tiger = new Tiger()) {

			lion.hunt();
			tiger.hunt();

		} catch (Exception e) {
			System.out.println(e);
		} finally {
			System.out.println("Finally.");
		}
	
	}
}

Output for above example:

  1. LION is OPEN in the wild.
  2. TIGER is OPEN in the wild.
  3. TIGER is CLOSED in the cage.
  4. LION is CLOSED in the cage.
  5. java.lang.Exception: DeerNotFound!
  6. Finally.

Look at the sequence of output listed above to understand the flow of control and the order in which the close method is invoked internally.

Throwable.getSuppressed Exceptions

Read the Lion and Tiger example line by line. There is an important point to understand is hidden in it. Now go back and read Lion.java

public void close() throws Exception {
	System.out.println("LION is CLOSED in the cage.");
	throw new Exception("Unable to close the cage!");
}

When try-with-resources compiled to bytecode…

As given in Java Language Specification,

try (VariableModifiersopt R Identifier = Expression ...)
    Block

following is the equivalent code of above, when converted to without try-with-resources,

{
    final VariableModifiers_minus_final R Identifier = Expression;
    Throwable #primaryExc = null;

    try ResourceSpecification_tail
        Block
    catch (Throwable #t) {
        #primaryExc = #t;
        throw #t;
    } finally {
        if (Identifier != null) {
            if (#primaryExc != null) {
                try {
                    Identifier.close();
                } catch (Throwable #suppressedExc) {
                    #primaryExc.addSuppressed(#suppressedExc);
                }
            } else {
                Identifier.close();
            }
        }
    }
}

Comments on "try-with-resources"

  1. […] Yes, this exception handling tutorial series is not complete yet and continue reading the part III of exception handling series try-with-resources. […]

  2. Praveen S M says:

    Good one..

  3. Dharmveer says:

    Thanks a lot for this well explained article…

  4. Yatheesh says:

    very nice

  5. suneetha says:

    Not BAd

  6. Renuka says:

    informative

  7. pradip garala says:

    nice work…

  8. Ajay says:

    good explainations…

  9. sudha says:

    A great post and u explained it very beautifully..Thanks for sharing your knowledge with us. Keep it up.

  10. Anonymous says:

    Thanks for sharing you knowledge with us.

    SOoo Nice of you.

  11. sailu says:

    its a fantastic article joe..simple and informative

  12. Rakesh says:

    Nice explanation..But one question, how to add customly created exceptions to be suppressed.

  13. atf says:

    DO YOU HAVE CODE FOR GETTING THE REMOTE IP ADDRESS ON SAME NETWORK(LAN) IN JAVA
    PLZ GIVE

  14. Abimaran says:

    Thank, it was nice!

  15. Shiva says:

    Good one….

  16. Neha says:

    Nice article. Well explained!

  17. Raj says:

    It’s really good…..

  18. Chirag Moradiy says:

    Well explained!!

    It is the must-use feature which I wasn’t using so far though my projects run on jdk7. I will definitely use this feature and suggest my team to do the same.

    Thanks for giving us your valuable time in writing this article.

  19. Varshu says:

    HI Joe,

    Your blog provides lot of good information. This is nice feature in Java 7. Thanks for bringing it in notice.

  20. amit sarang says:

    thax joe.

    nice to learn from u. whatever read upto now from ur blog always interesting and informativ. i like to read ur blog rather than book.

  21. Anonymous says:

    Nice feature of java 7.

  22. Ragav says:

    Very informative.. :)

  23. Venkat says:

    Nice explanation….

  24. Ravi says:

    Sounds good..

  25. great tutorial, thanks for sharing.

  26. abhi says:

    Hi Joe,

    Thanks for the tutorial. One output line seems missing, i.e.
    “java.lang.Exception: DeerNotFound says Lion!”

    I know it is obivious,but just to avoid any confusion. Thanks.

    Also,can you please add some Java Spring(frameworks) tutorial etc. Thanks in advance.

  27. jagnya says:

    thank u sir………

  28. Andrew says:

    Hey Joe,

    Thanks for a nice tutorial about try-with-resources statement!
    The only thing I would add is a word of caution regarding chaining resources like:

    try (Reader reader = new BufferedReader(new FileReader(“file”))) {
    // …
    }

  29. samir says:

    Thanks for the nice explanation.

  30. Chaula Ganatra says:

    Very well explained.
    Thanks Joe.

  31. dheeraj says:

    THNAK U FOR THIS WONDERFUL KNOWLEDGE…..

  32. Dilip says:

    Nice tutorial on try with resource.

Comments are closed for "try-with-resources".