SonarJava: TryWithResourcesCheck: try-with-resources is not equivalent to try-finally

51 views
Skip to first unread message

edp...@gmail.com

unread,
Jan 23, 2018, 4:11:19 PM1/23/18
to SonarQube
try-with-resources is not equivalent to try-finally as try-with-resources will always throw any exception thrown from close, but that is not usually wanted.
There are important projects that are not migrating to try-with-resources because of this issue:
https://github.com/spring-projects/spring-framework/pull/1098

Migrating try-finally to try-with-resources may introduce bugs if the resource can throw exceptions on close

If there are strong arguments to remove TryWithResourcesCheck, the rule could be fixed by only suggesting the change when the resource close method does not throw any exception.

Tibor Blenessy

unread,
Jan 24, 2018, 3:46:50 AM1/24/18
to edp...@gmail.com, SonarQube
Hello,

there is no inherent issue to use try-with-resources, you can still have the catch block attached to it and you can catch the exception thrown from close and suppress it if necessary. The only difference is that close will be already called on all declared resources, which is especially useful when dealing with multiple resources.  You can find this behavior documented here   https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html#suppressed-exceptions 

Hope that helps.

Tibor



--
You received this message because you are subscribed to the Google Groups "SonarQube" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sonarqube+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sonarqube/75488bcb-fcb8-4c89-af80-1d1ae6305730%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--

Tibor Blenessy | SonarSource

SonarJava Developer

https://sonarsource.com 

edp...@gmail.com

unread,
Jan 24, 2018, 3:25:42 PM1/24/18
to SonarQube
Hi Tibor,

I am not sure what you mean.
Here is a sample program.
Could you fix it so that the close exception is just logged, while exceptions in the try block are thrown?


public class TryWithResourcesTest {

    public static void main(String[] args) throws Exception {

        try (MyClosable a = new MyClosable()) {
            if (System.currentTimeMillis() % 2 == 0) {
                throw new RuntimeException("Exception on try block");
            }
        }

        System.out.println("Finished successfully");
    }

}

class MyClosable implements AutoCloseable {

    @Override
    public void close() throws Exception {
        throw new RuntimeException("Exception during close");
    }

}


Thanks

Tibor Blenessy

unread,
Jan 25, 2018, 12:31:05 PM1/25/18
to edp...@gmail.com, SonarQube
Hello,

have a look on this gist how this can be achieved

Distinguishing by exception message is not ideal, however that's not an issue of try-with-resources. You can design your exceptions so they are more easily distinguishable. Also note that I don't need to close the resource in finally, as this is handled automatically. Especially with multiple resources this quickly becomes unwieldy with classic try-catch-finally statement.

How exactly this is done is described in detail in Java Language Specification, check it out here https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.3.1 

Anyhow, check is just a check. It should never be applied blindly and without consideration, that's why you can always mark issue as "wont fix" and provide a comment explaining the context.

Best regards

Tibor






For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages