-
Notifications
You must be signed in to change notification settings - Fork 14.2k
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
MINOR: Disallow unused local variables #18963
base: trunk
Are you sure you want to change the base?
Conversation
@@ -74,7 +74,7 @@ static void verifyVersionsMatchTopLevelMessage( | |||
verifyVersionsMatchTopLevelMessage(what, topLevelMessage, field); | |||
} | |||
for (StructSpec struct : topLevelMessage.commonStructs()) { | |||
for (FieldSpec field : topLevelMessage.fields()) { | |||
for (FieldSpec field : struct.fields()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually looks like a bug to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the patch @lucasbru! I'm always in favor of safety improvements :)
I don't love that we have to suppress warnings, but I understand we're a bit constrained due to our wide range of Java versions. It doesn't look like we have too many required suppressions.
For a few places where you have created an ignored
variable and a suppression, I noticed something interesting. If we remove the assignment, I get an IDEA warning about ignoring the result of a method. However, it does not fail the checkstyle.
I think we should evaluate each of these individually to determine if its safe to ignore the result. I left comments on these inline.
@SuppressWarnings("UnusedLocalVariable") | ||
boolean ignored = copyQuotaManagerLockCondition.await(quotaTimeout().toMillis(), TimeUnit.MILLISECONDS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abhijeetk88 @satishd, is it safe to ignore the result of the await here?
@@ -74,7 +74,7 @@ static void verifyVersionsMatchTopLevelMessage( | |||
verifyVersionsMatchTopLevelMessage(what, topLevelMessage, field); | |||
} | |||
for (StructSpec struct : topLevelMessage.commonStructs()) { | |||
for (FieldSpec field : topLevelMessage.fields()) { | |||
for (FieldSpec field : struct.fields()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -169,6 +169,7 @@ public LoadedLogOffsets load() throws IOException { | |||
long offset = LogFileUtils.offsetFromFile(file); | |||
if (offset >= minSwapFileOffset && offset < maxSwapFileOffset) { | |||
logger.info("Deleting segment files {} that is compacted but has not been deleted yet.", file.getName()); | |||
@SuppressWarnings("UnusedLocalVariable") | |||
boolean ignore = file.delete(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we actually check if the file was deleted?
@mimaison I see you worked the Java conversion of this class. WDYT about checking the result of delete
and renameTo
below?
@@ -885,7 +885,8 @@ public Set<StreamTask> drainRestoredActiveTasks(final Duration timeout) { | |||
restoredActiveTasksLock.lock(); | |||
try { | |||
while (restoredActiveTasks.isEmpty() && now <= deadline) { | |||
final boolean elapsed = restoredActiveTasksCondition.await(deadline - now, TimeUnit.MILLISECONDS); | |||
@SuppressWarnings("UnusedLocalVariable") | |||
final boolean ignored = restoredActiveTasksCondition.await(deadline - now, TimeUnit.MILLISECONDS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cadonna do we need to check the result of the await here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It really does not matter in that case whether we got interrupted or the timeout expired. We could consider just removing the local here. It will be flagged by intellij though.
@@ -79,7 +79,8 @@ public static void main(String[] args) { | |||
shareConsumers.forEach(shareConsumer -> shareConsumersMetrics.add(shareConsumer.metrics())); | |||
} | |||
shareConsumers.forEach(shareConsumer -> { | |||
Map<TopicIdPartition, Optional<KafkaException>> val = shareConsumer.commitSync(); | |||
@SuppressWarnings("UnusedLocalVariable") | |||
Map<TopicIdPartition, Optional<KafkaException>> ignored = shareConsumer.commitSync(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AndrewJSchofield do we need to check the result of commitSync?
clients/src/test/java/org/apache/kafka/clients/consumer/internals/FetcherTest.java
Outdated
Show resolved
Hide resolved
...ect/runtime/src/test/java/org/apache/kafka/connect/integration/MonitorableSinkConnector.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice improvement @lucasbru!
I know that in some places in Java you can use __
to ignore a parameter, but this seems like a more comprehensive solution. I'm actually surprised there are so few places with unused variables.
@lucasbru try updating this PR with trunk. That should fix the build scan errors |
Recently, we found a regression that could have been detected by static analysis, since a local variable wasn't being passed to a method during a refactoring, and was left unused. It was fixed in 7a749b5, but almost slipped into 4.0. Unused variables are typically detected by IDEs, but this is insufficient to prevent these kinds of bugs. This change enables unused local variable detection in checkstyle for Kafka.
A few notes on the usage:
for (Type ignored: collection)
loops which have to loopcollection.length
number of times, but that do not useignored
in the loop body. These are typically still easier to read than a classicalfor
loop. Second, some IDEs detect it if a return value of a function such asFile.delete
is not being used. In this case, people sometimes store the result in an unused local variable to make ignoring the return value explicit and to avoid the squiggly lines._
. This is supported by checkstyle. In pre-22 versions, IntelliJ allows such variables to be namedignored
to suppress the unused local variable warning. This pattern is often (but not consistently) used in the Kafka codebase. This is, however, not supported by checkstyle.Since we cannot switch to Java 22, yet, and we want to use automated detection using checkstyle, we have to resort to prefixing the unused local variables with
@SuppressWarnings("UnusedLocalVariable")
. We have to apply this in 11 cases across the Kafka codebase. While not being pretty, I'd argue it's worth it to prevent bugs like the one fixed in 7a749b5.Committer Checklist (excluded from commit message)