Search code examples
javacode-analysispmddataflowstatic-code-analysis

PMD rules: How to properly solve this DD-anomaly issue


I have the following Android code:

public final List<MyObj> getList()  {
    Cursor cursor = null;
    try {
        final String queryStr = GET_LIST_STATEMENT;
        cursor = db.rawQuery(queryStr, new String[] {});
        List<MyObj> list = null;
        //here I get the data from de cursor.
        return list ;
    } catch (SQLiteFullException ex) {
        //do something to treat the exception.
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

When I run PMD analysis over this code, I get the following issue: Found 'DD'-anomaly for variable 'cursor' (lines '182'-'185').

  • The line 182 is: Cursor cursor = null;.
  • The line 185 is: cursor = db.rawQuery(queryStr, new String[] {});

So, I understand that the problem is that I'm doing a Premature Initialization in the line 182 (I never read the variable between the lines 182 and 185), but if I don't do that, I can't have the code closing the cursor in the finally block.

What to do in this case? Just ignore this PMD issue? Can I configure PMD to don't rise up this specific kind of DD-anomaly (not all DD-anomaly)? Should PMD be smart enough to doesn't rise up this issue?

Another example of DD-anomaly that I think is not a real problem:

    Date distributeDate;
    try {
        distributeDate = mDf.parse(someStringDate);
    } catch (ParseException e) {
        Log.e("Problem", "Problem parsing the date of the education. Apply default date.");
        distributeDate = Calendar.getInstance().getTime();
    }

In this case, the anomaly occurs with the distributeDate variable.


Solution

  • The documentation is pretty easy to understand:

    Either you use annotations to suppress warnings:

    // This will suppress UnusedLocalVariable warnings in this class
    @SuppressWarnings("PMD.UnusedLocalVariable")
    public class Bar {
     void bar() {
      int foo;
     }
    }
    

    or you use a comment:

    public class Bar {
     // 'bar' is accessed by a native method, so we want to suppress warnings for it
     private int bar; //NOPMD
    }
    

    When it comes to your specific code, I'd say that the easiest way to handle it is to not use a finally block even though this would look like the perfect place for it.