Skip to content

fix(spring): bind the agent executor pool by bean name, not by type - #97

Closed
Zhoujie628 wants to merge 1 commit into
project-openan:mainfrom
Zhoujie628:fix/a2a-agent-executor-pool-qualifier
Closed

Zhoujie628 wants to merge 1 commit into
project-openan:mainfrom
Zhoujie628:fix/a2a-agent-executor-pool-qualifier

Conversation

@Zhoujie628

Copy link
Copy Markdown
Contributor

Fixes #96

Summary

  • Match the A2A server executor by bean name: @Bean(name = "agentExecutorPool") + @ConditionalOnMissingBean(name = "agentExecutorPool")
  • Qualify both injection points with @Qualifier("agentExecutorPool") (requestHandler parameter 5 and restHandler)

Why

The bare @ConditionalOnMissingBean matched by return type (ExecutorService), so any host executor bean suppressed the pool; the handlers then injected ExecutorService by type and failed with NoUniqueBeanDefinitionException at parameter 5 of requestHandler.

Verification

  • mvn -pl spring-boot-starter test: 32 tests pass
  • New WebApplicationContextRunner regression test with two foreign ExecutorService/ScheduledExecutorService beans - fails before the fix with the reported exception, passes after
  • Host-override test: a host bean named agentExecutorPool replaces the auto-configured one
  • mvn -pl spring-boot-starter spotless:check passes

agentExecutorPool used a bare @ConditionalOnMissingBean, which matches by
return type (ExecutorService). Host applications routinely define their own
ExecutorService beans - dispatchers, ScheduledExecutorService-based SSE
heartbeat schedulers, pub-sub workers - and because user configuration
registers before auto-configuration, any one of them suppressed the A2A
pool. requestHandler and restHandler then injected ExecutorService by type
without a qualifier, found several candidates (none primary), and the
application failed to refresh with NoUniqueBeanDefinitionException at
"Parameter 5 of method requestHandler".

Match by bean name instead: the pool is always auto-configured unless the
host declares its own bean named agentExecutorPool, and both injection
points take @qualifier("agentExecutorPool"). Capacity keeps coming from
the a2at.server.executor-* properties.

Regression: a WebApplicationContextRunner with foreign ExecutorService and
ScheduledExecutorService beans pre-registered now starts and wires the
auto-configured pool (verified to reproduce the reported
NoUniqueBeanDefinitionException without the fix), plus a host-override
test where a same-named bean replaces the auto-configured one.

Signed-off-by: tangzhiqiang <tangzhiqiang@gdcattsoft.com>
@Zhoujie628
Zhoujie628 requested a review from a team as a code owner October 22, 2026 09:48
@Zhoujie628

Copy link
Copy Markdown
Contributor Author

Closing to resubmit this change from the contributor fork so that the pull request is opened by the commit author (tangzhiqiang). The code and the commit are unchanged; a new PR will reference issue #96.

@Zhoujie628 Zhoujie628 closed this Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(spring): host ExecutorService beans break A2AAutoConfiguration startup

3 participants