javaeclipsecheckstyletry-with-resourcestry-finally

try-finally with close auto-refactoring to try-with-resources with codestyle/checkstyle


I am working on a codebase that has recently migrated from Java 6 to Java 7. I would like to replace constructions like this:

Connection conn = null;
try{
    conn = new Connection();
    ...
} catch(Exception ex){
    ...
} finally{
    if (conn != null){
        conn.close();
    }
}

with try-with-resources (available from Java 1.7 onward):

try(Connection conn = new Connection()){
    ...
} catch(Exception ex){
    ...
}

Is there an automated way to automatically refactor the old to the new (perhaps with the Checkstyle-plugin, or within Eclipse itself)?


Solution

  • It would be difficult to change it all quickly. Please note that sometimes there's another try-catch block in finally which catches exceptions thrown while closing resource.

    try-with-resources statement does allow you to handle resource closing exceptions (exceptions thrown at close method will be surpressed).

    I haven't heard of such Eclipse feature, but if you may want to use IntelliJ IDEA Community Edition IDE just for this sole purpose.

    #1

    You can use code inspection features called:

    1. 'try finally' replaceable with 'try' with resources.
    2. AutoCloseable used without 'try' with resources

    You should just press Ctrl+Alt+Shift, write inspection name and hit Enter. After that you will see places where IDEA can apply this pattern, but be aware that it doesn't cover 100% cases.

    #2

    Another way, more difficult, but greatly customizable is Structural Search and Replace functionality. You can define there structure which is to be changed:

    try {
        $type$ $objectName$ = new $concreteType$($args$)
        $tryStatements$;
    } catch($exceptionType$ $exceptionName$) {
        $catchStatements$;
    } finally {
        $finallyStatements$;
    }
    

    And the final structure:

    try ($type$ $objectName$ = new $concreteType$($args$)) {
      $tryStatements$;
    } catch($exceptionType$ $exceptionName$) {
        $catchStatements$;
    }
    

    In variable settings you can require that $concreteType$ implements AutoCloseable interface.

    But please note, that:

    1. I get rid of finally block here and support single catch block.
    2. There's also assumption that there would be single resource opened per one try-with-resources block.
    3. As mentioned before - there's no exception handling in finally block.

    This template certainly needs more work and it just may not be worthwhile to do it.