3

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)?

pants
  • 192
  • 13
Kevin Cruijssen
  • 9,153
  • 9
  • 61
  • 135

1 Answers1

3

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.

Maciej Dobrowolski
  • 11,561
  • 5
  • 45
  • 67
  • Well, too be honest, I knew about IntelliJ. I'm coming from a C# background and used ReSharper in Visual Studio. Later I've heard that IntelliJ is from the same makers as ReSharper, so they have a lot of similar functionality. Unfortunately the project I'm currently working on is in Eclipse. It obviously isn't top priority, but I thought that if there is something simple to change this all at the same time it would be nice. Since there isn't, we'll just change it when we come across the old try-close_in_finally, and perhaps one day search for all of them to change them at the same time. Thanks – Kevin Cruijssen Feb 29 '16 at 07:47
  • 1
    @KevinCruijssen your project does not even need to compile/work with IntelliJ. You can just import it there, do the replacements, save files and go back to Eclipse. – Maciej Dobrowolski Feb 29 '16 at 08:52
  • Good point. Will install IntelliJ soon and do the replacements. At my current job we use Friday afternoon for all kind of non-project related things like refactoring, code coverage with new unit tests, sharing problems / new stuff we've came across, etc. For now I will accept your answer. Once again thanks. – Kevin Cruijssen Feb 29 '16 at 09:04
  • I am a little confused by one line that you said: try-with-resources statement does not catch resource closing exceptions. But on the page https://stackoverflow.com/questions/17739362/java7-try-with-resources-statement-advantage says and close() is automatically called, if it throws an IOException, it will be supressed (as specified in the Java Language Specification 14.20.3) . Same happens for java.sql.Connection I don't know for sure which is right, but I believe that the error is surpressed, or ignored. – Karl Henselin Jun 23 '17 at 14:54
  • @KarlHenselin you're right, exception will be surpressed. My point was that sometimes you want to handle such exception and using that syntax you will not be allowed to do so :) I'll edit the answer to be more specific. Thanks! – Maciej Dobrowolski Jun 24 '17 at 12:16