[java] CloseResource: add new property "closeNotInFinally"

This commit is contained in:
Andreas Dangel
2020-08-21 09:33:24 +02:00
parent 36f61f44aa
commit b73b1e92f3
3 changed files with 22 additions and 0 deletions

View File

@ -36,6 +36,16 @@ See also [[all] Ensure PMD/CPD uses tab width of 1 for tabs consistently #2656](
cases where the variable of the caught exception is reassigned. This practice is surprising and prevents
further evolution of the code like multi-catch.
#### Modified Rules
* The Java rule {% rule "java/errorprone/CloseResource" %} (`java-errorprone`) has a new property
`closeNotInFinally`. With this property set to `true` the rule will also find calls to close a
resource, which are not in a finally-block of a try-statement. If a resource is not closed within a
finally block, it might not be closed at all in case of exceptions.
As this new detection would yield many new violations, it is disabled by default. It might be
enabled in a later version of PMD.
#### Deprecated Rules
* The Java rule {% rule "java/errorprone/DataflowAnomalyAnalysis" %} (`java-errorprone`)

View File

@ -93,6 +93,10 @@ public class CloseResourceRule extends AbstractJavaRule {
"java.util.stream.DoubleStream")
.build();
private static final PropertyDescriptor<Boolean> DETECT_CLOSE_NOT_IN_FINALLY =
booleanProperty("closeNotInFinally")
.desc("Detect if 'close' (or other closeTargets) is called outside of a finally-block").defaultValue(false).build();
private final Set<String> types = new HashSet<>();
private final Set<String> simpleTypes = new HashSet<>();
private final Set<String> closeTargets = new HashSet<>();
@ -106,6 +110,7 @@ public class CloseResourceRule extends AbstractJavaRule {
definePropertyDescriptor(TYPES_DESCRIPTOR);
definePropertyDescriptor(USE_CLOSE_AS_DEFAULT_TARGET);
definePropertyDescriptor(ALLOWED_RESOURCE_TYPES);
definePropertyDescriptor(DETECT_CLOSE_NOT_IN_FINALLY);
}
@Override
@ -622,6 +627,10 @@ public class CloseResourceRule extends AbstractJavaRule {
@Override
public Object visit(ASTPrimaryPrefix prefix, Object data) {
if (!getProperty(DETECT_CLOSE_NOT_IN_FINALLY)) {
return super.visit(prefix, data);
}
ASTName methodCall = prefix.getFirstChildOfType(ASTName.class);
if (methodCall != null && isNodeInstanceOfResourceType(methodCall)) {
String closedVar = getVariableClosedByMethodCall(methodCall);

View File

@ -377,6 +377,7 @@ public class Test {
<test-code>
<description>#947 CloseResource rule fails if field is marked with annotation</description>
<rule-property name="closeNotInFinally">true</rule-property>
<expected-problems>2</expected-problems>
<expected-linenumbers>8,9</expected-linenumbers>
<expected-messages>
@ -548,6 +549,7 @@ public class Bar {
<test-code>
<description>#1375 CloseResource not detected properly - ok</description>
<rule-property name="closeNotInFinally">true</rule-property>
<expected-problems>1</expected-problems>
<expected-linenumbers>6</expected-linenumbers>
<expected-messages>
@ -1308,6 +1310,7 @@ public class Foo {
<test-code>
<description>wrapped ByteArrayInputStream false-negative test</description>
<rule-property name="closeNotInFinally">true</rule-property>
<expected-problems>1</expected-problems>
<expected-linenumbers>7</expected-linenumbers>
<expected-messages>