Tuesday, June 14, 2011

Java7 Automatic resource management

ARM:

One of the useful features in Java7 is the Automatic resource management via the try-with-resources statement.

In the olden days thou would (or atleast were supposed to) code like:
void doSomething() throws IOException {
  OutputStream out = null;
  try {
    out = new FileOutputStream("");
    out.write(data);
  } finally {
    if (out != null) {
      out.close();
    }
  }
}

Which is error prone if you do forget to close the resources.

The new way is:

void doSomethingNew() throws IOException {
  try (OutputStream out = new FileOutputStream("")) {
    out.write(data);
  }
}

This is syntactically much more pleasing and does the right thing internally.

Going deep:
The try-with syntax works with any AutoCloseable implementation and you can have multiple resources as well.

The compiler will transform the above code into something like:

void doSomethingNew() throws IOException {
  OutputStream out = null;
  Throwable localThrowable1 = null;
  try {
    out = new FileOutputStream("");
    out.write(blah);
  } catch (Throwable localThrowable2) {
    // We keep a reference to which can add a suppressed exception
    localThrowable1 = localThrowable2;
    throw localThrowable2;
  } finally {
    if (out != null) {
      if (localThrowable1 != null) {
        // Already have an exception thrown
        try {
          out.close();
        } catch (Throwable localThrowable3) {
          // Add the suppressed exception during close
          localThrowable1.addSuppressed(localThrowable3);
        }
      } else {
        // Potentially throw an IOException due to failure when close'ing
        out.close();
      }
    }
  }
}

The pattern is:

  • If there are no exception - close() in the finally block OR
  • If there are no exception during operation but there is an exception during close() then throw it OR
  • If there is an exception thrown then throw it after closing the resource OR
  • If there is an exception1 thrown then throw it .. and if there is an exception2 closing the resource.. then exception1.addSuppressed(exception2). This is new in theThrowable class

Sidenote:
There was a huge effort to get closures into Java7 but none of the solutions was light on syntax/complexity. After the backlash over Generics a smaller but better step has been taken.

Sidenote++:
For scala see using. You do not need to wait for language changes to make syntactically pleasing APIs because of curry-ing and other fancy stuff.


More References:
ARM spec
Article on ARM

2 comments:

POS Hardware said...

I would like to thank you for the efforts you have made in writing this article. I learned a lot. Thanks for sharing!!

ArranyList and Java said...

Java7 Project coin is good enhancement in programmers armory for day 2 day work, though not big as changes in Java5. Out of all features
automatic resource management and fork join framework in java7 is my favorite with bit of interest on multiple catch block