Java for each loop being flagged as UR anomaly by PMD

John Doe picture John Doe · Feb 6, 2014 · Viewed 9.5k times · Source

I would like to confirm if this is a bug on PMD? How do I file a ticket if it is.

    public static void main(final String[] args) {
        for (final String string : args) {
            string.getBytes(); //UR Anomaly
        }
        for (int i = 0; i < args.length; i++) {
            args[i].getBytes();
        }
    }

Lines 1-3 are being flagged as UR anomaly, while rewriting it to iterate with a local variable is fine.

Would like to eliminate as much PMD violations, but it is inconvenient to have to resort to old loop construct as a workaround.

While controversial, I do not wish to disable this rule since I find DD, and DU anomaly flagging as useful.

Answer

barfuin picture barfuin · Feb 6, 2014

It appears that you have hit a bug in PMD. The DataflowAnomalyAnalysis rule does not seem to catch all possible kinds of variable definitions (another example found here). UR stands for "undefined reference", which is obviously incorrect.

So, what can you do?

Since the problem appears to affect mostly the UR part of the rule, you can disable it and continue using the DU and DD parts. You need a fairly recent version of PMD to do this. In your ruleset file, suppress UR findings like this:

<rule ref="rulesets/java/controversial.xml/DataflowAnomalyAnalysis">
    <properties>
        <property name="violationSuppressRegex" value="^Found 'UR'-anomaly.*"/>
    </properties>
</rule>

Update: For PMD 6.+, the rule ref has changed (thanks ZuziaKru):

<rule ref="category/java/errorprone.xml/DataflowAnomalyAnalysis">
    <properties>
        <property name="violationSuppressRegex" value="^Found 'UR'-anomaly.*"/>
    </properties>
</rule>

In my humble opinion, the whole UR checking is a bit over the top, because the compiler will not accept undefined references. And these days, running the compiler is no longer such a big deal.