-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Spring Integration 6.x to 7.0 Migration Guide
- New
DistributedLock
API - Removal of deprecated classes from
spring-integration-hazelcast
- Deprecated JUnit 4 Based Components
- Jackson 3 support
TcpListener.onMessage()
contract- Migration to Spring Core Retry
Spring Integration 7.0 introduces a DistributedLock
abstraction with a Time-To-Live (TTL) API (for now), allowing lock objects in the target persistent store to be marked as expired if the instances holding the lock become unresponsive.
This enables other instances to acquire the lock.
With this new abstraction, the LockRegistry
interface—along with its extensions and implementations—now accepts a generic argument to specify the Lock
implementation provided by that particular LockRegistry
.
For example, the DefaultLockRegistry
is now defined as:public final class DefaultLockRegistry implements LockRegistry<Lock>
.
Similarly, ZookeeperLockRegistry
is now:
public class ZookeeperLockRegistry implements ExpirableLockRegistry<Lock>
.
However, JdbcLockRegistry
and RedisLockRegistry
are now defined as:
implements ExpirableLockRegistry<DistributedLock>, RenewableLockRegistry<DistributedLock>
Therefore, the obtain()
method in these registries now returns a DistributedLock
instance, which includes the newly introduced lock(Duration ttl)
and tryLock(Duration waitTime, Duration ttl)
methods.
The RedisLockRegistry
has supported TTL from the beginning via its default expireAfter property. However, with the addition of lock(Duration ttl)
, TTL can now be specified per lock usage.
The JdbcLockRegistry
, being RDBMS-based, required changes to the SQL schema. A new EXPIRED_AFTER
column has been added to the INT_LOCK
table.
As a result, for existing databases, the following DDL statement must be executed to properly migrate to Spring Integration 7.0:
ALTER TABLE INT_LOCK ADD EXPIRED_AFTER TIMESTAMP NOT NULL;
Due to the removal of the CP Subsystem from the open-source edition of Hazelcast, the related Spring Integration classes were deprecated in version 6.5. These classes are now fully removed as outdated APIs. For more information, see the Spring Integration 6.4 to 6.5 Migration Guide.
The classes in spring-integration-test-support
module to support JUnit 4 infrastructure, such as Log4j2LevelAdjuster
, AbstractRequestResponseScenarioTests
, LongRunningIntegrationTest
and SingleRequestResponseScenarioTests
, are now deprecated in favor of respective replacements for JUnit Jupiter.
Their JavaDocs have references to replacements.
Spring Integration now provides classes and injection points for Jackson 3 support.
Jackson 2 based classes have been deprecated for removal.
See their JavaDocs for migration path.
Some defaults in Jackson 3 are not compatible with Jackson 2.
So, if you find your application not working, consider injecting custom Jackson 3 ObjectMapper
with respective feature set/unset.
For example, so far we have noticed these discrepancies:
-
WRITE_DATES_AS_TIMESTAMPS(false)
// was true in 2.x -
WRITE_DURATIONS_AS_TIMESTAMPS(false)
// was true in 2.x -
ONE_BASED_MONTHS(true)
// was false in 2.x
The TcpListener.onMessage()
has been boolean
return contract for many years without any use in the framework.
Now the return type has been changed to void
to simplify contract and all the logic in the framework where this method is involved.
The spring-retry
dependency, together with all of its API usage have been replaced by retry API in https://docs.spring.io/spring-framework/reference/7.0/core/resilience.html#resilience-programmatic-retry[Spring Framework Core] module.
This breaking change is the natural evolution of the whole Spring portfolio.
The Spring Retry project is in maintenance mode from now on without any further major/minor version plans.
Everyone is encouraged to migrate for the retry API in Spring Framework.
In general, the following references have been migrated (and therefore, must be fixed in the target projects which uses Spring Integration):
-
org.springframework.retry.support.RetryTemplate
->org.springframework.core.retry.RetryTemplate
; -
org.springframework.retry.RetryPolicy
->org.springframework.core.retry.RetryPolicy
; -
org.springframework.retry.RecoveryCallback
->org.springframework.integration.core.RecoveryCallback
. There is noRecoveryCallback
abstraction in the Spring Framework, since regulartry..catch
on theRetryException
is enough. For Spring Integration, theRecoveryCallback
makes sense as a dead-letter publisher to an error channel; -
org.springframework.retry.backoff.BackOffPolicy
->org.springframework.util.backoff.BackOff
. However, it is not exposed directly as aRetryTemplate
options: rather as an internal API backed by the configuration viaRetryPolicy.Builder
; - The
RetryContext
in AMPQ, JMS and Apache Kafka channel adapters is replaced with an internalAttributeAccessor
implementation.
Therefore, the following project classes have suffered breaking changes:
AmqpBaseInboundChannelAdapterSpec
AmqpBaseInboundGatewaySpec
AmqpInboundChannelAdapter
AmqpInboundGateway
PostgresSubscribableChannel
ChannelPublishingJmsMessageListener
JmsInboundGatewaySpec
JmsMessageDrivenChannelAdapterSpec
KafkaInboundGatewaySpec
KafkaMessageDrivenChannelAdapterSpec
KafkaInboundEndpoint
KafkaInboundGateway
KafkaMessageDrivenChannelAdapter
The RetryTemplate
and RecoveryCallback
configuration options of these classes now requires org.springframework.core.retry.RetryTemplate
and org.springframework.integration.core.RecoveryCallback
, respectively.
The ThreadLocal<@Nullable AttributeAccessor> ATTRIBUTES_HOLDER
is still there, however it comes with limited number of attributes (mostly related to the endpoint logic) since new RetryTemplate
implementation does not expose a RetryContext
abstraction.
The RequestHandlerRetryAdvice
was rebuilt to avoid external API as much as possible.
For the stateless retry logic, there is just enough to provide a org.springframework.core.retry.RetryPolicy
.
The stateful retry logic is activated by the Function<Message<?>, Object> stateKeyFunction
.
The RetryStateGenerator
abstraction and its SpelExpressionRetryStateGenerator
implementation have been removed due to dependency on the spring-retry
API.
So, the RequestHandlerRetryAdvice
in new incarnation does not expect a RetryTemplate
and RetryStateGenerator
.
Instead, the org.springframework.core.retry.RetryPolicy
can be set: buy default, 3 retry attempts with no delay in between.
This RetryPolicy
is used internally by the org.springframework.core.retry.RetryTemplate
for stateless logic, and directly with its BackOff
API for stateful.
The stateKeyFunction
together with a Predicate<Message<?>> newMessagePredicate
replaces RetryStateGenerator
.
In addition, the stateCacheSize
(default 100
) can be modified to control the cache size for the stateful state objects.
Another new option is an org.springframework.core.retry.RetryListener
injection.