X

Musings on JDK development

  • Java
    February 16, 2011

Project Coin:try-with-resources on a null resource

After due consideration the JSR 334 expert group has decided the semantics of the try-with-resources statement on a null resource should be changed as follows: the compiler-generated calls to close a resource will only occur if the resource is non-null.

Concretely, the semantics of the desugaring of the finally block are changed from

finally {
if (#primaryException != null) {
try {
#resource.close();
} catch(Throwable #suppressedException) {
#primaryException.addSuppressed(#suppressedException);
}
} else {
#resource.close();
}
}

to

finally {
if (#primaryException != null) {
try {
if(#resource != null)
#resource.close();
} catch(Throwable #suppressedException) {
#primaryException.addSuppressed(#suppressedException);
}
} else {
if(#resource != null)
#resource.close();
}
}

This decision was informed by discussions on coin-dev as well as experiments retrofitting try-with-resources onto the JDK libraries.

The change allows idioms like

try(Resource r = methodThatMightReturnNull()) {
if (r == null)
return; // nothing to do
}

to complete normally without generating a null pointer exception. Note that the programmer still has responsibility to check for a null resource if the resource is used inside the try block; the generated null check does not occur before the try block is entered.

Implementing the change is being tracked under Oracle bug 7020047 "Project Coin: generate null-check around try-with-resources close call."

Join the discussion

Comments ( 3 )
  • Damon Hart-Davis Thursday, February 17, 2011

    That potential double-testing of nullness seems a waste (conditionals blow out pipelines) unless the JIT is definitely smart enough to hoist the common (sub)expression out of the block.

    Rgds

    Damon


  • Joe Darcy Thursday, February 17, 2011

    @Damon,

    While at most one test of the resource against null would be executed, it is better to not repeat the code for the test. (The close call itself has to be repeated since its exceptional behavior, if any, has to be treated differently depending on the whether or not there is an existing exception.)

    I've modified my implementation to hoist out the null check of the resource and all the regression tests pass; thanks for the suggestion!

    -Joe


  • Damon Hart-Davis Thursday, February 17, 2011

    I wasn't even paying attention to the aspect that you just improved (though feel free to send my medal anyway); I was thinking of the now treble repetition of the nullness test between your code and the user's code, and wondering if hoisting your test out of the block would make it easier for even a dumb JIT to invisibly use your already-computed final boolean in place of the user's own test...

    But, I'll let you go on thinking I meant what I said... %\^P

    Rgds

    Damon


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.