Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Java: Add java/javautilconcurrentscheduledthreadpoolexecutor query for zero thread pool size #19844

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

tamasvajk
Copy link
Contributor

@tamasvajk tamasvajk commented Jun 23, 2025

This pull request introduces a new query to identify potential issues with setting the corePoolSize of ScheduledThreadPoolExecutor to zero, which may lead to unintended behavior and programmer error. The changes include adding the query logic, documentation, test cases, and integration into the query suite.

MRVA top 100 only reports 4 alerts. I checked autofix on 3 of these. Two autofix suggestions completely removed the executor.setCorePoolSize(0) calls, the third one changed the 0 value to Schedulers.DEFAULT_POOL_SIZE, which is the value used in setMaximumPoolSize.

@tamasvajk tamasvajk force-pushed the tamasvajk/threadpoolexecutor branch from e2b0faa to c6a4221 Compare June 23, 2025 10:11
@tamasvajk tamasvajk force-pushed the tamasvajk/threadpoolexecutor branch from c6a4221 to 60e726b Compare June 23, 2025 10:52
@tamasvajk tamasvajk marked this pull request as ready for review June 24, 2025 10:59
@tamasvajk tamasvajk requested a review from a team as a code owner June 24, 2025 10:59
@tamasvajk tamasvajk added the no-change-note-required This PR does not need a change note label Jun 24, 2025

from IntegerLiteral zero, Sink set
where
DataFlow::localFlow(DataFlow::exprNode(zero), DataFlow::exprNode(set.getArgument(0))) and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any particular reason why only local flow is used (instead of making a data flow configuration and using global flow)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if there's any reason. I simply migrated the query as is from the private repo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tried the below:

private module FlowConfig implements DataFlow::ConfigSig {
  predicate isSource(DataFlow::Node source) { source.asExpr().(IntegerLiteral).getIntValue() = 0 }

  predicate isSink(DataFlow::Node sink) { exists(Sink s | s.getArgument(0) = sink.asExpr()) }
}

private module Flow = DataFlow::Global<FlowConfig>;

from DataFlow::Node sinkNode, Sink s
where Flow::flow(_, sinkNode) and s.getArgument(0) = sinkNode.asExpr()
select s, "ScheduledThreadPoolExecutor.corePoolSize is set to have 0 threads."

It resulted in some new findings, for example this, which is a FP.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Where is the source of the FP located?
  • Are you categorising it as an FP due to the threads > 0 check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't checked the source, only saw the threads > 0 check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason the global dataflow doesn't properly use the guard check threads > 0 in this case. Not sure why that happens (it works fine in a local flow example). Let's keep it as it is then (as you also mentioned offline - the most relevant usecase is probably immediate initialisation with 0 or something that can be picked up by local flow).

@@ -0,0 +1,35 @@
/**
* @id java/javautilconcurrentscheduledthreadpoolexecutor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe put some hyphens in the id for readability?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the ID would be a breaking change for customers already using this query. Do you think improving the readability of the ID is worth doing?

Copy link
Contributor

@michaelnebel michaelnebel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -0,0 +1,24 @@
## Overview

According the Java documentation on `ScheduledThreadPoolExecutor`, it is not a good idea to set `corePoolSize` to zero, since doing so indicates the executor to keep 0 threads in its pool and the executor will serve no purpose.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
According the Java documentation on `ScheduledThreadPoolExecutor`, it is not a good idea to set `corePoolSize` to zero, since doing so indicates the executor to keep 0 threads in its pool and the executor will serve no purpose.
According to the Java documentation on `ScheduledThreadPoolExecutor`, it is not a good idea to set `corePoolSize` to zero, since doing so indicates the executor to keep 0 threads in its pool and the executor will serve no purpose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Java no-change-note-required This PR does not need a change note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants