ring bearer
ring bearer

Reputation: 20783

try-with-resource close sequence : FileInputStream close executed three times

I was trying a simple try-with-resource example using Java 8 on OS X. I see some strange behavior. First, following is the code I am running:

 public void test() {

        try( FileInputStream fin = new FileInputStream("/tmp/test");
             FileOutputStream fout = new FileOutputStream("/tmp/test1")
                ){

            System.out.println("Nothing here");
            System.out.println("Nothing here");
        }catch (Exception e) {
            System.err.println("Error "  + e);
        }
    }

The application runs fine and prints Nothing here twice as expected. When I run this in debug mode (IntelliJ idea), execution pauses twice at FileInputSteam::close() and then pauses at FileOutputStream::close() and then again pauses at FileInputStream::close() - To check the source of this behavior, I looked at the .class file through jad-gui. It shows following code :

public void test()
  {
    try
    {
      FileInputStream fin = new FileInputStream("/tmp/test");Throwable localThrowable6 = null;
      try
      {
        FileOutputStream fout = new FileOutputStream("/tmp/test1");Throwable localThrowable7 = null;
        try
        {
          System.out.println("Nothing here");
          System.out.println("Nothing here");
        }
        catch (Throwable localThrowable1)
        {
          localThrowable7 = localThrowable1;throw localThrowable1;
        }
        finally {}
      }
      catch (Throwable localThrowable4)
      {
        localThrowable6 = localThrowable4;throw localThrowable4;
      }
      finally
      {
        if (fin != null) {
          if (localThrowable6 != null) {
            try
            {
              fin.close();
            }
            catch (Throwable localThrowable5)
            {
              localThrowable6.addSuppressed(localThrowable5);
            }
          } else {
            fin.close();
          }
        }
      }
    }
    catch (Exception e)
    {
      System.err.println("Error " + e);
    }
  }

This is more confusing.

Why the decompiled code does not show any call to FileOutputStream::close() - is it an issue with jd-gui ?

Why during debug the control goes twice to FileInputStream::close() first? Is this some bug or is this how it is supposed to work?

Upvotes: 2

Views: 471

Answers (1)

mszalbach
mszalbach

Reputation: 11470

See comment of @jb-nizet your decompiler did not show the correct things, which explains your question 1.

For question 2 have a look at the Stream.path variable in the debugger. On my System this are not the Streams openend by you but Java 8 internal files like "/opt/Oracle_Java/jdk1.8.0_40/jre/lib/tzdb.dat", "/opt/Oracle_Java/jdk1.8.0_40/jre/lib/meta-index" and the class itself. But I only have one call for the InputStream "/tmp/test" and one for the Output Stream "/tmp/test1".

Upvotes: 1

Related Questions