Commit Graph

4412 Commits

Author SHA1 Message Date
Sam Brannen cc31bf3c33 Accept zero for RetryPolicy.Builder.delay()
This aligns the programmatic RetryPolicy configuration option with the
delay support in @⁠Retryable.

See gh-35110
2025-07-01 17:40:15 +02:00
Sébastien Deleuze fb214bb74a Merge branch '6.2.x' 2025-07-01 11:02:54 +02:00
Phillip Webb 89b8b1a468 Prevent cache pollution by storing only the factories
Update `SpringFactoriesLoader` so that the cache stores only the
factories and not the complete loader.

Prior to this commit, if a cache entry was added with the thread
context classloader, the loader instance would be added and the
classloader stored. If the thread context classloader subsequently
changes, and a call is made to `forDefaultResourceLocation` with
`null` for the classloader, the cached entry would be used which
contains the older classloader.

Closes gh-34732
2025-07-01 11:01:48 +02:00
Sam Brannen 769ba9e23b Merge branch '6.2.x'
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
2025-06-29 17:42:35 +02:00
Sam Brannen 1ad05db877 Simplify dependency management for JUnit artifacts
Backport Bot / build (push) Waiting to run Details
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:ubuntu-latest name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:21], map[id:ubuntu-latest name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:ubuntu-latest name:Linux]) (push) Waiting to run Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
This commit simplifies our dependency management for JUnit artifacts by
making use of the junit-jupiter and junit-platform-suite aggregator
artifacts.

Closes gh-35127
2025-06-29 17:42:22 +02:00
Sam Brannen b211ac1f4a Resolve warning in CachingMetadataReaderFactoryTests 2025-06-29 16:28:09 +02:00
Sam Brannen ad278cd52e Fix ExponentialBackOffTests 2025-06-28 19:29:49 +02:00
Sam Brannen 4cdfd90882 Polish backoff and retry support
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
This revises commit 15dd320b95.

See gh-34529
See gh-35110
2025-06-28 19:14:45 +02:00
Juergen Hoeller 96f0399072 Reintroduce FixedBackOff(long) constructor
Effectively removing FixedBackOff(Duration) only.

See gh-35028
See gh-35110
2025-06-28 12:11:02 +02:00
Juergen Hoeller 15dd320b95 Consistent maxAttempts (long) and delay/maxDelay (Duration) declarations
Includes timeUnit attribute in @Retryable (aligned with @Scheduled).

See gh-34529
See gh-35110
2025-06-28 11:40:00 +02:00
Sam Brannen bcdf26d492 Redesign RetryPolicy to directly incorporate BackOff
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
After experimenting with our newly introduced core retry support
(RetryPolicy, RetryTemplate, etc.) and @⁠Retryable support, it
became apparent that there are overlapping concerns between the current
RetryPolicy and BackOff contracts.

- RetryPolicy and BackOff both have stateful executions: RetryExecution
  and BackOffExecution. However, only one stateful execution is
  necessary.

- FixedBackOff and ExponentialBackOff already incorporate "retry" logic
  in terms of max attempts, max elapsed time, etc. Thus, there is no
  need to duplicate such behavior in a RetryPolicy and its
  RetryExecution.

- RetryTemplate currently accepts both a RetryPolicy and a BackOff in
  order to instrument the retry algorithm. However, users would
  probably rather focus on configuring all "retry" logic via a single
  mechanism.

In light of the above, this commit directly incorporates BackOff
in RetryPolicy as follows.

- Remove the RetryExecution interface and move its shouldRetry() method
  to RetryPolicy, replacing the current RetryExecution start() method.

- Introduce a default getBackOff() method in the RetryPolicy interface.

- Introduce RetryPolicy.withDefaults() factory method.

- Completely overhaul the RetryPolicy.Builder to provide support for
  configuring a BackOff strategy.

- Remove BackOff configuration from RetryTemplate.

- Revise the method signatures of callbacks in RetryListener.

The collective result of these changes can be witnessed in the
reworked implementation of AbstractRetryInterceptor.

RetryPolicy retryPolicy = RetryPolicy.builder()
		.includes(spec.includes())
		.excludes(spec.excludes())
		.predicate(spec.predicate().forMethod(method))
		.maxAttempts(spec.maxAttempts())
		.delay(Duration.ofMillis(spec.delay()))
		.maxDelay(Duration.ofMillis(spec.maxDelay()))
		.jitter(Duration.ofMillis(spec.jitter()))
		.multiplier(spec.multiplier())
		.build();

RetryTemplate retryTemplate = new RetryTemplate(retryPolicy);

See gh-34716
See gh-34529
See gh-35058
Closes gh-35110
2025-06-27 17:28:10 +02:00
Sam Brannen 98b29b5e37 Consistently implement toString() in BackOff strategies
Closes gh-35120
2025-06-27 16:10:55 +02:00
Sam Brannen d97288a74e Improve Javadoc and tests for BackOff strategies 2025-06-27 16:04:32 +02:00
Stefano Cordio f7fef93842 Refine nullability of MethodInvoker#setArguments
Closes gh-35089
Signed-off-by: Stefano Cordio <stefano.cordio@gmail.com>
2025-06-26 15:04:49 +02:00
Juergen Hoeller 841d9fb73b Add public method to get bean order on DefaultListableBeanFactory
Closes gh-34712
2025-06-26 14:48:07 +02:00
Tran Ngoc Nhan 1a046f9cec Fix Nullable import in ClassFileAnnotationMetadata
Closes gh-35114

Signed-off-by: Tran Ngoc Nhan <ngocnhan.tran1996@gmail.com>
2025-06-25 20:43:09 +02:00
Brian Clozel 2fa25b50d9 Fix caching operations in CachingMetadataReaderFactory
gh-33616 refactored `CachingMetadataReaderFactory` and broke the
behavior as it bypassed the cache for `getMetadataReader(String
className)` operations.

This commit restores the original behavior.

Fixes gh-35112
2025-06-25 20:32:38 +02:00
Sam Brannen f3f05da39b Refer to Spring Retry project in Javadoc
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
2025-06-25 16:38:48 +02:00
Juergen Hoeller e828bbbb0a Invert order of suppressed exceptions (for common exception rendering)
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
See gh-35057
2025-06-24 22:22:45 +02:00
Sébastien Deleuze 839d3a7d44 Refine nullability of PropertyResolver.getProperty(key: String)
Closes gh-35104
2025-06-24 16:06:32 +02:00
Sébastien Deleuze 294406dae9 Remove `@Suppress("EXTENSION_SHADOWED_BY_MEMBER")`
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
Fixed in Kotlin 2.2.0 and IntelliJ IDEA IDEA 2024.2 EAP, see
https://youtrack.jetbrains.com/issue/KT-75169 related issue.

See gh-34453
2025-06-24 11:40:23 +02:00
Juergen Hoeller 6927e39e6b Merge branch '6.2.x' 2025-06-18 12:23:07 +02:00
Juergen Hoeller aa525cc3cd Delegate to ReflectionUtils.accessibleConstructor
Backport Bot / build (push) Has been cancelled Details
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Has been cancelled Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:ubuntu-latest name:Linux]) (push) Has been cancelled Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:21], map[id:ubuntu-latest name:Linux]) (push) Has been cancelled Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:ubuntu-latest name:Linux]) (push) Has been cancelled Details
Deploy Docs / Dispatch docs deployment (push) Has been cancelled Details
Build and Deploy Snapshot / Verify (push) Has been cancelled Details
2025-06-18 12:20:30 +02:00
Sam Brannen c5fd57d92b Polish @⁠Retryable Javadoc and internals 2025-06-17 17:07:15 +02:00
Sébastien Deleuze f601bbb2ac Allow usage of `@CheckReturnValue` on types and ctors
Closes gh-34910
2025-06-17 16:53:12 +02:00
Sam Brannen 74ee1b991a Apply consistent copyright headers in Kotlin source code
See gh-35070
2025-06-17 16:24:15 +02:00
Spring Builds 16edf9867a Update copyright headers in source files
This commit updates Java, Kotlin, and Groovy source files to use the
"<year>-present" pattern in copyright headers.

Closes gh-35070
2025-06-17 16:23:50 +02:00
Sam Brannen 103a7e58bb Apply consistent copyright headers in Kotlin source code
See gh-35070
2025-06-17 15:54:58 +02:00
Spring Builds aee29b7f30 Update copyright headers in source files
This commit updates Java, Kotlin, and Groovy source files to use the
"<year>-present" pattern in copyright headers.

Closes gh-35070
2025-06-17 15:54:58 +02:00
Juergen Hoeller f69df9b767 Introduce retry interceptor and annotation-based retry support
Based on RetryTemplate with ExponentialBackOff.
Includes optional jitter support in ExponentialBackOff.
Supports reactive methods through Reactor's RetryBackoffSpec.

Closes gh-34529
2025-06-17 12:49:29 +02:00
Sam Brannen cc7dc47c4c Simplify suppressed exception assertions
See https://github.com/assertj/assertj/issues/3858
2025-06-16 16:32:24 +02:00
Sam Brannen 6bbfd56dce Remove duplication in RetryTemplateTests 2025-06-16 14:32:33 +02:00
Sam Brannen f41a568b1d Improve Javadoc for RetryPolicy.Builder 2025-06-16 14:31:50 +02:00
Sam Brannen 09372b72ae Add retryWithExceptionExcludes() test 2025-06-16 13:33:10 +02:00
Sam Brannen 97522cfa36 Introduce Builder API and factory methods for RetryPolicy
Prior to this commit, we had three concrete RetryPolicy implementations.

- MaxRetryAttemptsPolicy
- MaxDurationAttemptsPolicy
- PredicateRetryPolicy

However, there was no way to combine the behavior of those policies.
Furthermore, the PredicateRetryPolicy was practically useless as a
standalone policy, since it did not have a way to end an infinite loop
for a Retryable that continually throws an exception which matches the
predicate.

This commit therefore replaces the current built-in RetryPolicy
implementations with a fluent Builder API and dedicated factory methods
for common use cases.

In addition, this commit also introduces built-in support for
specifying include/exclude lists.

Examples:

new MaxRetryAttemptsPolicy(5) -->

    RetryPolicy.withMaxAttempts(5)

new MaxDurationAttemptsPolicy(Duration.ofSeconds(5)) -->

    RetryPolicy.withMaxDuration(Duration.ofSeconds(5))

new PredicateRetryPolicy(IOException.class::isInstance) -->

    RetryPolicy.builder()
        .maxAttempts(3)
        .predicate(IOException.class::isInstance)
        .build();

The following example demonstrates all supported features of the builder.

RetryPolicy.builder()
    .maxAttempts(5)
    .maxDuration(Duration.ofMillis(100))
    .includes(IOException.class)
    .excludes(FileNotFoundException.class)
    .predicate(t -> t.getMessage().contains("Unexpected failure"))
    .build();

Closes gh-35058
2025-06-16 13:15:38 +02:00
Juergen Hoeller 945f3fb5ac Revise RetryTemplate for alignment with Reactor
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
Exposes last exception as cause in RetryException.
Applies first back-off after the initial exception.
Breaks out of retry loop on BackOffExecution.STOP.
Expects null result in Retryable and RetryListener.

Closes gh-35057
2025-06-16 12:05:25 +02:00
Brian Clozel af7758cbc7 Configure CheckStyle rule for empty catch blocks
This commit configures a new CheckStyle rule that fails for empty
"catch" blocks, unless the exception is named "ignored" or "expected".

This also fixes the remaining instances missed by the previous commit.

Closes gh-35047
2025-06-15 16:11:48 +02:00
Vincent Potucek 0d4dfb6c1f Rename exception variables in empty catch blocks
The Spring codebase sometimes ignores exceptions in catch blocks on
purpose. This is often called out by an inline comment.
We should make this more obvious by renaming the exception argument in
the catch block to declare whether the exception is "ignored" or
"expected".

See gh-35047

Signed-off-by: Vincent Potucek <vpotucek@me.com>
[brian.clozel@broadcom.com: rework commit message]
Signed-off-by: Brian Clozel <brian.clozel@broadcom.com>
2025-06-15 16:11:42 +02:00
Sam Brannen cd3ac44fb0 Add test for CompositeRetryListener.addListener() 2025-06-15 15:23:43 +02:00
Sam Brannen 8dc9621ad7 Merge branch '6.2.x'
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
2025-06-14 15:35:09 +02:00
Sam Brannen 9f1aef16f9 Fix Javadoc for FixedBackOff
Backport Bot / build (push) Waiting to run Details
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:ubuntu-latest name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:21], map[id:ubuntu-latest name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:ubuntu-latest name:Linux]) (push) Waiting to run Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
2025-06-14 15:33:04 +02:00
Brian Clozel cd80ca0fe0 Merge branch '6.2.x' 2025-06-13 09:57:18 +02:00
Johnny Lim 722333f0f1 Polish DataBufferInputStream.skip()
Backport Bot / build (push) Waiting to run Details
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:ubuntu-latest name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:21], map[id:ubuntu-latest name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:ubuntu-latest name:Linux]) (push) Waiting to run Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
See gh-34799
Closes gh-35030

Signed-off-by: Johnny Lim <izeye@naver.com>
2025-06-13 09:57:02 +02:00
Sam Brannen 082eb607ec Overhaul tests for RetryTemplate
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
2025-06-12 17:34:54 +02:00
Sam Brannen ff167aafa2 Make built-in RetryPolicy implementations final
Closes gh-35040
2025-06-12 17:34:54 +02:00
Sam Brannen bfd3dc2676 Implement toString() in RetryPolicy and RetryExecution implementations
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
Closes gh-35029
2025-06-11 19:17:03 +02:00
Sam Brannen bc967842f6 Rename and polish ComposedRetryListenerTests 2025-06-11 19:04:48 +02:00
Sam Brannen b6680422db Change signature of RetryOperations.execute() regarding nullability
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details
Due to lacking support in NullAway for the current arrangement, we are
(perhaps temporarily) changing the signature of the execute() method in
RetryOperations (and thus also in RetryTemplate)...

from: <R extends @Nullable Object> R execute(Retryable<R> retryable);

to:   <R> @Nullable R execute(Retryable<? extends @Nullable R> retryable);

Once https://github.com/uber/NullAway/issues/1075 has been resolved, we
will consider switching back to the original signature.

See gh-34716
2025-06-11 17:43:29 +02:00
Sam Brannen 8f3ca49bc4 Rename Retryable.run() to Retryable.execute()
See gh-34716
2025-06-11 13:50:16 +02:00
Sam Brannen d74b863ae7 Polish Javadoc for core retry functionality
See gh-34716
2025-06-11 13:49:00 +02:00