javaee / jersey

This is no longer the active Jersey repository. Please see the README.md
http://jersey.github.io
Other
2.86k stars 2.35k forks source link

Unable to register multiple instances of the same `Binder` class #3686

Open fabriziocucci opened 7 years ago

fabriziocucci commented 7 years ago

Description

While writing the test case for #3675, I've noticed that it doesn't seem to be possible to register two instances of the same Binder class (either Jersey binder or HK2 binder).

Technically, the main cause seems to be in ComponentBag#registerModel:

private boolean registerModel(final Class<?> componentClass,
        final int defaultPriority,
        final Map<Class<?>, Integer> contractMap,
        final Inflector<ContractProvider.Builder, ContractProvider> modelEnhancer) {

    return Errors.process(() -> {
        if (models.containsKey(componentClass)) { // <-- true for the second binder!
                Errors.error(LocalizationMessages.COMPONENT_TYPE_ALREADY_REGISTERED(componentClass), Severity.HINT);
            return false;
        }
        ...
        });
}

Is this by design?

Test

kinow commented 7 years ago

I'm facing an issue and thought it could be related to this one. But while debugging 2.26, I've found that the class was actually the implementation class, not the interface. I have a few implementations that use Feature. But the models.containsKey is correctly checking for the implementation value, not the interface name. Just my 0.02 cents.

fabriziocucci commented 7 years ago

But the models.containsKey is correctly checking for the implementation value, not the interface name.

@kinow that's exactly my point and it fails in the (corner) case where you register two instances of the same concrete class implementing the Binder interface (see example).

The only real (corner) case where I see this happening is if you have a concrete MyBinder class which accepts a generic command (e.g. Consumer<Binder>) performing some common bindings in the configure method before/after executing the instance-specific command.

I'm wondering whether returning true instead of false in the code snippet of the description wouldn't be enough to cover this...

kinow commented 7 years ago

Oh, sorry, thought you were referring to the interface.