Use binary class name to resolve per-class HTTP interface fallbacks - #1715
Use binary class name to resolve per-class HTTP interface fallbacks#1715HDPark95 wants to merge 1 commit into
Conversation
CircuitBreakerRequestValueProcessor stored the declaring class under its canonical name, while fallbacks are registered per service using Class#getName() (the binary name). For a nested @HttpExchange interface these two forms differ (Outer.Inner vs Outer$Inner), so the per-class fallback was never matched and the invocation fell through to the default fallback or NoFallbackAvailableException. Store the binary name so the declaring-class lookup key matches the registration key. Top-level interfaces are unaffected because their canonical and binary names are identical. Signed-off-by: HDPark95 <qkrgusen456@gmail.com>
|
I ran this locally against the PR head (JDK 17.0.15, The regression guard holds. With the one-line production change reverted and the rest of the branch untouched, With the change in place both classes are green (6/0 and 14/0). The reactive decorator needs no separate change: both decorators resolve through Two things I noticed while checking. Neither blocks the fix. 1. The existing fixtures still build the key with 2. Inherited A JDK proxy over |
What
CircuitBreakerRequestValueProcessorrecords the declaring class of the invoked@HttpExchangemethod undergetCanonicalName(), but per-class fallbacks are registered withClass#getName()(the binary name) inCircuitBreakerConfigurerUtils.addFallbackEntries.getFallbackthen resolves the fallback by looking up that recorded value.For a top-level interface both forms are identical, but for a nested
@HttpExchangeinterface they differ:com.example.Outer.Inner(canonical) vscom.example.Outer$Inner(binary). The lookup key never matches the registration key, so the per-class fallback is silently skipped and the invocation falls through to thedefaultfallback or, when none is registered, throwsNoFallbackAvailableException.Fix
Record the declaring class under
getName()so the declaring-class lookup key matches the registration key. Top-level interfaces are unaffected because their canonical and binary names are identical.This circuit-breaking-over-
@HttpExchangesupport is new in 5.0.0 and unreleased, so aligning the stored attribute carries no compatibility concern.Verification
shouldResolvePerClassFallbackForNestedServiceInterfacetoCircuitBreakerAdapterDecoratorTests, which drives the realCircuitBreakerRequestValueProcessorwith a nested service interface and asserts the per-class fallback resolves.NoFallbackAvailableException; with the fix the whole test class passes (Tests run: 6, Failures: 0, Errors: 0)../mvnw -pl spring-cloud-commons testis green, including spring-javaformat and checkstyle validation.