java:S6204 incorectly reports modifiable list as needs to be unmodifiable

I’m using SonarLint in IntelliJ, and it’s incorrectly reporting java:S6204, it wants me to use .toList() but I don’t want an unmodifiable list, it needs to remain a regular ArrayList.

In the image above it’s asking to turn it into an unmodifiable list whilst the method above (purely there for showing off the problem, actual invocation is elsewhere) wants to modify the result, and thus it can’t possibly be an unmodifiable list.

The rule does work when the 2 blocks are within the same method.

I think this rule needs to be less strict, there’s theoretically not a mandatory need to have everything be unmodifiable, if you are using .collect(Collectors.toUnmodifiableList()), then you want to change it, but if you are using .collect(Collectors.toList()), I don’t think Sonar should make the decision if it should be a unmodifiable or not as Sonar can’t / doesn’t check methods down the line whether it should be modifiable.

Hey there.

Can you please share a self-contained sample of code in text format, rather than a screenshot?

Sure thing, made an empty project locally and put the following in the main class:

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

public class Main
{
    public static void main(String[] args)
    {
        final List<String> test = test();
        test.add("C");
    }

    public static List<String> test()
    {
        return Stream.of("A", "B").collect(Collectors.toList());
    }
}

Even in this small code block Sonar wants to replace it with .toList()

Hi Thom, thanks for reporting this issue, as it is clearly an annoying FP.
The check that implements this rule is actually not looking outside the scope of the method where the list gets created, and so it reports whenever the list is not modified locally by the method test.

I have created a ticket to fix this, and hopefully we will be able to work on it in the near future.

Have a good day!