Return values from functions without side effects should not be ignored
[…] and also on ConcurrentMap.putIfAbsent calls ignored return value.

Is this just SonarQube not detecting that the side effect of the method is enough for me here (and the return value would not add any information) or am I missing an important point about the putIfAbsent contract, perhaps related to concurrency, since it’s explicitly only for ConcurrentMap?

The putIfAbsent method is typically used to ensure that a single value is associated with a given key (the first value for which put if absent succeeds). If you ignore the return value and retain a reference to the value passed in, you run the risk of retaining a value that is not the one that is associated with the key in the map. If it matters which one you use and you use the one that isn’t stored in the map, your program will behave incorrectly.

Now this starts to make some sense.

Coming back to your case, as you are not holding a reference to new ConcurrentHashMap<K, V>(), there is no risk for your program to work on inconsistent data as described in FindBugs’ rule description.

So my conclusion is that your code is indeed safe. Additionally, I believe that SONARJAVA-2546 should have been implemented as a separate rule rather than as an extension to RSPEC-2201. I’ll sync with our product team to see how to get those changes in.

Thanks alot for this extremely thoughtfull analysis and explanation @dbolkensteyn, it was very enlightening.

Additionally, I suggest not limiting this to ConcurrentMap in the new rule, since the basic reasoning is true for any Map-Implementation (and limiting it to ConurrentMap leads to the idea that this has something to do with Concurrency).