rspec/rules/S2093/java/rule.adoc

120 lines
3.3 KiB
Plaintext

== Why is this an issue?
Many resources in Java need be closed after they have been used.
If they are not, the garbage collector cannot reclaim the resources' memory, and they are still considered to be in use by the operating system.
Such resources are considered to be leaked, which can lead to performance issues.
Java 7 introduced the try-with-resources statement, which guarantees that the resource in question will be closed.
[source,java]
----
try (InputStream input = Files.newInputStream(path)) {
// "input" will be closed after the execution of this block
}
----
This syntax is safer than the traditional method using `try`, `catch`, and `finally` and hence should be preferred.
This rule raises an issue if a closeable resources is not opened using a try-with-resources statement.
This rule is automatically disabled when the project's `sonar.java.source` is lower than `7` as the close-with-resources statement was unavailable prior to Java 7.
== How to fix it
Use the try-with-resources syntax by moving the `Closable` variable declarations after the `try` keyword surrounded
by parentheses and separated by `;`:
[source,java]
----
try (/* resources declarations */) {
// resources usage ...
}
----
=== Code examples
==== Noncompliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
FileReader fr = null;
BufferedReader br = null;
try { // Noncompliant, the FileReader and BufferedReader are instantiated without try-with-resources
fr = new FileReader(fileName);
br = new BufferedReader(fr);
return br.readLine();
} catch (...) {
...
} finally {
if (br != null) { // br has to be closed manually
try {
br.close();
} catch(IOException e){...}
}
if (fr != null ) { // fr has to be closed manually
try {
br.close();
} catch(IOException e){...}
}
}
----
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
try ( // Compliant, all resources are instantiated within a try-with-resources statement and hence automatically closed after use
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr)
) {
return br.readLine();
}
catch (...) {}
----
== Resources
* https://wiki.sei.cmu.edu/confluence/x/6DZGBQ[CERT, ERR54-J.] - Use a try-with-resources statement to safely handle closeable resources
* https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html[The Java(TM) Tutorials - The try-with-resources Statement]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Change this "try" to a try-with-resources.
'''
== Comments And Links
(visible only on this page)
=== on 21 Nov 2024, 16:48:00 Alban Auzeill wrote:
[test-code-support-investigation-for-java] Decision for scope: Main -> All. It's important to close resources during tests.
=== on 12 Oct 2014, 18:26:26 Freddy Mallet wrote:
Minor point @Ann but I would associate the tag 'bug' to this rule.
=== on 12 Oct 2014, 22:18:37 Ann Campbell wrote:
I disagree [~freddy.mallet]. Properly written (and we have other rules to catch if it's not) there's no bug.
=== on 17 Oct 2014, 10:17:50 Freddy Mallet wrote:
Ok [~ann.campbell.2]
=== on 6 Jan 2016, 10:16:15 Nicolas Peru wrote:
Adding to default profile as we can rely on detection of java version.
endif::env-github,rspecator-view[]