Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spotbugs reports VR_UNRESOLVABLE_REFERENCE when code is compiled with Java 11 #1254

Closed
trancexpress opened this issue Aug 13, 2020 · 4 comments · Fixed by #1334
Closed

spotbugs reports VR_UNRESOLVABLE_REFERENCE when code is compiled with Java 11 #1254

trancexpress opened this issue Aug 13, 2020 · 4 comments · Fixed by #1334
Assignees

Comments

@trancexpress
Copy link
Contributor

trancexpress commented Aug 13, 2020

We have some code with nested inner classes calling private methods in the outer class. As we are trying to compile our product with Java 11, we notice a ton of VR_UNRESOLVABLE_REFERENCE reports from spotbugs.

This seems to boil down to JEP-181: https://openjdk.java.net/jeps/181

Synthetic accessors seem to be no longer necessary; the compiler does not generate them. From what I can tell, when code is compiled with Java 11, ResolveAllReferences.visit() falls into the ConstantCP case for method calls (CONSTANT_Methodref) that previously needed synthetic accessors (but now no longer do). The method is not found, as its private (see how defined is filled in ResolveAllReferences.addAllDefinitions()). spotbugs then reports VR_UNRESOLVABLE_REFERENCE, which is false; our product tests run just fine with the Java 11 compiled code.

Example:

...:/home/sandreev$ /usr/lib/jvm/java-11/bin/javac Foo.java
...:/home/sandreev$ javap Foo.class
Compiled from "Foo.java"
public class Foo {
  public Foo();
  public static void main(java.lang.String[]);
  public void bar();
}
...:/home/sandreev$ /usr/lib/jvm/java-1.8.0/bin/javac Foo.java
...:/home/sandreev$ javap Foo.class
Compiled from "Foo.java"
public class Foo {
  public Foo();
  public static void main(java.lang.String[]);
  public void bar();
  static void access$000(Foo);
}
...:/home/sandreev$ cat Foo.java 
public class Foo {

    public static void main(String[] args) {
        new Foo().bar();
    }

    public void bar() {
        java.lang.Runnable r = new java.lang.Runnable() {
            @java.lang.Override
            public void run() {                                                                                                                                                                                                              
                foo();                                                                                                                                                                                                                       
            }                                                                                                                                                                                                                                
        };                                                                                                                                                                                                                                   
        r.run();                                                                                                                                                                                                                             
    }                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
    private void foo() {                                                                                                                                                                                                                     
        System.out.println("Foo.foo()");                                                                                                                                                                                                     
    }                                                                                                                                                                                                                                        
}

See my comment below for a reproducer.

@trancexpress
Copy link
Contributor Author

Snippet to reproduce:

public class Foo {

    public void bar() {
        new java.lang.Runnable() {
            @java.lang.Override
            public void run() {
                foo();
            }
        }.run();
    }

    private void foo() {
        System.out.println("Foo.foo()");
    }
}

Settings:

detectorResolveAllReferences=ResolveAllReferences|true
detector_threshold=3
effort=default
filter_settings=Low|BAD_PRACTICE,CORRECTNESS,EXPERIMENTAL,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false|20

Results with Java 11 (bad):

...:/home/sandreev$ /usr/lib/jvm/java-11/bin/javac Foo.java
...:/home/sandreev$ javap Foo*.class
Compiled from "Foo.java"
class Foo$1 implements java.lang.Runnable {
  final Foo this$0;
  Foo$1(Foo);
  public void run();
}
Compiled from "Foo.java"
public class Foo {
  public Foo();
  public void bar();
}
...:/home/sandreev$ /home/sandreev/git/misc/spotbugs/spotbugs/build/distributions/spotbugs-4.1.2-SNAPSHOT/bin/spotbugs -textui -maxRank 20 -low -xml -userPrefs edu.umd.cs.findbugs.core.prefs Foo*.class
visiting className=java.lang.Object, name=<init>, signature=()V, co=CONSTANT_Methodref[10](class_index = 5, name_and_type_index = 22)
visiting className=Foo, name=foo, signature=()V, co=CONSTANT_Methodref[10](class_index = 18, name_and_type_index = 23)
visiting className=java.lang.Object, name=<init>, signature=()V, co=CONSTANT_Methodref[10](class_index = 9, name_and_type_index = 20)
visiting className=Foo$1, name=<init>, signature=(LFoo;)V, co=CONSTANT_Methodref[10](class_index = 2, name_and_type_index = 22)
visiting className=Foo$1, name=run, signature=()V, co=CONSTANT_Methodref[10](class_index = 2, name_and_type_index = 23)
visiting className=java.io.PrintStream, name=println, signature=(Ljava/lang/String;)V, co=CONSTANT_Methodref[10](class_index = 27, name_and_type_index = 28)
<?xml version="1.0" encoding="UTF-8"?>

<BugCollection version="4.1.2-SNAPSHOT" sequence="0" timestamp="1597333990000" analysisTimestamp="1597333997840" release="">
  <Project projectName="">
    <Jar>Foo$1.class</Jar>
    <Jar>Foo.class</Jar>
  </Project>
  <BugInstance type="UPM_UNCALLED_PRIVATE_METHOD" priority="3" rank="20" abbrev="UPM" category="PERFORMANCE">
    <Class classname="Foo">
      <SourceLine classname="Foo" start="1" end="14" sourcefile="Foo.java" sourcepath="Foo.java"/>
    </Class>
    <Method classname="Foo" name="foo" signature="()V" isStatic="false">
      <SourceLine classname="Foo" start="13" end="14" startBytecode="0" endBytecode="36" sourcefile="Foo.java" sourcepath="Foo.java"/>
    </Method>
  </BugInstance>
  <BugInstance type="VR_UNRESOLVABLE_REFERENCE" priority="2" rank="7" abbrev="VR" category="CORRECTNESS">
    <Class classname="Foo$1">
      <SourceLine classname="Foo$1" start="4" end="8" sourcefile="Foo.java" sourcepath="Foo.java"/>
    </Class>
    <String value="Foo.foo : ()V"/>
  </BugInstance>
  <Errors errors="0" missingClasses="0"></Errors>
  <FindBugsSummary timestamp="Thu, 13 Aug 2020 17:53:10 +0200" total_classes="2" referenced_classes="15" total_bugs="2" total_size="17" num_packages="1" java_version="1.8.0_262" vm_version="25.262-b10" cpu_seconds="6.97" clock_seconds="0.77" peak_mbytes="263.30" alloc_mbytes="683.00" gc_seconds="0.05" priority_3="1" priority_2="1">
    <PackageStats package="" total_bugs="2" total_types="2" total_size="17" priority_3="1" priority_2="1">
      <ClassStats class="Foo" sourceFile="Foo.java" interface="false" size="10" bugs="1" priority_3="1"/>
      <ClassStats class="Foo$1" sourceFile="Foo.java" interface="false" size="7" bugs="1" priority_2="1"/>
    </PackageStats>
    <FindBugsProfile>
      <ClassProfile name="edu.umd.cs.findbugs.classfile.engine.ClassInfoAnalysisEngine" totalMilliseconds="176" invocations="337" avgMicrosecondsPerInvocation="523" maxMicrosecondsPerInvocation="37575" standardDeviationMicrosecondsPerInvocation="2345"/>
      <ClassProfile name="edu.umd.cs.findbugs.classfile.engine.bcel.JavaClassAnalysisEngine" totalMilliseconds="41" invocations="197" avgMicrosecondsPerInvocation="208" maxMicrosecondsPerInvocation="10656" standardDeviationMicrosecondsPerInvocation="787"/>
      <ClassProfile name="edu.umd.cs.findbugs.detect.FieldItemSummary" totalMilliseconds="27" invocations="15" avgMicrosecondsPerInvocation="1852" maxMicrosecondsPerInvocation="7987" standardDeviationMicrosecondsPerInvocation="2560"/>
      <ClassProfile name="edu.umd.cs.findbugs.classfile.engine.bcel.MethodGenFactory" totalMilliseconds="25" invocations="5" avgMicrosecondsPerInvocation="5194" maxMicrosecondsPerInvocation="25378" standardDeviationMicrosecondsPerInvocation="10092"/>
      <ClassProfile name="edu.umd.cs.findbugs.util.TopologicalSort" totalMilliseconds="23" invocations="304" avgMicrosecondsPerInvocation="78" maxMicrosecondsPerInvocation="1663" standardDeviationMicrosecondsPerInvocation="172"/>
      <ClassProfile name="edu.umd.cs.findbugs.OpcodeStack$JumpInfoFactory" totalMilliseconds="19" invocations="63" avgMicrosecondsPerInvocation="312" maxMicrosecondsPerInvocation="2976" standardDeviationMicrosecondsPerInvocation="436"/>
      <ClassProfile name="edu.umd.cs.findbugs.detect.FindNoSideEffectMethods" totalMilliseconds="18" invocations="15" avgMicrosecondsPerInvocation="1224" maxMicrosecondsPerInvocation="6666" standardDeviationMicrosecondsPerInvocation="1723"/>
      <ClassProfile name="edu.umd.cs.findbugs.detect.NoteDirectlyRelevantTypeQualifiers" totalMilliseconds="11" invocations="15" avgMicrosecondsPerInvocation="794" maxMicrosecondsPerInvocation="5424" standardDeviationMicrosecondsPerInvocation="1334"/>
      <ClassProfile name="edu.umd.cs.findbugs.classfile.engine.ClassDataAnalysisEngine" totalMilliseconds="11" invocations="338" avgMicrosecondsPerInvocation="35" maxMicrosecondsPerInvocation="516" standardDeviationMicrosecondsPerInvocation="49"/>
      <ClassProfile name="edu.umd.cs.findbugs.classfile.engine.bcel.ValueNumberDataflowFactory" totalMilliseconds="11" invocations="5" avgMicrosecondsPerInvocation="2269" maxMicrosecondsPerInvocation="9815" standardDeviationMicrosecondsPerInvocation="3784"/>
      <ClassProfile name="edu.umd.cs.findbugs.classfile.engine.bcel.CFGFactory" totalMilliseconds="11" invocations="5" avgMicrosecondsPerInvocation="2247" maxMicrosecondsPerInvocation="10235" standardDeviationMicrosecondsPerInvocation="3994"/>
    </FindBugsProfile>
  </FindBugsSummary>
  <ClassFeatures></ClassFeatures>
  <History></History>
</BugCollection>

Results with Java 8 (good):

...:/home/sandreev$ /usr/lib/jvm/java-1.8.0/bin/javac Foo.java
...:/home/sandreev$ javap Foo*.class
Compiled from "Foo.java"
class Foo$1 implements java.lang.Runnable {
  final Foo this$0;
  Foo$1(Foo);
  public void run();
}
Compiled from "Foo.java"
public class Foo {
  public Foo();
  public void bar();
  static void access$000(Foo);
}
...:/home/sandreev$ /home/sandreev/git/misc/spotbugs/spotbugs/build/distributions/spotbugs-4.1.2-SNAPSHOT/bin/spotbugs -textui -maxRank 20 -low -xml -userPrefs edu.umd.cs.findbugs.core.prefs Foo*.class
visiting className=java.lang.Object, name=<init>, signature=()V, co=CONSTANT_Methodref[10](class_index = 10, name_and_type_index = 23)
visiting className=Foo$1, name=<init>, signature=(LFoo;)V, co=CONSTANT_Methodref[10](class_index = 3, name_and_type_index = 25)
visiting className=Foo$1, name=run, signature=()V, co=CONSTANT_Methodref[10](class_index = 3, name_and_type_index = 26)
visiting className=java.io.PrintStream, name=println, signature=(Ljava/lang/String;)V, co=CONSTANT_Methodref[10](class_index = 30, name_and_type_index = 31)
visiting className=java.lang.Object, name=<init>, signature=()V, co=CONSTANT_Methodref[10](class_index = 5, name_and_type_index = 21)
visiting className=Foo, name=access$000, signature=(LFoo;)V, co=CONSTANT_Methodref[10](class_index = 18, name_and_type_index = 22)
<?xml version="1.0" encoding="UTF-8"?>

<BugCollection version="4.1.2-SNAPSHOT" sequence="0" timestamp="1597334095000" analysisTimestamp="1597334106042" release="">
  <Project projectName="">
    <Jar>Foo$1.class</Jar>
    <Jar>Foo.class</Jar>
  </Project>
  <Errors errors="0" missingClasses="0"></Errors>
  <FindBugsSummary timestamp="Thu, 13 Aug 2020 17:54:55 +0200" total_classes="2" referenced_classes="15" total_bugs="0" total_size="18" num_packages="1" java_version="1.8.0_262" vm_version="25.262-b10" cpu_seconds="6.32" clock_seconds="0.72" peak_mbytes="263.00" alloc_mbytes="683.00" gc_seconds="0.05">
    <PackageStats package="" total_bugs="0" total_types="2" total_size="18">
      <ClassStats class="Foo" sourceFile="Foo.java" interface="false" size="11" bugs="0"/>
      <ClassStats class="Foo$1" sourceFile="Foo.java" interface="false" size="7" bugs="0"/>
    </PackageStats>
    <FindBugsProfile>
      <ClassProfile name="edu.umd.cs.findbugs.classfile.engine.ClassInfoAnalysisEngine" totalMilliseconds="163" invocations="337" avgMicrosecondsPerInvocation="485" maxMicrosecondsPerInvocation="38302" standardDeviationMicrosecondsPerInvocation="2228"/>
      <ClassProfile name="edu.umd.cs.findbugs.classfile.engine.bcel.JavaClassAnalysisEngine" totalMilliseconds="35" invocations="195" avgMicrosecondsPerInvocation="179" maxMicrosecondsPerInvocation="10412" standardDeviationMicrosecondsPerInvocation="778"/>
      <ClassProfile name="edu.umd.cs.findbugs.detect.FieldItemSummary" totalMilliseconds="24" invocations="15" avgMicrosecondsPerInvocation="1601" maxMicrosecondsPerInvocation="6687" standardDeviationMicrosecondsPerInvocation="2143"/>
      <ClassProfile name="edu.umd.cs.findbugs.util.TopologicalSort" totalMilliseconds="22" invocations="304" avgMicrosecondsPerInvocation="73" maxMicrosecondsPerInvocation="1081" standardDeviationMicrosecondsPerInvocation="143"/>
      <ClassProfile name="edu.umd.cs.findbugs.classfile.engine.bcel.MethodGenFactory" totalMilliseconds="20" invocations="6" avgMicrosecondsPerInvocation="3432" maxMicrosecondsPerInvocation="19844" standardDeviationMicrosecondsPerInvocation="7339"/>
      <ClassProfile name="edu.umd.cs.findbugs.OpcodeStack$JumpInfoFactory" totalMilliseconds="18" invocations="64" avgMicrosecondsPerInvocation="294" maxMicrosecondsPerInvocation="2699" standardDeviationMicrosecondsPerInvocation="402"/>
      <ClassProfile name="edu.umd.cs.findbugs.detect.FindNoSideEffectMethods" totalMilliseconds="18" invocations="15" avgMicrosecondsPerInvocation="1211" maxMicrosecondsPerInvocation="6574" standardDeviationMicrosecondsPerInvocation="1699"/>
      <ClassProfile name="edu.umd.cs.findbugs.classfile.engine.ClassDataAnalysisEngine" totalMilliseconds="12" invocations="338" avgMicrosecondsPerInvocation="35" maxMicrosecondsPerInvocation="1082" standardDeviationMicrosecondsPerInvocation="77"/>
    </FindBugsProfile>
  </FindBugsSummary>
  <ClassFeatures></ClassFeatures>
  <History></History>
</BugCollection>

@iloveeclipse
Copy link
Member

Fixed via #1334.

@prosprice
Copy link

@iloveeclipse does this fix mean #811 can be closed?

@iloveeclipse
Copy link
Member

@iloveeclipse does this fix mean #811 can be closed?
I assume yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants