forked from phoedos/pmd
#1387 CloseResource has false positive for ResultSet
This commit is contained in:
@ -31,6 +31,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTVariableInitializer;
|
||||
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
|
||||
import net.sourceforge.pmd.lang.rule.properties.BooleanProperty;
|
||||
import net.sourceforge.pmd.lang.rule.properties.StringMultiProperty;
|
||||
|
||||
import org.jaxen.JaxenException;
|
||||
@ -58,14 +59,18 @@ public class CloseResourceRule extends AbstractJavaRule {
|
||||
|
||||
private Set<String> closeTargets = new HashSet<String>();
|
||||
private static final StringMultiProperty CLOSE_TARGETS_DESCRIPTOR = new StringMultiProperty("closeTargets",
|
||||
"Methods which may close this resource", new String[] {"close"}, 1.0f, ',');
|
||||
"Methods which may close this resource", new String[] {}, 1.0f, ',');
|
||||
|
||||
private static final StringMultiProperty TYPES_DESCRIPTOR = new StringMultiProperty("types", "Affected types",
|
||||
new String[] { "java.sql.Connection", "java.sql.Statement", "java.sql.ResultSet" }, 2.0f, ',');
|
||||
|
||||
private static final BooleanProperty USE_CLOSE_AS_DEFAULT_TARGET = new BooleanProperty("closeAsDefaultTarget",
|
||||
"Consider 'close' as a target by default", true, 3.0f);
|
||||
|
||||
public CloseResourceRule() {
|
||||
definePropertyDescriptor(CLOSE_TARGETS_DESCRIPTOR);
|
||||
definePropertyDescriptor(TYPES_DESCRIPTOR);
|
||||
definePropertyDescriptor(USE_CLOSE_AS_DEFAULT_TARGET);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -73,6 +78,9 @@ public class CloseResourceRule extends AbstractJavaRule {
|
||||
if (closeTargets.isEmpty() && getProperty(CLOSE_TARGETS_DESCRIPTOR) != null) {
|
||||
closeTargets.addAll(Arrays.asList(getProperty(CLOSE_TARGETS_DESCRIPTOR)));
|
||||
}
|
||||
if (getProperty(USE_CLOSE_AS_DEFAULT_TARGET) && !closeTargets.contains("close")) {
|
||||
closeTargets.add("close");
|
||||
}
|
||||
if (types.isEmpty() && getProperty(TYPES_DESCRIPTOR) != null) {
|
||||
types.addAll(Arrays.asList(getProperty(TYPES_DESCRIPTOR)));
|
||||
}
|
||||
|
@ -604,6 +604,54 @@ public class CloseResourceTest {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#1387 CloseResource has false positive for ResultSet</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<rule-property name="closeTargets">closeConnection,closeCloseable,closeReader,closeResource,closeResultSet,closeStream,closeStatement</rule-property>
|
||||
<code><![CDATA[
|
||||
public class CloseResource {
|
||||
public void querySomething(Connection connection) {
|
||||
Statement stmt = null; // it complains this is not closed
|
||||
ResultSet resultSet = null; // it complains this is not closed
|
||||
String someSql = "select something...";
|
||||
try {
|
||||
stmt = connection.createStatement();
|
||||
resultSet = stmt.executQuery(someSql);
|
||||
while (resultSet.next()) {
|
||||
// do something
|
||||
}
|
||||
} finally {
|
||||
if (resultSet != null) {
|
||||
resultSet.close();
|
||||
}
|
||||
if (stmt != null) {
|
||||
stmt.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Verify closeAsDefaultTarget property</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<rule-property name="closeAsDefaultTarget">false</rule-property>
|
||||
<code><![CDATA[
|
||||
public class CloseResource {
|
||||
public void doSomething() {
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet resultSet = stmt.executeQuery("select ...");
|
||||
try {
|
||||
} finally {
|
||||
resultSet.close();
|
||||
stmt.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
@ -10,6 +10,10 @@
|
||||
|
||||
**New/Modified/Deprecated Rules:**
|
||||
|
||||
* java-design/CloseResource: New Property *closeAsDefaultTarget* which is *true* by default to stay
|
||||
backwards compatible. If this property is *true*, the rule will make sure, that `close` itself is
|
||||
always considered as a *closeTarget* - no matter whether it is configured with the *closeTargets* property
|
||||
or not.
|
||||
|
||||
**Pull Requests:**
|
||||
|
||||
@ -18,6 +22,8 @@
|
||||
|
||||
* java-controversial/DefaultPackage:
|
||||
[#1410](https://sourceforge.net/p/pmd/bugs/1410/): DefaultPackage triggers on field annotated with @VisibleForTesting
|
||||
* java-design/CloseResource:
|
||||
[#1387](https://sourceforge.net/p/pmd/bugs/1387/): CloseResource has false positive for ResultSet
|
||||
* java-strings/InsufficientStringBufferDeclaration:
|
||||
[#1409](https://sourceforge.net/p/pmd/bugs/1409/): NullPointerException in InsufficientStringBufferRule
|
||||
|
||||
|
Reference in New Issue
Block a user