Skip to content

Conversation

@minizhiren
Copy link

Root cause: binder registration order and reuse were nondeterministic, causing SupplierContractsTest to be flaky.

Fix: register bindings deterministically and reuse them safely (IdentityHashMap for insertion-order semantics; cleanup of binder cache).

Test: SupplierContractsTest now passes reliably across runs/seeds.

@jbescos
Copy link
Member

jbescos commented Oct 22, 2025

It is difficult to check this because text has been reformatted. Could you restore the previous format, please?.

@minizhiren
Copy link
Author

Sure! My pleasure!

@minizhiren minizhiren force-pushed the fix-suppliercontracts-flaky branch from 6769255 to 54d8485 Compare December 17, 2025 21:33
Comment on lines +326 to +335
// ---------- ClassBinding ----------
if (ClassBinding.class.isAssignableFrom(binding.getClass())) {
final ClassBinding<?> cb = (ClassBinding<?>) binding;

// Keep existing "update" path for CLIENT
if (RuntimeType.CLIENT == runtimeType) {
for (Type contract : ((ClassBinding<?>) binding).getContracts()) {
final List<BindingBeanPair> preregistered = classBindings.get(contract);
if (preregistered != null && preregistered.size() == 1) {
BeanHelper.updateBean(
(ClassBinding<?>) binding, preregistered.get(0), injectionResolvers, beanManager);
for (Type contract : cb.getContracts()) {
final java.util.List<BindingBeanPair> pre = classBindings.get(contract);
if (pre != null && pre.size() == 1) {
BeanHelper.updateBean(cb, pre.get(0), injectionResolvers, beanManager);
Copy link
Member

Choose a reason for hiding this comment

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

This section of here is is just renaming, right?. It does not modify any functionality.

I suggest to not do this refactoring because of two reasons:

  1. It is more difficult to focus in the real change of the PR.
  2. It adds noise when you want track changes of a file.

Comment on lines +354 to +365

// ---------- SupplierClassBinding ----------
} else if (SupplierClassBinding.class.isAssignableFrom(binding.getClass())) {
final SupplierClassBinding<?> scb = (SupplierClassBinding<?>) binding;

// Keep existing "update" path for CLIENT
if (RuntimeType.CLIENT == runtimeType) {
for (Type contract : ((SupplierClassBinding<?>) binding).getContracts()) {
final List<BindingBeanPair> preregistered = supplierClassBindings.get(contract);
if (preregistered != null && preregistered.size() == 1) {
for (Type contract : scb.getContracts()) {
final java.util.List<BindingBeanPair> pre = supplierClassBindings.get(contract);
if (pre != null && pre.size() == 1) {
BeanHelper.updateSupplierBean(
(SupplierClassBinding<?>) binding, preregistered.get(0), injectionResolvers, beanManager);
scb, pre.get(0), injectionResolvers, beanManager);
Copy link
Member

Choose a reason for hiding this comment

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

This is also refactoring, that we can avoid in this PR.

Comment on lines +385 to +402
// ---------- Instance bindings (unchanged) ----------
} else if (InitializableInstanceBinding.class.isAssignableFrom(binding.getClass())) {
if (RuntimeType.SERVER == runtimeType
|| !matchInitializableInstanceBinding((InitializableInstanceBinding<?>) binding)) {
initializableInstanceBindings.add((InitializableInstanceBinding<?>) binding);
BeanHelper.registerBean(
runtimeType, (InitializableInstanceBinding<?>) binding, abd, injectionResolvers, beanManager);
runtimeType, (InitializableInstanceBinding<?>) binding,
abd, injectionResolvers, beanManager);
}
} else if (InitializableSupplierInstanceBinding.class.isInstance(binding)) {
if (RuntimeType.SERVER == runtimeType
|| !matchInitializableSupplierInstanceBinding((InitializableSupplierInstanceBinding) binding)) {
initializableSupplierInstanceBindings.add((InitializableSupplierInstanceBinding) binding);
BeanHelper.registerSupplier(runtimeType, (InitializableSupplierInstanceBinding<?>) binding, abd, beanManager);
|| !matchInitializableSupplierInstanceBinding(
(InitializableSupplierInstanceBinding) binding)) {
initializableSupplierInstanceBindings.add(
(InitializableSupplierInstanceBinding) binding);
BeanHelper.registerSupplier(
runtimeType, (InitializableSupplierInstanceBinding<?>) binding,
abd, beanManager);
Copy link
Member

Choose a reason for hiding this comment

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

This is refactoring too

@jansupol
Copy link
Contributor

@minizhiren I am not quite sure what the purpose of this PR is. Do you use the module with 2.x Jersey? Or is the purpose to just to fix the test? I am just curious about the usage of this module by the community.

This module is meant to be used mainly in EE 12, and there was a significant development in the latest (4.0/4.0.JPMS) branch.

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.

3 participants