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

PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS false positive #329

Open
efenderbosch opened this issue Jan 7, 2019 · 3 comments
Open

PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS false positive #329

efenderbosch opened this issue Jan 7, 2019 · 3 comments

Comments

@efenderbosch
Copy link

return dbMapper.batchLoad(contactsIdsOnly).values().stream().
    flatMap(Collection::stream).
    filter(Contact.class::isInstance).
    map(Contact.class::cast). // PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS here
    collect(toList());

javac 10.0.1
spotbugs 3.1.10
fb-contrib 7.4.3.sb
MacOS, doesn't seem to happen in our Linux CI builds

@mebigfatguy
Copy link
Owner

mind running
javap -v -private YourClass

and dumping the byte code for at least this sequence of statements?

@OldIMP
Copy link

OldIMP commented Apr 19, 2022

Same issue in SonarQube Community Edition Version 8.9.7 (build 52159), which implies Findbugs Plugin v4.0.6, which implies fb-contrib v7.4.7 (sb-contrib)

@pbludov
Copy link

pbludov commented May 5, 2022

and dumping the byte code for at least this sequence of statements?

Java code

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class TestClass {

	public Set<String> test1(List<Object> list) {
		return list.stream()
                    .filter(String.class::isInstance)
                    .map(String.class::cast)
                    .collect(Collectors.toSet());
	}

	public Set<String> test2(List<Object> list) {
		Class<String> StringClass = String.class;
		return list.stream()
                    .filter(StringClass::isInstance)
                    .map(StringClass::cast)
                    .collect(Collectors.toSet());
	}

}

Dump

$ javap -v -private TestClass.class 
Classfile /home/pbludov/src/tmp/TestClass.class
  Last modified 6 мая 2022 г.; size 2162 bytes
  SHA-256 checksum bd6fdc72267018c66ad0983cacb8a8f45d53fde0a2c6238ea500db7f444b579f
  Compiled from "TestClass.java"
public class TestClass
  minor version: 0
  major version: 62
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #51                         // TestClass
  super_class: #2                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 3, attributes: 3
Constant pool:
    #1 = Methodref          #2.#3         // java/lang/Object."<init>":()V
    #2 = Class              #4            // java/lang/Object
    #3 = NameAndType        #5:#6         // "<init>":()V
    #4 = Utf8               java/lang/Object
    #5 = Utf8               <init>
    #6 = Utf8               ()V
    #7 = InterfaceMethodref #8.#9         // java/util/List.stream:()Ljava/util/stream/Stream;
    #8 = Class              #10           // java/util/List
    #9 = NameAndType        #11:#12       // stream:()Ljava/util/stream/Stream;
   #10 = Utf8               java/util/List
   #11 = Utf8               stream
   #12 = Utf8               ()Ljava/util/stream/Stream;
   #13 = Class              #14           // java/lang/String
   #14 = Utf8               java/lang/String
   #15 = Methodref          #16.#17       // java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
   #16 = Class              #18           // java/util/Objects
   #17 = NameAndType        #19:#20       // requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
   #18 = Utf8               java/util/Objects
   #19 = Utf8               requireNonNull
   #20 = Utf8               (Ljava/lang/Object;)Ljava/lang/Object;
   #21 = InvokeDynamic      #0:#22        // #0:test:(Ljava/lang/Class;)Ljava/util/function/Predicate;
   #22 = NameAndType        #23:#24       // test:(Ljava/lang/Class;)Ljava/util/function/Predicate;
   #23 = Utf8               test
   #24 = Utf8               (Ljava/lang/Class;)Ljava/util/function/Predicate;
   #25 = InterfaceMethodref #26.#27       // java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
   #26 = Class              #28           // java/util/stream/Stream
   #27 = NameAndType        #29:#30       // filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
   #28 = Utf8               java/util/stream/Stream
   #29 = Utf8               filter
   #30 = Utf8               (Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
   #31 = InvokeDynamic      #1:#32        // #1:apply:(Ljava/lang/Class;)Ljava/util/function/Function;
   #32 = NameAndType        #33:#34       // apply:(Ljava/lang/Class;)Ljava/util/function/Function;
   #33 = Utf8               apply
   #34 = Utf8               (Ljava/lang/Class;)Ljava/util/function/Function;
   #35 = InterfaceMethodref #26.#36       // java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
   #36 = NameAndType        #37:#38       // map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
   #37 = Utf8               map
   #38 = Utf8               (Ljava/util/function/Function;)Ljava/util/stream/Stream;
   #39 = Methodref          #40.#41       // java/util/stream/Collectors.toSet:()Ljava/util/stream/Collector;
   #40 = Class              #42           // java/util/stream/Collectors
   #41 = NameAndType        #43:#44       // toSet:()Ljava/util/stream/Collector;
   #42 = Utf8               java/util/stream/Collectors
   #43 = Utf8               toSet
   #44 = Utf8               ()Ljava/util/stream/Collector;
   #45 = InterfaceMethodref #26.#46       // java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
   #46 = NameAndType        #47:#48       // collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
   #47 = Utf8               collect
   #48 = Utf8               (Ljava/util/stream/Collector;)Ljava/lang/Object;
   #49 = Class              #50           // java/util/Set
   #50 = Utf8               java/util/Set
   #51 = Class              #52           // TestClass
   #52 = Utf8               TestClass
   #53 = Utf8               Code
   #54 = Utf8               LineNumberTable
   #55 = Utf8               LocalVariableTable
   #56 = Utf8               this
   #57 = Utf8               LTestClass;
   #58 = Utf8               test1
   #59 = Utf8               (Ljava/util/List;)Ljava/util/Set;
   #60 = Utf8               list
   #61 = Utf8               Ljava/util/List;
   #62 = Utf8               LocalVariableTypeTable
   #63 = Utf8               Ljava/util/List<Ljava/lang/Object;>;
   #64 = Utf8               Signature
   #65 = Utf8               (Ljava/util/List<Ljava/lang/Object;>;)Ljava/util/Set<Ljava/lang/String;>;
   #66 = Utf8               test2
   #67 = Utf8               StringClass
   #68 = Utf8               Ljava/lang/Class;
   #69 = Utf8               Ljava/lang/Class<Ljava/lang/String;>;
   #70 = Utf8               SourceFile
   #71 = Utf8               TestClass.java
   #72 = Utf8               BootstrapMethods
   #73 = MethodHandle       6:#74         // REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
   #74 = Methodref          #75.#76       // java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
   #75 = Class              #77           // java/lang/invoke/LambdaMetafactory
   #76 = NameAndType        #78:#79       // metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
   #77 = Utf8               java/lang/invoke/LambdaMetafactory
   #78 = Utf8               metafactory
   #79 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
   #80 = MethodType         #81           //  (Ljava/lang/Object;)Z
   #81 = Utf8               (Ljava/lang/Object;)Z
   #82 = MethodHandle       5:#83         // REF_invokeVirtual java/lang/Class.isInstance:(Ljava/lang/Object;)Z
   #83 = Methodref          #84.#85       // java/lang/Class.isInstance:(Ljava/lang/Object;)Z
   #84 = Class              #86           // java/lang/Class
   #85 = NameAndType        #87:#81       // isInstance:(Ljava/lang/Object;)Z
   #86 = Utf8               java/lang/Class
   #87 = Utf8               isInstance
   #88 = MethodType         #20           //  (Ljava/lang/Object;)Ljava/lang/Object;
   #89 = MethodHandle       5:#90         // REF_invokeVirtual java/lang/Class.cast:(Ljava/lang/Object;)Ljava/lang/Object;
   #90 = Methodref          #84.#91       // java/lang/Class.cast:(Ljava/lang/Object;)Ljava/lang/Object;
   #91 = NameAndType        #92:#20       // cast:(Ljava/lang/Object;)Ljava/lang/Object;
   #92 = Utf8               cast
   #93 = MethodType         #94           //  (Ljava/lang/Object;)Ljava/lang/String;
   #94 = Utf8               (Ljava/lang/Object;)Ljava/lang/String;
   #95 = Utf8               InnerClasses
   #96 = Class              #97           // java/lang/invoke/MethodHandles$Lookup
   #97 = Utf8               java/lang/invoke/MethodHandles$Lookup
   #98 = Class              #99           // java/lang/invoke/MethodHandles
   #99 = Utf8               java/lang/invoke/MethodHandles
  #100 = Utf8               Lookup
{
  public TestClass();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 5: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LTestClass;

  public java.util.Set<java.lang.String> test1(java.util.List<java.lang.Object>);
    descriptor: (Ljava/util/List;)Ljava/util/Set;
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=3, locals=2, args_size=2
         0: aload_1
         1: invokeinterface #7,  1            // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
         6: ldc           #13                 // class java/lang/String
         8: dup
         9: invokestatic  #15                 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
        12: pop
        13: invokedynamic #21,  0             // InvokeDynamic #0:test:(Ljava/lang/Class;)Ljava/util/function/Predicate;
        18: invokeinterface #25,  2           // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
        23: ldc           #13                 // class java/lang/String
        25: dup
        26: invokestatic  #15                 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
        29: pop
        30: invokedynamic #31,  0             // InvokeDynamic #1:apply:(Ljava/lang/Class;)Ljava/util/function/Function;
        35: invokeinterface #35,  2           // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
        40: invokestatic  #39                 // Method java/util/stream/Collectors.toSet:()Ljava/util/stream/Collector;
        43: invokeinterface #45,  2           // InterfaceMethod java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
        48: checkcast     #49                 // class java/util/Set
        51: areturn
      LineNumberTable:
        line 8: 0
        line 9: 9
        line 10: 26
        line 11: 40
        line 8: 51
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      52     0  this   LTestClass;
            0      52     1  list   Ljava/util/List;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            0      52     1  list   Ljava/util/List<Ljava/lang/Object;>;
    Signature: #65                          // (Ljava/util/List<Ljava/lang/Object;>;)Ljava/util/Set<Ljava/lang/String;>;

  public java.util.Set<java.lang.String> test2(java.util.List<java.lang.Object>);
    descriptor: (Ljava/util/List;)Ljava/util/Set;
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=3, locals=3, args_size=2
         0: ldc           #13                 // class java/lang/String
         2: astore_2
         3: aload_1
         4: invokeinterface #7,  1            // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
         9: aload_2
        10: dup
        11: invokestatic  #15                 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
        14: pop
        15: invokedynamic #21,  0             // InvokeDynamic #0:test:(Ljava/lang/Class;)Ljava/util/function/Predicate;
        20: invokeinterface #25,  2           // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
        25: aload_2
        26: dup
        27: invokestatic  #15                 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
        30: pop
        31: invokedynamic #31,  0             // InvokeDynamic #1:apply:(Ljava/lang/Class;)Ljava/util/function/Function;
        36: invokeinterface #35,  2           // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
        41: invokestatic  #39                 // Method java/util/stream/Collectors.toSet:()Ljava/util/stream/Collector;
        44: invokeinterface #45,  2           // InterfaceMethod java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
        49: checkcast     #49                 // class java/util/Set
        52: areturn
      LineNumberTable:
        line 16: 0
        line 17: 3
        line 18: 11
        line 19: 27
        line 20: 41
        line 17: 52
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      53     0  this   LTestClass;
            0      53     1  list   Ljava/util/List;
            3      50     2 StringClass   Ljava/lang/Class;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            0      53     1  list   Ljava/util/List<Ljava/lang/Object;>;
            3      50     2 StringClass   Ljava/lang/Class<Ljava/lang/String;>;
    Signature: #65                          // (Ljava/util/List<Ljava/lang/Object;>;)Ljava/util/Set<Ljava/lang/String;>;
}
SourceFile: "TestClass.java"
BootstrapMethods:
  0: #73 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #80 (Ljava/lang/Object;)Z
      #82 REF_invokeVirtual java/lang/Class.isInstance:(Ljava/lang/Object;)Z
      #80 (Ljava/lang/Object;)Z
  1: #73 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #88 (Ljava/lang/Object;)Ljava/lang/Object;
      #89 REF_invokeVirtual java/lang/Class.cast:(Ljava/lang/Object;)Ljava/lang/Object;
      #93 (Ljava/lang/Object;)Ljava/lang/String;
InnerClasses:
  public static final #100= #96 of #98;   // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles

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

No branches or pull requests

4 participants