Skip to content

Synthetic bean priorities interfere with other beans sharing the same bean class #3541

Closed

Description

@manovotn

Registering a synthetic bean can change which bean is selected for an unrelated type when they share the same beanClass.

For example, an extension registers these synthetic alternatives:

interface Service {
    String value();
}

interface OtherService {
    String value();
}

class Shared {}
class Distinct {}

void addBeans(@Observes AfterBeanDiscovery event) {
    event.<Service>addBean()
            .beanClass(Shared.class).types(Service.class)
            .alternative(true).priority(10)
            .createWith(ctx -> () -> "A");

    event.<Service>addBean()
            .beanClass(Distinct.class).types(Service.class)
            .alternative(true).priority(15)
            .createWith(ctx -> () -> "B");

    event.<OtherService>addBean()
            .beanClass(Shared.class).types(OtherService.class)
            .alternative(true).priority(20)
            .createWith(ctx -> () -> "C");
}

Looking up Service should select B, which has priority 15. Instead, Weld selects A: it uses C’s priority of 20 because A and C share their bean class. Removing C restores the expected result.

Two competing synthetic beans sharing a bean class can also resolve ambiguously despite having different priorities.

A bean class is not a unique identifier for a synthetic bean. Each bean’s priority should be handled independently. This affects alternatives and reserves, registered either through a configurator or as custom beans implementing Prioritized.

The fix should be applied to Weld 6 and 7.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions