forked from phoedos/pmd
@ -14,6 +14,12 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
#### New Rules
|
||||
|
||||
* The new Java rule {% rule "java/bestpractices/UseTryWithResources" %) (`java-bestpractices`) searches
|
||||
for try-blocks, that could be changed to a try-with-resources statement. This statement ensures that
|
||||
each resource is closed at the end of the statement and is available since Java 7.
|
||||
|
||||
#### Modified Rules
|
||||
|
||||
* The Java rule {% rule "java/codestyle/LocalVariableCouldBeFinal" %} (`java-codestyle`) has a new
|
||||
@ -24,6 +30,7 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
* java-bestpractices
|
||||
* [#658](https://github.com/pmd/pmd/issues/658): \[java] OneDeclarationPerLine: False positive for loops
|
||||
* [#1405](https://github.com/pmd/pmd/issues/1405): \[java] New Rule: UseTryWithResources - Replace close and IOUtils.closeQuietly with try-with-resources
|
||||
* java-codestyle
|
||||
* [#1513](https://github.com/pmd/pmd/issues/1513): \[java] LocalVariableCouldBeFinal: allow excluding the variable in a for-each loop
|
||||
* java-errorprone
|
||||
|
@ -1444,6 +1444,62 @@ public class Foo {
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="UseTryWithResources"
|
||||
language="java"
|
||||
minimumLanguageVersion="1.7"
|
||||
since="6.11.0"
|
||||
message="Consider use the try-with-resources statement instead of explicitly closing the resource"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usetrywithresources">
|
||||
<description>
|
||||
Java 7 introduced the try-with-resources statement. This statement ensures that each resource is closed at the end
|
||||
of the statement. It avoids the need of explicitly closing the resources in a finally block. Additionally exceptions
|
||||
are better handled: If an exception occurred both in the `try` block and `finally` block, then the exception from
|
||||
the try block was suppressed. With the `try`-with-resources statement, the exception thrown from the try-block is
|
||||
preserved.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="closeMethods" type="List[String]" delimiter="," description="Method names in finally block, which trigger this rule" value="close,closeQuietly"/>
|
||||
<property name="version" value="2.0" />
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//TryStatement[not(ResourceSpecification)][FinallyStatement//Name[
|
||||
tokenize(@Image, '\.')[last()] = $closeMethods
|
||||
]]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
</properties>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class TryWithResources {
|
||||
public void run() {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = openInputStream();
|
||||
int i = in.read();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) in.close();
|
||||
} catch (IOException ignored) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
// better use try-with-resources
|
||||
try (InputStream in2 = openInputStream()) {
|
||||
int i = in2.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="UseVarargs"
|
||||
language="java"
|
||||
minimumLanguageVersion="1.5"
|
||||
|
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.rule.bestpractices;
|
||||
|
||||
import net.sourceforge.pmd.testframework.PmdRuleTst;
|
||||
|
||||
public class UseTryWithResourcesTest extends PmdRuleTst {
|
||||
// no additional unit tests
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<test-data
|
||||
xmlns="http://pmd.sourceforge.net/rule-tests"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd">
|
||||
<test-code>
|
||||
<description>Code sample</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>4</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class TryWithResources {
|
||||
public void run() {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = openInputStream();
|
||||
int i = in.read();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) in.close();
|
||||
} catch (IOException ignored) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
// better use try-with-resources
|
||||
try (InputStream in2 = openInputStream()) {
|
||||
int i = in2.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>With IOUtils.closeQuietly 1</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>4</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class TryWithResources {
|
||||
public void run() {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = openInputStream();
|
||||
int i = in.read();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
IOUtils.closeQuietly(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>With IOUtils.closeQuietly 2</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>4</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class TryWithResources {
|
||||
public void run() {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = openInputStream();
|
||||
int i = in.read();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
closeQuietly(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Multiple Resources</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>5</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class TryWithResources {
|
||||
public void run() {
|
||||
InputStream in1 = null;
|
||||
InputStream in2 = null;
|
||||
try {
|
||||
in1 = openInputStream();
|
||||
in2 = openInputStream();
|
||||
int x = in1.read();
|
||||
int y = in2.read();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (in1 != null) in1.close();
|
||||
} catch (IOException ignored) {
|
||||
// ignored
|
||||
}
|
||||
IOUtils.closeQuietly(in2);
|
||||
}
|
||||
|
||||
// better use try-with-resources
|
||||
try (InputStream in3 = openInputStream(); InputStream in4 = openInputStream()) {
|
||||
int x = in3.read();
|
||||
int y = in4.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Custom close methods</description>
|
||||
<rule-property name="closeMethods">myClose2,myClose</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>4</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class TryWithResources {
|
||||
public void run() {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = openInputStream();
|
||||
int i = in.read();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
myClose(in);
|
||||
}
|
||||
|
||||
// this block doesn't trigger the rule because of the custom close methods property
|
||||
try {
|
||||
in = openInputStream();
|
||||
int i = in.read();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
IOUtils.closeQuietly(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
Reference in New Issue
Block a user