Does anyone know why SonarQube detects a violation of the rule "Conditionally executed blocks should be reachable" (squid:S2583) in the following example? Is this a false positive?
In this piece of Java code, a file is read and an EOFException
(or multiple of them) can occur in the process of reading the input stream. Thus, the exception is caught and handled, and a flag is set to remember that it happened. However, Sonar does not consider the line exHappened = true;
in the first catch block and claims that variable is always false
:
public static boolean doSomething() {
boolean exHappened = false;
try (DataInputStream s = new DataInputStream(new FileInputStream("test"))) {
LOGGER.info("Doing something...");
}
catch (EOFException eof) { // this Exception can definitely happen
exHappened = true;
}
catch (IOException io) {
LOGGER.error("sorry", io);
}
if (exHappened) { // Sonar thinks this condition is always false
return false;
}
else {
return true;
}
}
To make it even more clear, add a throw new EOFException()
into the try { }
, then the condition will always be true and Sonar still claims that it always false...
(I'm using SonarQube 5.6.6 and SonarJava plugin 4.13.0.11627)
This seems to be a problem in how catch blocks are handled during data flow analysis in SonarJava. Catch block catching subtype of the exception declared in the throws declaration of called method is not being considered, hence the assignment to the variable is never seen by the engine.
I created following ticket to fix this problem https://jira.sonarsource.com/browse/SONARJAVA-2483