Skip to content

fix(spring): host ExecutorService beans break A2AAutoConfiguration startup #96

Closed

Description

@Zhoujie628

Problem

dev.openan.workflow.engine.spring.A2AAutoConfiguration declares the A2A server executor with a bare @ConditionalOnMissingBean:

@Bean(destroyMethod = "shutdownNow")
@ConditionalOnMissingBean
public ExecutorService agentExecutorPool(A2AProperties properties) { ... }

With no attributes the condition matches by return type (ExecutorService). Host applications routinely define their own executor beans - dispatchers, ScheduledExecutorService-based SSE heartbeat schedulers, pub-sub workers (ScheduledExecutorService is a subtype, so it is a candidate too). Because user configuration is registered before auto-configuration, any single one of them suppresses agentExecutorPool.

requestHandler (parameter 5) and restHandler then inject ExecutorService by type, without a qualifier, so the application fails to start:

UnsatisfiedDependencyException: Error creating bean with name 'requestHandler'
... parameter 5 ... NoUniqueBeanDefinitionException: expected single matching bean
but found 3: spaceAiDispatcherExecutor,spaceSseHeartbeatScheduler,spaceSsePubSubExecutor

The parameter-name hint in that message is a red herring: the parameter is named pool and no bean of that name exists.

Expected

The starter's own executor should be created and used regardless of unrelated ExecutorService beans in the host, while a host can still override it explicitly.

Fix

  1. Match by bean name: @Bean(name = "agentExecutorPool", destroyMethod = "shutdownNow") plus @ConditionalOnMissingBean(name = "agentExecutorPool").
  2. Qualify both injection points: @Qualifier("agentExecutorPool") on the requestHandler and restHandler ExecutorService parameters.

Both halves are required: without (1) the pool is never created, without (2) the injection stays ambiguous.

Workaround before the fix

Declare a @Primary ExecutorService bean in the host with the same settings.

Activity

  1. Zhoujie628 commented on Oct 22, 2026

    @Zhoujie628
    ContributorAuthor

    Superseded by #98: same report filed from the account that authored the fix, PR is #99.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions