Menu

#1414 EC_UNRELATED_TYPES goes undetected in Lambdas

3.x
closed-rejected
nobody
None
5
2017-10-22
2015-08-21
saidin
No

When writing String.equals(Integer), FindBugs will report "EC_UNRELATED_TYPES: This method calls equals(Object) on two references of different class types with no common subclasses.".

However, doing the same thing in a Lambda goes unnoticed. This is quite common when using something like the stream filter API.

I was able to reproduce this (JDK8 u51, FindBugs 3.0.1) with the following test:

package regressions;

import edu.umd.cs.findbugs.annotations.ExpectWarning;

public class UnrelatedTypesInLambda {
    @ExpectWarning("EC_UNRELATED_TYPES")
    public void unrelatedPlain() {
        String lhs = "";
        Integer rhs = 1;
        lhs.equals(rhs);
    }

    // This has the same bug as the above example but it isn't detected by FindBugs.
    // @ExpectWarning("EC_UNRELATED_TYPES")
    public void unrelatedLambda() {
        String lhs = "";
        Integer rhs = 1;
        final Runnable lambda = () -> {
            lhs.equals(rhs);
        };

        lambda.run();
    }
}

Discussion

  • Tagir Valeev

    Tagir Valeev - 2015-10-08

    The bug is reported in this case. The difference is that it's reported not for unrelatedLambda method, but for compiled lambda body, so you cannot easily annotate it with @ExpectWarning. Here's the full XML report:

    <BugInstance type="EC_UNRELATED_TYPES" priority="3" rank="6" abbrev="EC" category="CORRECTNESS" first="1">
      <Class classname="regressions.UnrelatedTypesInLambda">
        <SourceLine classname="regressions.UnrelatedTypesInLambda" sourcefile="UnrelatedTypesInLambda.java" sourcepath="regressions/UnrelatedTypesInLambda.java"/>
      </Class>
      <Method classname="regressions.UnrelatedTypesInLambda" name="lambda$0" signature="(Ljava/lang/String;Ljava/lang/Integer;)V" isStatic="true">
        <SourceLine classname="regressions.UnrelatedTypesInLambda" start="20" end="21" startBytecode="0" endBytecode="4" sourcefile="UnrelatedTypesInLambda.java" sourcepath="regressions/UnrelatedTypesInLambda.java"/>
      </Method>
      <Type descriptor="Ljava/lang/Integer;" role="TYPE_FOUND">
        <SourceLine classname="java.lang.Integer" start="52" end="1590" sourcefile="Integer.java" sourcepath="java/lang/Integer.java"/>
      </Type>
      <Type descriptor="Ljava/lang/String;" role="TYPE_EXPECTED">
        <SourceLine classname="java.lang.String" start="111" end="3128" sourcefile="String.java" sourcepath="java/lang/String.java"/>
      </Type>
      <LocalVariable name="?" register="1" pc="2" role="LOCAL_VARIABLE_VALUE_OF"/>
      <Method classname="java.lang.String" name="equals" signature="(Ljava/lang/Object;)Z" isStatic="false" role="METHOD_EQUALS_USED">
        <SourceLine classname="java.lang.String" start="965" end="983" startBytecode="0" endBytecode="208" sourcefile="String.java" sourcepath="java/lang/String.java"/>
      </Method>
      <SourceLine classname="regressions.UnrelatedTypesInLambda" start="20" end="20" startBytecode="2" endBytecode="2" sourcefile="UnrelatedTypesInLambda.java" sourcepath="regressions/UnrelatedTypesInLambda.java"/>
      <SourceLine classname="regressions.UnrelatedTypesInLambda" start="20" end="20" startBytecode="2" endBytecode="2" sourcefile="UnrelatedTypesInLambda.java" sourcepath="regressions/UnrelatedTypesInLambda.java"/>
      <Property name="FOUND_IN_SYNTHETIC_METHOD" value="true"/>
    </BugInstance>
    

    As you can see, it's reported in autogenerated method regressions.UnrelatedTypesInLambda.lambda$0(String, Integer) and has no information that this lambda is called in unrelatedLambda method, thus @ExpectWarning annotation does not work here. We may improve support of lambdas (currently it's very poor). See also GitHub issue#51.

     

    Last edit: Tagir Valeev 2015-10-08
  • saidin

    saidin - 2015-10-08

    The reason I wrote the test was because a bug made it's way past build which is set to fail if any bug is reported. Clearly my test is bad, but I still believe there is a bug here.

    I'll try write a better test. Thanks for the pointer about the lambdas; I'll be sure to check the full report.

     
  • Arnaud

    Arnaud - 2016-05-22

    I have a similar issue.
    Problems are not detected inside lambda body, in Eclipse:

    static String x = "xxx";
    static String y = "yyy";
    
    public static void main(String[] args)  {
        if (x == y) // OK, detected
            System.out.println();
    
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                if (x == y) // OK, detected
                    System.out.println();       
            }           
        };
        r1.run();
    
        Runnable r2 = () -> {
            if (x == y) // PROBLEM, not detected!
                System.out.println();
        };
        r2.run();
    }
    
     
  • Andrey Loskutov

    Andrey Loskutov - 2017-10-22
    • Status: open --> closed-rejected
     

Log in to post a comment.

MongoDB Logo MongoDB