From 09a90e9cdd19c32e6db94fe4fb510cd0dd8efb8f Mon Sep 17 00:00:00 2001
From: Stefano Cordio
Date: Mon, 9 Jun 2025 15:41:42 +0200
Subject: [PATCH 1/6] Remove ErrorProne exclusions
Signed-off-by: Stefano Cordio
---
pom.xml | 39 ---------------------------------------
1 file changed, 39 deletions(-)
diff --git a/pom.xml b/pom.xml
index 667b992278..43f607e758 100644
--- a/pom.xml
+++ b/pom.xml
@@ -187,45 +187,6 @@
--should-stop=ifError=FLOW
-Xplugin:ErrorProne
- -Xep:AlmostJavadoc:OFF
- -Xep:ByteBufferBackingArray:OFF
- -Xep:ClassCanBeStatic:OFF
- -Xep:CollectionUndefinedEquality:OFF
- -Xep:DefaultCharset:OFF
- -Xep:DirectInvocationOnMock:OFF
- -Xep:DoNotCallSuggester:OFF
- -Xep:EmptyCatch:OFF
- -Xep:EqualsGetClass:OFF
- -Xep:Finally:OFF
- -Xep:FutureReturnValueIgnored:OFF
- -Xep:HidingField:OFF
- -Xep:ImmutableEnumChecker:OFF
- -Xep:InlineMeSuggester:OFF
- -Xep:InputStreamSlowMultibyteRead:OFF
- -Xep:JavaTimeDefaultTimeZone:OFF
- -Xep:JavaUtilDate:OFF
- -Xep:JdkObsolete:OFF
- -Xep:MissingSummary:OFF
- -Xep:MixedMutabilityReturnType:OFF
- -Xep:MutablePublicArray:OFF
- -Xep:NonAtomicVolatileUpdate:OFF
- -Xep:RedundantControlFlow:OFF
- -Xep:ReferenceEquality:OFF
- -Xep:StaticAssignmentInConstructor:OFF
- -Xep:StaticAssignmentOfThrowable:OFF
- -Xep:StaticMockMember:OFF
- -Xep:StreamResourceLeak:OFF
- -Xep:StringCaseLocaleUsage:OFF
- -Xep:StringSplitter:OFF
- -Xep:SynchronizeOnNonFinalField:OFF
- -Xep:ThreadLocalUsage:OFF
- -Xep:ThreadPriorityCheck:OFF
- -Xep:TypeParameterUnusedInFormals:OFF
- -Xep:UndefinedEquals:OFF
- -Xep:UnnecessaryStringBuilder:OFF
- -Xep:UnusedMethod:OFF
- -Xep:UnusedVariable:OFF
- -Xep:WaitNotInLoop:OFF
From 48df704e8816577c64635d51092330b0c09d3486 Mon Sep 17 00:00:00 2001
From: Stefano Cordio
Date: Mon, 9 Jun 2025 15:54:20 +0200
Subject: [PATCH 2/6] Add NullAway
Signed-off-by: Stefano Cordio
---
pom.xml | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/pom.xml b/pom.xml
index 43f607e758..4c099cc777 100644
--- a/pom.xml
+++ b/pom.xml
@@ -156,6 +156,7 @@
3.4.20.0.472.38.0
+ 0.12.7
@@ -187,6 +188,9 @@
--should-stop=ifError=FLOW
-Xplugin:ErrorProne
+
+ -Xep:NullAway:ERROR
+ -XepOpt:NullAway:OnlyNullMarked
@@ -195,6 +199,11 @@
error_prone_core${error-prone.version}
+
+ com.uber.nullaway
+ nullaway
+ ${nullaway.version}
+
From 984da17ca25b994b63328ed0dc43938bc502285b Mon Sep 17 00:00:00 2001
From: Stefano Cordio
Date: Mon, 9 Jun 2025 16:07:33 +0200
Subject: [PATCH 3/6] Execute OpenRewrite recipes
This executed:
```
mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-migrate-java:RELEASE -Drewrite.activeRecipes=org.openrewrite.java.jspecify.MigrateFromSpringFrameworkAnnotations,org.openrewrite.staticanalysis.AnnotateNullableMethods,org.openrewrite.staticanalysis.NullableOnMethodReturnType -Drewrite.exportDatatables=true
```
Signed-off-by: Stefano Cordio
---
.../batch/core/SpringBatchVersion.java | 5 +-
.../batch/core/configuration/JobLocator.java | 3 +-
.../support/DefaultJobLoader.java | 2 +-
.../configuration/support/GroupAwareJob.java | 6 +-
.../configuration/support/MapJobRegistry.java | 3 +-
.../support/MapStepRegistry.java | 4 +-
.../xml/ExceptionElementParser.java | 4 +-
.../core/configuration/xml/JobParser.java | 4 +-
.../DefaultJobParametersConverter.java | 5 +-
.../converter/JobParametersConverter.java | 4 ++
.../batch/core/job/AbstractJob.java | 5 +-
.../springframework/batch/core/job/Job.java | 6 +-
.../batch/core/job/JobExecution.java | 14 ++--
.../batch/core/job/SimpleJob.java | 4 +-
.../batch/core/job/flow/FlowExecutor.java | 3 +-
.../batch/core/job/flow/FlowJob.java | 4 +-
.../core/job/flow/JobExecutionDecider.java | 3 +-
.../batch/core/job/flow/JobFlowExecutor.java | 6 +-
.../core/job/flow/support/SimpleFlow.java | 3 +-
.../job/flow/support/StateTransition.java | 3 +-
.../job/flow/support/state/SplitState.java | 3 +-
.../CompositeJobParametersValidator.java | 6 +-
.../DefaultJobParametersValidator.java | 2 +-
.../core/job/parameters/JobParameter.java | 3 +-
.../core/job/parameters/JobParameters.java | 48 +++++--------
.../job/parameters/JobParametersBuilder.java | 3 +-
.../parameters/JobParametersIncrementer.java | 2 +-
.../parameters/JobParametersValidator.java | 2 +-
.../batch/core/launch/JobOperator.java | 6 +-
...FieldMaxValueJobParametersIncrementer.java | 3 +-
.../core/launch/support/RunIdIncrementer.java | 3 +-
.../launch/support/SimpleJobOperator.java | 5 +-
.../CompositeItemProcessListener.java | 3 +-
.../CompositeStepExecutionListener.java | 6 +-
.../ExecutionContextPromotionListener.java | 6 +-
.../core/listener/ItemProcessListener.java | 3 +-
.../core/listener/JobListenerMetaData.java | 6 +-
.../MethodInvokerMethodInterceptor.java | 4 +-
.../listener/MulticasterBatchListener.java | 6 +-
.../core/listener/StepExecutionListener.java | 6 +-
.../core/listener/StepListenerMetaData.java | 6 +-
.../core/observability/BatchMetrics.java | 7 +-
.../core/repository/dao/JobExecutionDao.java | 4 ++
.../core/repository/dao/JobInstanceDao.java | 6 +-
.../core/repository/dao/StepExecutionDao.java | 6 +-
.../dao/jdbc/JdbcExecutionContextDao.java | 3 +-
.../dao/jdbc/JdbcJobExecutionDao.java | 10 ++-
.../dao/jdbc/JdbcJobInstanceDao.java | 15 ++--
.../dao/jdbc/JdbcStepExecutionDao.java | 7 +-
.../dao/mongodb/MongoJobExecutionDao.java | 6 +-
.../dao/mongodb/MongoJobInstanceDao.java | 8 ++-
.../dao/mongodb/MongoStepExecutionDao.java | 6 +-
.../core/repository/explore/JobExplorer.java | 27 +++----
.../support/JobExplorerFactoryBean.java | 3 +-
.../explore/support/SimpleJobExplorer.java | 27 +++----
.../support/JdbcJobRepositoryFactoryBean.java | 3 +-
.../support/JobRepositoryFactoryBean.java | 3 +-
.../batch/core/scope/context/JobContext.java | 6 +-
.../context/JobSynchronizationManager.java | 6 +-
.../batch/core/scope/context/StepContext.java | 6 +-
.../context/StepSynchronizationManager.java | 6 +-
.../SynchronizationManagerSupport.java | 8 +--
.../NoWorkFoundStepExecutionListener.java | 6 +-
.../batch/core/step/StepExecution.java | 14 ++--
.../core/step/item/ChunkOrientedTasklet.java | 6 +-
.../core/step/item/SimpleChunkProcessor.java | 2 +-
.../core/step/item/SimpleChunkProvider.java | 9 ++-
.../job/DefaultJobParametersExtractor.java | 3 +-
.../step/tasklet/CallableTaskletAdapter.java | 6 +-
...nfigurableSystemProcessExitCodeMapper.java | 4 +-
.../tasklet/MethodInvokingTaskletAdapter.java | 6 +-
.../step/tasklet/SystemCommandTasklet.java | 5 +-
.../batch/core/step/tasklet/Tasklet.java | 3 +-
.../JobBuilderConfigurationTests.java | 11 +--
.../JobLoaderConfigurationTests.java | 13 ++--
.../JobScopeConfigurationTests.java | 6 +-
.../StepScopeConfigurationTests.java | 6 +-
.../support/DefaultJobLoaderTests.java | 7 +-
.../xml/DecisionJobParserTests.java | 2 +-
.../xml/DefaultUnknownJobParserTests.java | 5 +-
.../xml/DummyCompletionPolicy.java | 4 +-
.../xml/DummyItemHandlerAdapter.java | 6 +-
.../configuration/xml/DummyItemProcessor.java | 6 +-
.../configuration/xml/DummyItemReader.java | 6 +-
.../configuration/xml/DummyJobRepository.java | 16 ++---
.../xml/DummyPlatformTransactionManager.java | 4 +-
.../core/configuration/xml/DummyTasklet.java | 6 +-
.../configuration/xml/FailingTasklet.java | 6 +-
.../xml/FlowStepParserTests.java | 2 +-
.../xml/InterruptibleTasklet.java | 6 +-
.../configuration/xml/NameStoringTasklet.java | 6 +-
.../NextAttributeUnknownJobParserTests.java | 5 +-
.../core/configuration/xml/NoopTasklet.java | 6 +-
.../xml/PartitionStepWithFlowParserTests.java | 2 +-
.../core/configuration/xml/StepNameTests.java | 5 +-
.../configuration/xml/StopJobParserTests.java | 2 +-
.../xml/TestCustomStatusListener.java | 6 +-
.../configuration/xml/TestIncrementer.java | 5 +-
.../core/configuration/xml/TestListener.java | 6 +-
.../core/configuration/xml/TestProcessor.java | 6 +-
.../core/configuration/xml/TestReader.java | 6 +-
.../core/configuration/xml/TestTasklet.java | 6 +-
.../JobParametersConverterSupport.java | 3 +-
.../core/job/ExtendedAbstractJobTests.java | 4 +-
.../core/job/builder/FlowJobBuilderTests.java | 2 +-
.../flow/support/JobFlowExecutorSupport.java | 8 +--
.../support/CommandLineJobRunnerTests.java | 22 +++---
.../support/TaskExecutorJobOperatorTests.java | 10 +--
.../support/TestJobParametersIncrementer.java | 3 +-
.../CompositeStepExecutionListenerTests.java | 14 ++--
.../core/listener/ItemListenerErrorTests.java | 8 +--
.../MulticasterBatchListenerTests.java | 13 ++--
.../StepListenerFactoryBeanTests.java | 8 +--
.../StepListenerMethodInterceptorTests.java | 9 +--
.../core/partition/ExampleItemReader.java | 6 +-
.../dao/OptimisticLockingFailureTests.java | 6 +-
.../core/repository/dao/TablePrefixTests.java | 6 +-
.../JobRepositoryFactoryBeanTests.java | 4 +-
.../batch/core/scope/TestJob.java | 8 +--
.../batch/core/step/JobRepositorySupport.java | 14 ++--
.../batch/core/step/NonAbstractStepTests.java | 5 +-
.../core/step/RestartInPriorStepTests.java | 6 +-
.../batch/core/step/RestartLoopTests.java | 6 +-
.../builder/RegisterMultiListenerTests.java | 8 +--
.../core/step/builder/StepBuilderTests.java | 5 +-
.../core/step/item/ChunkMonitorTests.java | 14 ++--
.../item/ExceptionThrowingTaskletStub.java | 6 +-
.../FaultTolerantChunkProcessorTests.java | 30 ++++----
...aultTolerantStepFactoryBeanRetryTests.java | 45 ++++++------
.../FaultTolerantStepFactoryBeanTests.java | 14 ++--
.../step/item/SimpleChunkProcessorTests.java | 6 +-
.../step/item/SimpleStepFactoryBeanTests.java | 5 +-
.../core/step/item/SkipProcessorStub.java | 6 +-
.../batch/core/step/item/SkipReaderStub.java | 6 +-
.../step/item/TaskletStepExceptionTests.java | 72 +++++++++----------
.../step/skip/ReprocessExceptionTests.java | 5 +-
.../core/step/tasklet/TaskletStepTests.java | 53 +++++++-------
.../ConcurrentTransactionTests.java | 20 +++---
.../football/internal/GameFieldSetMapper.java | 4 +-
.../internal/PlayerFieldSetMapper.java | 4 +-
.../batch/core/test/ldif/MyMapper.java | 6 +-
.../MappingLdifReaderBuilderTests.java | 5 +-
.../config/DummyNamespaceHandler.java | 5 +-
...lerantStepFactoryBeanIntegrationTests.java | 5 +-
...epFactoryBeanRollbackIntegrationTests.java | 5 +-
.../FaultTolerantStepIntegrationTests.java | 5 +-
.../test/timeout/SleepingItemProcessor.java | 6 +-
.../core/test/timeout/SleepingTasklet.java | 6 +-
.../batch/item/ExecutionContext.java | 14 ++--
.../batch/item/ItemProcessor.java | 4 +-
.../batch/item/ItemReader.java | 2 +-
.../batch/item/ItemWriter.java | 2 +-
.../batch/item/PeekableItemReader.java | 2 +-
.../batch/item/SkipWrapper.java | 5 +-
.../item/adapter/ItemProcessorAdapter.java | 6 +-
.../batch/item/adapter/ItemReaderAdapter.java | 6 +-
.../batch/item/amqp/AmqpItemReader.java | 6 +-
.../batch/item/avro/AvroItemReader.java | 5 +-
.../data/AbstractPaginatedDataItemReader.java | 6 +-
.../batch/item/data/MongoItemWriter.java | 5 +-
.../batch/item/data/RepositoryItemReader.java | 5 +-
.../builder/RepositoryItemWriterBuilder.java | 4 +-
.../database/AbstractCursorItemReader.java | 9 ++-
.../database/AbstractPagingItemReader.java | 6 +-
.../ExtendedConnectionDataSourceProxy.java | 4 +-
.../item/database/JdbcCursorItemReader.java | 6 +-
.../database/StoredProcedureItemReader.java | 6 +-
.../batch/item/file/FlatFileItemReader.java | 8 +--
.../item/file/MultiResourceItemReader.java | 6 +-
.../batch/item/file/ResourcesItemReader.java | 6 +-
.../SimpleBinaryBufferedReaderFactory.java | 4 +-
.../SuffixRecordSeparatorPolicy.java | 4 +-
.../file/transform/AbstractLineTokenizer.java | 3 +-
.../item/file/transform/DefaultFieldSet.java | 6 +-
.../transform/DefaultFieldSetFactory.java | 2 +-
.../item/file/transform/LineTokenizer.java | 2 +-
...PatternMatchingCompositeLineTokenizer.java | 3 +-
.../file/transform/RecordFieldExtractor.java | 6 +-
.../item/function/FunctionItemProcessor.java | 6 +-
.../PredicateFilteringItemProcessor.java | 4 +-
.../batch/item/jms/JmsItemReader.java | 6 +-
.../jms/JmsMethodInvocationRecoverer.java | 5 +-
.../batch/item/json/GsonJsonObjectReader.java | 5 +-
.../item/json/JacksonJsonObjectReader.java | 5 +-
.../batch/item/json/JsonItemReader.java | 5 +-
.../batch/item/json/JsonObjectReader.java | 3 +-
.../batch/item/kafka/KafkaItemReader.java | 5 +-
.../batch/item/ldif/LdifReader.java | 5 +-
.../batch/item/ldif/MappingLdifReader.java | 5 +-
.../batch/item/ldif/RecordMapper.java | 3 +-
.../batch/item/redis/RedisItemReader.java | 4 +-
...tractItemCountingItemStreamItemReader.java | 9 ++-
.../ClassifierCompositeItemProcessor.java | 6 +-
.../item/support/CompositeItemProcessor.java | 6 +-
.../item/support/CompositeItemReader.java | 4 +-
.../item/support/IteratorItemReader.java | 6 +-
.../batch/item/support/ListItemReader.java | 6 +-
.../support/PassThroughItemProcessor.java | 6 +-
.../item/support/ScriptItemProcessor.java | 6 +-
.../support/SingleItemPeekableItemReader.java | 9 ++-
.../item/support/SynchronizedItemReader.java | 6 +-
.../support/SynchronizedItemStreamReader.java | 6 +-
.../validator/ValidatingItemProcessor.java | 6 +-
.../batch/item/xml/StaxEventItemReader.java | 5 +-
.../builder/StaxEventItemReaderBuilder.java | 2 +-
.../xml/stax/DefaultFragmentEventReader.java | 4 +-
.../SynchronizedAttributeAccessor.java | 6 +-
.../support/AnnotationMethodResolver.java | 9 ++-
.../batch/support/DatabaseType.java | 4 +-
.../batch/support/MethodInvoker.java | 2 +-
.../batch/support/MethodInvokerUtils.java | 9 ++-
.../batch/support/MethodResolver.java | 2 +-
.../batch/support/PropertiesConverter.java | 3 +-
.../batch/support/SimpleMethodInvoker.java | 6 +-
.../support/AvroItemWriterTestSupport.java | 14 ++--
...dbcBatchItemWriterNamedParameterTests.java | 3 +-
.../support/SqlPagingQueryUtilsTests.java | 5 +-
.../item/file/FlatFileItemReaderTests.java | 3 +-
...ltiResourceItemReaderIntegrationTests.java | 6 +-
.../MultiResourceItemWriterFlatFileTests.java | 3 +-
.../BeanWrapperFieldSetMapperTests.java | 9 ++-
.../function/SupplierItemReaderTests.java | 3 +-
.../batch/item/json/JsonItemReaderTests.java | 5 +-
.../batch/item/sample/FooService.java | 4 +-
...ClassifierCompositeItemProcessorTests.java | 22 +++---
...ItemCountingItemStreamItemReaderTests.java | 5 +-
.../SingleItemPeekableItemReaderTests.java | 5 +-
.../item/xml/StaxEventItemReaderTests.java | 5 +-
.../batch/jms/ExternalRetryInBatchTests.java | 1 -
.../RepeatOperationsInterceptorTests.java | 3 +-
.../repeat/support/ChunkedRepeatTests.java | 5 +-
.../support/ResultHolderResultQueueTests.java | 3 +-
.../batch/retry/jms/ExternalRetryTests.java | 1 -
.../integration/async/AsyncItemProcessor.java | 6 +-
.../chunk/ChunkMessageChannelItemWriter.java | 6 +-
.../integration/chunk/ChunkResponse.java | 3 +-
.../xml/RemoteChunkingManagerParser.java | 4 +-
.../integration/JobRepositorySupport.java | 13 ++--
...RemoteChunkingManagerStepBuilderTests.java | 5 +-
.../integration/chunk/TestItemReader.java | 6 +-
.../config/xml/RemoteChunkingParserTests.java | 5 +-
.../MessagingGatewayIntegrationTests.java | 3 +-
.../partition/ExampleItemReader.java | 6 +-
...tTransactionalPollingIntegrationTests.java | 3 +-
...tTransactionalPollingIntegrationTests.java | 3 +-
...yTransactionalPollingIntegrationTests.java | 3 +-
.../integration/retry/SimpleRecoverer.java | 4 +-
.../TransactionalPollingIntegrationTests.java | 3 +-
.../batch/integration/step/TestTasklet.java | 6 +-
.../batch/samples/amqp/MessageProcessor.java | 6 +-
.../batch/samples/common/ErrorLogTasklet.java | 9 ++-
.../samples/common/SkipCheckingDecider.java | 3 +-
.../samples/common/SkipCheckingListener.java | 4 +-
.../samples/common/StagingItemProcessor.java | 6 +-
.../samples/common/StagingItemReader.java | 8 +--
.../samples/common/StagingItemWriter.java | 6 +-
.../samples/domain/person/PersonService.java | 4 +-
.../CompositeCustomerUpdateLineTokenizer.java | 5 +-
.../domain/trade/CustomerOperation.java | 4 +-
.../trade/CustomerUpdateFieldSetMapper.java | 4 +-
.../domain/trade/CustomerUpdateProcessor.java | 6 +-
.../CustomerCreditIncreaseProcessor.java | 6 +-
.../internal/GeneratingTradeItemReader.java | 6 +-
.../trade/internal/JdbcCustomerDao.java | 4 +-
.../domain/trade/internal/TradeProcessor.java | 6 +-
.../multiline/MultiLineTradeItemReader.java | 6 +-
.../AggregateItemReader.java | 6 +-
.../internal/OrderItemReader.java | 6 +-
.../patternmatching/internal/xml/Order.java | 4 +-
.../football/internal/GameFieldSetMapper.java | 4 +-
.../internal/PlayerFieldSetMapper.java | 4 +-
.../samples/launch/DefaultJobLoader.java | 4 +-
.../GeneratingTradeResettingListener.java | 6 +-
.../batch/samples/loop/LimitDecider.java | 3 +-
.../samples/mail/UserMailItemProcessor.java | 6 +-
.../samples/misc/jmx/InfiniteLoopReader.java | 6 +-
.../ExceptionThrowingItemReaderProxy.java | 6 +-
.../misc/quartz/JobLauncherDetailsTests.java | 10 ++-
.../batch/test/ExecutionContextTestUtils.java | 12 ++--
.../batch/test/JobLauncherTestUtils.java | 2 +-
.../batch/test/JobRepositoryTestUtils.java | 3 +-
.../test/JobScopeTestExecutionListener.java | 4 +-
.../batch/test/StepRunner.java | 3 +-
.../test/StepScopeTestExecutionListener.java | 4 +-
.../BatchTestContextCustomizerFactory.java | 3 +-
.../batch/test/JobLauncherTestUtilsTests.java | 7 +-
...copeAnnotatedListenerIntegrationTests.java | 8 +--
.../batch/test/sample/LoggingTasklet.java | 6 +-
.../batch/test/sample/SampleTasklet.java | 6 +-
289 files changed, 960 insertions(+), 926 deletions(-)
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/SpringBatchVersion.java b/spring-batch-core/src/main/java/org/springframework/batch/core/SpringBatchVersion.java
index 57493f3eef..0b4c40bfd0 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/SpringBatchVersion.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/SpringBatchVersion.java
@@ -15,7 +15,7 @@
*/
package org.springframework.batch.core;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Class that exposes the Spring Batch version. Fetches the "Implementation-Version"
@@ -43,8 +43,7 @@ private SpringBatchVersion() {
* {@code "N/A"} if it cannot be determined.
* @see Package#getImplementationVersion()
*/
- @Nullable
- public static String getVersion() {
+ public static @Nullable String getVersion() {
Package pkg = SpringBatchVersion.class.getPackage();
if (pkg != null && pkg.getImplementationVersion() != null) {
return pkg.getImplementationVersion();
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/JobLocator.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/JobLocator.java
index 202026cb92..7dcbff8309 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/JobLocator.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/JobLocator.java
@@ -15,9 +15,10 @@
*/
package org.springframework.batch.core.configuration;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.job.Job;
import org.springframework.batch.core.launch.NoSuchJobException;
-import org.springframework.lang.Nullable;
/**
* A runtime service locator interface for retrieving job configurations by
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultJobLoader.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultJobLoader.java
index 259259cbe1..a32371c7ea 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultJobLoader.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultJobLoader.java
@@ -23,6 +23,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.Job;
import org.springframework.batch.core.step.Step;
@@ -34,7 +35,6 @@
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/GroupAwareJob.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/GroupAwareJob.java
index b0cbce6657..0899b113c8 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/GroupAwareJob.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/GroupAwareJob.java
@@ -15,11 +15,12 @@
*/
package org.springframework.batch.core.configuration.support;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.job.Job;
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.job.parameters.JobParametersIncrementer;
import org.springframework.batch.core.job.parameters.JobParametersValidator;
-import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
@@ -87,8 +88,7 @@ public boolean isRestartable() {
}
@Override
- @Nullable
- public JobParametersIncrementer getJobParametersIncrementer() {
+ public @Nullable JobParametersIncrementer getJobParametersIncrementer() {
return delegate.getJobParametersIncrementer();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/MapJobRegistry.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/MapJobRegistry.java
index 9058740855..a1159adac7 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/MapJobRegistry.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/MapJobRegistry.java
@@ -23,6 +23,8 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.job.Job;
import org.springframework.batch.core.configuration.DuplicateJobException;
import org.springframework.batch.core.configuration.JobRegistry;
@@ -31,7 +33,6 @@
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/MapStepRegistry.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/MapStepRegistry.java
index 051a44edd0..cdb60e5094 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/MapStepRegistry.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/MapStepRegistry.java
@@ -22,6 +22,8 @@
import java.util.concurrent.ConcurrentMap;
import org.springframework.batch.core.step.Step;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.configuration.DuplicateJobException;
import org.springframework.batch.core.configuration.StepRegistry;
import org.springframework.batch.core.launch.NoSuchJobException;
@@ -62,7 +64,7 @@ public void unregisterStepsFromJob(String jobName) {
}
@Override
- public Step getStep(String jobName, String stepName) throws NoSuchJobException {
+ public @Nullable Step getStep(String jobName, String stepName) throws NoSuchJobException {
Assert.notNull(jobName, "The job name cannot be null.");
Assert.notNull(stepName, "The step name cannot be null.");
if (!map.containsKey(jobName)) {
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/ExceptionElementParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/ExceptionElementParser.java
index de8aff9119..3f4c5bb81f 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/ExceptionElementParser.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/ExceptionElementParser.java
@@ -22,11 +22,13 @@
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.xml.DomUtils;
+
+import org.jspecify.annotations.Nullable;
import org.w3c.dom.Element;
public class ExceptionElementParser {
- public ManagedMap parse(Element element, ParserContext parserContext,
+ public @Nullable ManagedMap parse(Element element, ParserContext parserContext,
String exceptionListName) {
List children = DomUtils.getChildElementsByTagName(element, exceptionListName);
if (children.size() == 1) {
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobParser.java
index 9931c03172..e72068c353 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobParser.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/JobParser.java
@@ -30,6 +30,8 @@
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
+
+import org.jspecify.annotations.Nullable;
import org.w3c.dom.Element;
/**
@@ -158,7 +160,7 @@ else if (listenersElements.size() > 1) {
* @param parserContext The {@link ParserContext}.
* @return the {@link BeanMetadataElement} extracted from the element parameter.
*/
- public BeanMetadataElement parseBeanElement(Element element, ParserContext parserContext) {
+ public @Nullable BeanMetadataElement parseBeanElement(Element element, ParserContext parserContext) {
String refAttribute = element.getAttribute(REF_ATTR);
Element beanElement = DomUtils.getChildElementByTagName(element, BEAN_ELE);
Element refElement = DomUtils.getChildElementByTagName(element, REF_ELE);
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java
index 454c691872..0078d2fb7a 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java
@@ -20,12 +20,13 @@
import java.util.Properties;
import org.springframework.batch.core.job.parameters.JobParameter;
+
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.job.parameters.JobParametersBuilder;
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
-import org.springframework.lang.NonNull;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/JobParametersConverter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/JobParametersConverter.java
index 128938f48f..2b90ae5277 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/JobParametersConverter.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/JobParametersConverter.java
@@ -21,6 +21,10 @@
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.job.parameters.JobParametersBuilder;
import org.springframework.lang.Nullable;
+import org.springframework.batch.core.JobParameters;
+
+import org.jspecify.annotations.Nullable;
+import org.springframework.batch.core.JobParametersBuilder;
/**
* A factory for {@link JobParameters} instances. A job can be executed with many possible
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/AbstractJob.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/AbstractJob.java
index 7c60e2da7a..57c9115a27 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/AbstractJob.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/AbstractJob.java
@@ -29,6 +29,7 @@
import io.micrometer.observation.ObservationRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
@@ -54,7 +55,6 @@
import org.springframework.batch.repeat.RepeatException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -206,8 +206,7 @@ public void setJobParametersIncrementer(JobParametersIncrementer jobParametersIn
}
@Override
- @Nullable
- public JobParametersIncrementer getJobParametersIncrementer() {
+ public @Nullable JobParametersIncrementer getJobParametersIncrementer() {
return this.jobParametersIncrementer;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/Job.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/Job.java
index 80fdd5583b..39f826f39e 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/Job.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/Job.java
@@ -19,6 +19,9 @@
import org.springframework.batch.core.job.parameters.JobParametersIncrementer;
import org.springframework.batch.core.job.parameters.JobParametersValidator;
import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
+
+import org.springframework.batch.core.job.DefaultJobParametersValidator;
/**
* Batch domain object representing a job. {@code Job} is an explicit abstraction
@@ -57,8 +60,7 @@ default boolean isRestartable() {
* @return an incrementer to be used for creating new parameters. Defaults to
* {@code null}.
*/
- @Nullable
- default JobParametersIncrementer getJobParametersIncrementer() {
+ default @Nullable JobParametersIncrementer getJobParametersIncrementer() {
return null;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/JobExecution.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/JobExecution.java
index bfccba5e4b..3662f6903d 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/JobExecution.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/JobExecution.java
@@ -32,7 +32,8 @@
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.batch.item.ExecutionContext;
-import org.springframework.lang.Nullable;
+
+import org.jspecify.annotations.Nullable;
/**
* Batch domain object representing the execution of a job.
@@ -141,8 +142,7 @@ public JobParameters getJobParameters() {
/**
* @return The current end time.
*/
- @Nullable
- public LocalDateTime getEndTime() {
+ public @Nullable LocalDateTime getEndTime() {
return endTime;
}
@@ -165,8 +165,7 @@ public void setEndTime(LocalDateTime endTime) {
/**
* @return The current start time.
*/
- @Nullable
- public LocalDateTime getStartTime() {
+ public @Nullable LocalDateTime getStartTime() {
return startTime;
}
@@ -208,7 +207,7 @@ public void upgradeStatus(BatchStatus status) {
* implementations.
* @return the {@code id} of the enclosing job.
*/
- public Long getJobId() {
+ public @Nullable Long getJobId() {
if (jobInstance != null) {
return jobInstance.getId();
}
@@ -318,8 +317,7 @@ public void addStepExecution(StepExecution stepExecution) {
* @return a {@link LocalDateTime} object representing the last time this
* {@code JobExecution} was updated.
*/
- @Nullable
- public LocalDateTime getLastUpdated() {
+ public @Nullable LocalDateTime getLastUpdated() {
return lastUpdated;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/SimpleJob.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/SimpleJob.java
index d2d2db1825..19e5175fec 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/SimpleJob.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/SimpleJob.java
@@ -21,6 +21,8 @@
import java.util.List;
import org.springframework.batch.core.BatchStatus;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.step.Step;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.batch.core.repository.JobRestartException;
@@ -91,7 +93,7 @@ public void addStep(Step step) {
}
@Override
- public Step getStep(String stepName) {
+ public @Nullable Step getStep(String stepName) {
for (Step step : this.steps) {
if (step.getName().equals(stepName)) {
return step;
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java
index 9b916d749a..fdda55dabb 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java
@@ -15,13 +15,14 @@
*/
package org.springframework.batch.core.job.flow;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.job.JobInterruptedException;
import org.springframework.batch.core.job.StartLimitExceededException;
import org.springframework.batch.core.step.Step;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.batch.core.repository.JobRestartException;
-import org.springframework.lang.Nullable;
/**
* Context and execution strategy for {@link FlowJob} to allow it to delegate its
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java
index 65e3604e85..586efe4bf1 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java
@@ -20,6 +20,8 @@
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.batch.core.job.Job;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.job.JobExecutionException;
import org.springframework.batch.core.step.Step;
@@ -73,7 +75,7 @@ public void setFlow(Flow flow) {
* {@inheritDoc}
*/
@Override
- public Step getStep(String stepName) {
+ public @Nullable Step getStep(String stepName) {
if (!initialized) {
init();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobExecutionDecider.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobExecutionDecider.java
index 34db827b1d..bf66fccff1 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobExecutionDecider.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobExecutionDecider.java
@@ -15,9 +15,10 @@
*/
package org.springframework.batch.core.job.flow;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.step.StepExecution;
-import org.springframework.lang.Nullable;
/**
* Interface allowing for programmatic access to the decision on what the status of a flow
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobFlowExecutor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobFlowExecutor.java
index e72278f638..eac74cd255 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobFlowExecutor.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobFlowExecutor.java
@@ -16,6 +16,8 @@
package org.springframework.batch.core.job.flow;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.job.JobExecution;
@@ -26,7 +28,6 @@
import org.springframework.batch.core.job.StepHandler;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.JobRestartException;
-import org.springframework.lang.Nullable;
/**
* Implementation of {@link FlowExecutor} for use in components that need to execute a
@@ -111,8 +112,7 @@ public JobExecution getJobExecution() {
}
@Override
- @Nullable
- public StepExecution getStepExecution() {
+ public @Nullable StepExecution getStepExecution() {
return stepExecutionHolder.get();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/SimpleFlow.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/SimpleFlow.java
index e90f7db82a..434807d73f 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/SimpleFlow.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/SimpleFlow.java
@@ -28,6 +28,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.step.Step;
import org.springframework.batch.core.step.StepExecution;
@@ -106,7 +107,7 @@ public void setStateTransitions(List stateTransitions) {
* {@inheritDoc}
*/
@Override
- public State getState(String stateName) {
+ public @Nullable State getState(String stateName) {
return stateMap.get(stateName);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/StateTransition.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/StateTransition.java
index 6757f9cc69..bdc82933d7 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/StateTransition.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/StateTransition.java
@@ -18,12 +18,13 @@
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.job.flow.State;
import org.springframework.batch.support.PatternMatcher;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.util.Objects;
+import org.jspecify.annotations.Nullable;
+
/**
* Value object representing a potential transition from one {@link State} to another. The
* originating State name and the next {@link State} to execute are linked by a pattern
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java
index 8bedef1114..11e2ed15ff 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java
@@ -25,6 +25,8 @@
import java.util.concurrent.FutureTask;
import org.springframework.batch.core.job.flow.Flow;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.flow.FlowExecution;
import org.springframework.batch.core.job.flow.FlowExecutionException;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
@@ -34,7 +36,6 @@
import org.springframework.core.task.SyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.core.task.TaskRejectedException;
-import org.springframework.lang.Nullable;
/**
* A {@link State} implementation that splits a {@link Flow} into multiple parallel
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/CompositeJobParametersValidator.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/CompositeJobParametersValidator.java
index 743afa4d85..918996f819 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/CompositeJobParametersValidator.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/CompositeJobParametersValidator.java
@@ -17,8 +17,12 @@
import java.util.List;
+import org.springframework.batch.core.JobParameters;
+
+import org.jspecify.annotations.Nullable;
+import org.springframework.batch.core.JobParametersInvalidException;
+import org.springframework.batch.core.JobParametersValidator;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/DefaultJobParametersValidator.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/DefaultJobParametersValidator.java
index 836cc74803..3ec33f12e4 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/DefaultJobParametersValidator.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/DefaultJobParametersValidator.java
@@ -22,9 +22,9 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameter.java
index 7c02f48b5c..2666b90ad8 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameter.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameter.java
@@ -18,9 +18,10 @@
import java.io.Serializable;
-import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
+import org.jspecify.annotations.NonNull;
+
/**
* Domain representation of a parameter to a batch job. The identifying flag is used to
* indicate if the parameter is to be used as part of the identification of a job
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameters.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameters.java
index b4de56936f..7c4fe66d2c 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameters.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameters.java
@@ -27,9 +27,10 @@
import java.util.List;
import java.util.Map;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
+import org.jspecify.annotations.Nullable;
+
/**
* Value object representing runtime parameters to a batch job. Because the parameters
* have no individual meaning outside of the {@code JobParameters} object they are
@@ -73,8 +74,7 @@ public JobParameters(Map> parameters) {
* @param key The key for which to get a value.
* @return The {@link Long} value or {@code null} if the key is absent.
*/
- @Nullable
- public Long getLong(String key) {
+ public @Nullable Long getLong(String key) {
if (!parameters.containsKey(key)) {
return null;
}
@@ -93,8 +93,7 @@ public Long getLong(String key) {
* @return the parameter represented by the provided key or, if that is missing, the
* default value.
*/
- @Nullable
- public Long getLong(String key, @Nullable Long defaultValue) {
+ public @Nullable Long getLong(String key, @Nullable Long defaultValue) {
if (parameters.containsKey(key)) {
return getLong(key);
}
@@ -108,8 +107,7 @@ public Long getLong(String key, @Nullable Long defaultValue) {
* @param key The key for which to get a value.
* @return The {@link String} value or {@code null} if the key is absent.
*/
- @Nullable
- public String getString(String key) {
+ public @Nullable String getString(String key) {
if (!parameters.containsKey(key)) {
return null;
}
@@ -128,8 +126,7 @@ public String getString(String key) {
* @return the parameter represented by the provided key or, if that is missing, the
* default value.
*/
- @Nullable
- public String getString(String key, @Nullable String defaultValue) {
+ public @Nullable String getString(String key, @Nullable String defaultValue) {
if (parameters.containsKey(key)) {
return getString(key);
}
@@ -143,8 +140,7 @@ public String getString(String key, @Nullable String defaultValue) {
* @param key The key for which to get a value.
* @return The {@link Double} value or {@code null} if the key is absent.
*/
- @Nullable
- public Double getDouble(String key) {
+ public @Nullable Double getDouble(String key) {
if (!parameters.containsKey(key)) {
return null;
}
@@ -163,8 +159,7 @@ public Double getDouble(String key) {
* @return the parameter represented by the provided key or, if that is missing, the
* default value.
*/
- @Nullable
- public Double getDouble(String key, @Nullable Double defaultValue) {
+ public @Nullable Double getDouble(String key, @Nullable Double defaultValue) {
if (parameters.containsKey(key)) {
return getDouble(key);
}
@@ -178,8 +173,7 @@ public Double getDouble(String key, @Nullable Double defaultValue) {
* @param key The key for which to get a value.
* @return the {@link java.util.Date} value or {@code null} if the key is absent.
*/
- @Nullable
- public Date getDate(String key) {
+ public @Nullable Date getDate(String key) {
if (!parameters.containsKey(key)) {
return null;
}
@@ -198,8 +192,7 @@ public Date getDate(String key) {
* @return the parameter represented by the provided key or, if that is missing, the
* default value.
*/
- @Nullable
- public Date getDate(String key, @Nullable Date defaultValue) {
+ public @Nullable Date getDate(String key, @Nullable Date defaultValue) {
if (parameters.containsKey(key)) {
return getDate(key);
}
@@ -213,8 +206,7 @@ public Date getDate(String key, @Nullable Date defaultValue) {
* @param key The key for which to get a value.
* @return the {@link LocalDate} value or {@code null} if the key is absent.
*/
- @Nullable
- public LocalDate getLocalDate(String key) {
+ public @Nullable LocalDate getLocalDate(String key) {
if (!parameters.containsKey(key)) {
return null;
}
@@ -233,8 +225,7 @@ public LocalDate getLocalDate(String key) {
* @return the parameter represented by the provided key or, if that is missing, the
* default value.
*/
- @Nullable
- public LocalDate getLocalDate(String key, @Nullable LocalDate defaultValue) {
+ public @Nullable LocalDate getLocalDate(String key, @Nullable LocalDate defaultValue) {
if (parameters.containsKey(key)) {
return getLocalDate(key);
}
@@ -248,8 +239,7 @@ public LocalDate getLocalDate(String key, @Nullable LocalDate defaultValue) {
* @param key The key for which to get a value.
* @return the {@link LocalTime} value or {@code null} if the key is absent.
*/
- @Nullable
- public LocalTime getLocalTime(String key) {
+ public @Nullable LocalTime getLocalTime(String key) {
if (!parameters.containsKey(key)) {
return null;
}
@@ -268,8 +258,7 @@ public LocalTime getLocalTime(String key) {
* @return the parameter represented by the provided key or, if that is missing, the
* default value.
*/
- @Nullable
- public LocalTime getLocalTime(String key, @Nullable LocalTime defaultValue) {
+ public @Nullable LocalTime getLocalTime(String key, @Nullable LocalTime defaultValue) {
if (parameters.containsKey(key)) {
return getLocalTime(key);
}
@@ -283,8 +272,7 @@ public LocalTime getLocalTime(String key, @Nullable LocalTime defaultValue) {
* @param key The key for which to get a value.
* @return the {@link LocalDateTime} value or {@code null} if the key is absent.
*/
- @Nullable
- public LocalDateTime getLocalDateTime(String key) {
+ public @Nullable LocalDateTime getLocalDateTime(String key) {
if (!parameters.containsKey(key)) {
return null;
}
@@ -303,8 +291,7 @@ public LocalDateTime getLocalDateTime(String key) {
* @return the parameter represented by the provided key or, if that is missing, the
* default value.
*/
- @Nullable
- public LocalDateTime getLocalDateTime(String key, @Nullable LocalDateTime defaultValue) {
+ public @Nullable LocalDateTime getLocalDateTime(String key, @Nullable LocalDateTime defaultValue) {
if (parameters.containsKey(key)) {
return getLocalDateTime(key);
}
@@ -313,8 +300,7 @@ public LocalDateTime getLocalDateTime(String key, @Nullable LocalDateTime defaul
}
}
- @Nullable
- public JobParameter> getParameter(String key) {
+ public @Nullable JobParameter> getParameter(String key) {
Assert.notNull(key, "key must not be null");
return parameters.get(key);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersBuilder.java
index 4cefbc1cbe..3a15e10a2f 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersBuilder.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersBuilder.java
@@ -27,7 +27,8 @@
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.repository.explore.JobExplorer;
-import org.springframework.lang.NonNull;
+
+import org.jspecify.annotations.NonNull;
import org.springframework.util.Assert;
/**
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersIncrementer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersIncrementer.java
index 61caebe6a2..940874adf9 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersIncrementer.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersIncrementer.java
@@ -15,7 +15,7 @@
*/
package org.springframework.batch.core.job.parameters;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Interface for obtaining the next {@link JobParameters} object in a sequence.
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersValidator.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersValidator.java
index c794e2b385..1336cf1339 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersValidator.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersValidator.java
@@ -16,7 +16,7 @@
package org.springframework.batch.core.job.parameters;
import org.springframework.batch.core.job.Job;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Strategy interface for a {@link Job} to use in validating its parameters for an
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/JobOperator.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/JobOperator.java
index 8bb99e9ba3..cb0bbe3e84 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/JobOperator.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/JobOperator.java
@@ -21,6 +21,8 @@
import java.util.Set;
import org.springframework.batch.core.job.Job;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.job.parameters.JobParameters;
@@ -32,7 +34,6 @@
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
-import org.springframework.lang.Nullable;
/**
* High level interface for operating batch jobs.
@@ -292,8 +293,7 @@ JobExecution startNextInstance(Job job) throws NoSuchJobException, JobParameters
* Scheduled for removal in 6.2 or later.
*/
@Deprecated(since = "6.0", forRemoval = true)
- @Nullable
- default JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
+ default @Nullable JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
throw new UnsupportedOperationException();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementer.java
index 759aa4400e..7fffb10408 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementer.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementer.java
@@ -15,11 +15,12 @@
*/
package org.springframework.batch.core.launch.support;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.job.parameters.JobParametersBuilder;
import org.springframework.batch.core.job.parameters.JobParametersIncrementer;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/RunIdIncrementer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/RunIdIncrementer.java
index ee2fac0417..b1824b2428 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/RunIdIncrementer.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/RunIdIncrementer.java
@@ -15,11 +15,12 @@
*/
package org.springframework.batch.core.launch.support;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.job.parameters.JobParameter;
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.job.parameters.JobParametersBuilder;
import org.springframework.batch.core.job.parameters.JobParametersIncrementer;
-import org.springframework.lang.Nullable;
/**
* This incrementer increments a "run.id" parameter of type {@link Long} from the given
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/SimpleJobOperator.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/SimpleJobOperator.java
index c071061466..1e7ed1e3a6 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/SimpleJobOperator.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/SimpleJobOperator.java
@@ -27,6 +27,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.job.Job;
@@ -59,7 +60,6 @@
import org.springframework.batch.core.step.tasklet.TaskletStep;
import org.springframework.batch.support.PropertiesConverter;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -394,9 +394,8 @@ public List getJobInstances(String jobName, int start, int count) throws N
@SuppressWarnings("removal")
@Override
- @Nullable
@Deprecated(since = "6.0", forRemoval = true)
- public JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
+ public @Nullable JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
return this.jobRepository.getJobInstance(jobName, jobParameters);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeItemProcessListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeItemProcessListener.java
index 19c966a503..935ef36013 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeItemProcessListener.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeItemProcessListener.java
@@ -19,7 +19,8 @@
import java.util.List;
import org.springframework.core.Ordered;
-import org.springframework.lang.Nullable;
+
+import org.jspecify.annotations.Nullable;
/**
* @author Dave Syer
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeStepExecutionListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeStepExecutionListener.java
index b3421897ae..d115a4e898 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeStepExecutionListener.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/CompositeStepExecutionListener.java
@@ -19,9 +19,10 @@
import java.util.Iterator;
import org.springframework.batch.core.ExitStatus;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.core.Ordered;
-import org.springframework.lang.Nullable;
/**
* @author Lucas Ward
@@ -56,9 +57,8 @@ public void register(StepExecutionListener stepExecutionListener) {
* that implement {@link Ordered}.
* @see StepExecutionListener#afterStep(StepExecution)
*/
- @Nullable
@Override
- public ExitStatus afterStep(StepExecution stepExecution) {
+ public @Nullable ExitStatus afterStep(StepExecution stepExecution) {
for (Iterator iterator = list.reverse(); iterator.hasNext();) {
StepExecutionListener listener = iterator.next();
ExitStatus close = listener.afterStep(stepExecution);
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ExecutionContextPromotionListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ExecutionContextPromotionListener.java
index 262cda639a..efd7a3fac2 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ExecutionContextPromotionListener.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ExecutionContextPromotionListener.java
@@ -15,6 +15,8 @@
*/
package org.springframework.batch.core.listener;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.job.Job;
import org.springframework.batch.core.step.Step;
@@ -22,7 +24,6 @@
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.support.PatternMatcher;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -49,9 +50,8 @@ public class ExecutionContextPromotionListener implements StepExecutionListener,
private boolean strict = false;
- @Nullable
@Override
- public ExitStatus afterStep(StepExecution stepExecution) {
+ public @Nullable ExitStatus afterStep(StepExecution stepExecution) {
ExecutionContext stepContext = stepExecution.getExecutionContext();
ExecutionContext jobContext = stepExecution.getJobExecution().getExecutionContext();
String exitCode = stepExecution.getExitStatus().getExitCode();
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ItemProcessListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ItemProcessListener.java
index fb3d394fcc..84694ca70d 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ItemProcessListener.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/ItemProcessListener.java
@@ -15,8 +15,9 @@
*/
package org.springframework.batch.core.listener;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.item.ItemProcessor;
-import org.springframework.lang.Nullable;
/**
* Listener interface for the processing of an item. Implementations of this interface are
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/JobListenerMetaData.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/JobListenerMetaData.java
index a268ebcc3d..2433d8f03d 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/JobListenerMetaData.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/JobListenerMetaData.java
@@ -20,9 +20,10 @@
import java.util.Map;
import org.springframework.batch.core.job.JobExecution;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.annotation.AfterJob;
import org.springframework.batch.core.annotation.BeforeJob;
-import org.springframework.lang.Nullable;
/**
* Enumeration for {@link JobExecutionListener} meta data, which ties together the names
@@ -89,8 +90,7 @@ public Class>[] getParamTypes() {
* @param propertyName name of the property to retrieve.
* @return meta data with supplied property name, {@code null} if none exists.
*/
- @Nullable
- public static JobListenerMetaData fromPropertyName(String propertyName) {
+ public static @Nullable JobListenerMetaData fromPropertyName(String propertyName) {
return propertyMap.get(propertyName);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MethodInvokerMethodInterceptor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MethodInvokerMethodInterceptor.java
index 78a5d81701..9b95dd76f8 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MethodInvokerMethodInterceptor.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MethodInvokerMethodInterceptor.java
@@ -20,6 +20,8 @@
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.batch.support.MethodInvoker;
@@ -52,7 +54,7 @@ public MethodInvokerMethodInterceptor(Map> invokerMap
}
@Override
- public Object invoke(MethodInvocation invocation) throws Throwable {
+ public @Nullable Object invoke(MethodInvocation invocation) throws Throwable {
String methodName = invocation.getMethod().getName();
if (ordered && methodName.equals("getOrder")) {
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MulticasterBatchListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MulticasterBatchListener.java
index 02ef2821fa..95dc131078 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MulticasterBatchListener.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/MulticasterBatchListener.java
@@ -19,11 +19,12 @@
import java.util.List;
import org.springframework.batch.core.ExitStatus;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.item.Chunk;
import org.springframework.batch.item.ItemStream;
-import org.springframework.lang.Nullable;
/**
* @author Dave Syer
@@ -143,9 +144,8 @@ public void onProcessError(T item, Exception ex) {
/**
* @see org.springframework.batch.core.listener.CompositeStepExecutionListener#afterStep(StepExecution)
*/
- @Nullable
@Override
- public ExitStatus afterStep(StepExecution stepExecution) {
+ public @Nullable ExitStatus afterStep(StepExecution stepExecution) {
try {
return stepListener.afterStep(stepExecution);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListener.java
index 9c451b417c..7b903a03c3 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListener.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListener.java
@@ -15,10 +15,11 @@
*/
package org.springframework.batch.core.listener;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.step.Step;
import org.springframework.batch.core.step.StepExecution;
-import org.springframework.lang.Nullable;
/**
* Listener interface for the lifecycle of a {@link Step}.
@@ -49,8 +50,7 @@ default void beforeStep(StepExecution stepExecution) {
* @return an {@link ExitStatus} to combine with the normal value. Return {@code null}
* (the default) to leave the old value unchanged.
*/
- @Nullable
- default ExitStatus afterStep(StepExecution stepExecution) {
+ default @Nullable ExitStatus afterStep(StepExecution stepExecution) {
return null;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepListenerMetaData.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepListenerMetaData.java
index 7ceff8a96f..52a7e35697 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepListenerMetaData.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepListenerMetaData.java
@@ -20,6 +20,8 @@
import java.util.Map;
import org.springframework.batch.core.step.StepExecution;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.annotation.AfterChunk;
import org.springframework.batch.core.annotation.AfterChunkError;
import org.springframework.batch.core.annotation.AfterProcess;
@@ -39,7 +41,6 @@
import org.springframework.batch.core.annotation.OnWriteError;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.item.Chunk;
-import org.springframework.lang.Nullable;
/**
* Enumeration for {@link StepListener} meta data, which ties together the names of
@@ -134,8 +135,7 @@ public String getPropertyName() {
* @param propertyName property name to retrieve data for.
* @return meta data with supplied property name, null if none exists.
*/
- @Nullable
- public static StepListenerMetaData fromPropertyName(String propertyName) {
+ public static @Nullable StepListenerMetaData fromPropertyName(String propertyName) {
return propertyMap.get(propertyName);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/BatchMetrics.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/BatchMetrics.java
index 7e5a9e7595..439f9d056d 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/BatchMetrics.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/BatchMetrics.java
@@ -28,8 +28,7 @@
import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
-
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Central class for batch metrics. It provides:
@@ -156,8 +155,8 @@ public static LongTaskTimer createLongTaskTimer(MeterRegistry meterRegistry, Str
* @param endTime the end time
* @return the duration between start time and end time
*/
- @Nullable
- public static Duration calculateDuration(@Nullable LocalDateTime startTime, @Nullable LocalDateTime endTime) {
+ public static @Nullable Duration calculateDuration(@Nullable LocalDateTime startTime,
+ @Nullable LocalDateTime endTime) {
if (startTime == null || endTime == null) {
return null;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java
index 4bdb677018..2e830b43b5 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java
@@ -22,6 +22,10 @@
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.lang.Nullable;
+import org.springframework.batch.core.JobExecution;
+
+import org.jspecify.annotations.Nullable;
+import org.springframework.batch.core.JobInstance;
/**
* Data Access Object for job executions.
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobInstanceDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobInstanceDao.java
index 581e02c00d..733193490a 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobInstanceDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobInstanceDao.java
@@ -19,10 +19,11 @@
import java.util.List;
import org.springframework.batch.core.job.JobExecution;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.launch.NoSuchJobException;
-import org.springframework.lang.Nullable;
/**
* Data Access Object for job instances.
@@ -97,8 +98,7 @@ public interface JobInstanceDao {
*
* @since 4.2
*/
- @Nullable
- default JobInstance getLastJobInstance(String jobName) {
+ default @Nullable JobInstance getLastJobInstance(String jobName) {
throw new UnsupportedOperationException();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/StepExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/StepExecutionDao.java
index 5bdc678471..f0e7e23661 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/StepExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/StepExecutionDao.java
@@ -19,9 +19,10 @@
import java.util.Collection;
import org.springframework.batch.core.job.JobExecution;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.step.StepExecution;
-import org.springframework.lang.Nullable;
public interface StepExecutionDao {
@@ -69,8 +70,7 @@ public interface StepExecutionDao {
* @param stepName the name of the step
* @return a {@link StepExecution}
*/
- @Nullable
- default StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
+ default @Nullable StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
throw new UnsupportedOperationException();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java
index e585661a80..63774beebf 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java
@@ -34,6 +34,8 @@
import java.util.stream.Stream;
import org.springframework.batch.core.job.JobExecution;
+
+import org.jspecify.annotations.NonNull;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.batch.core.repository.ExecutionContextSerializer;
import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao;
@@ -43,7 +45,6 @@
import org.springframework.core.serializer.Serializer;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
-import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
/**
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java
index 012f42982f..857a0c498f 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java
@@ -32,6 +32,8 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
@@ -58,8 +60,6 @@
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
-import org.springframework.lang.NonNull;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -331,9 +331,8 @@ public void updateJobExecution(JobExecution jobExecution) {
}
}
- @Nullable
@Override
- public JobExecution getLastJobExecution(JobInstance jobInstance) {
+ public @Nullable JobExecution getLastJobExecution(JobInstance jobInstance) {
Long id = jobInstance.getId();
@@ -344,8 +343,7 @@ public JobExecution getLastJobExecution(JobInstance jobInstance) {
}
@Override
- @Nullable
- public JobExecution getJobExecution(Long executionId) {
+ public @Nullable JobExecution getJobExecution(Long executionId) {
try {
return getJdbcTemplate().queryForObject(getQuery(GET_EXECUTION_BY_ID), new JobExecutionRowMapper(),
executionId);
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobInstanceDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobInstanceDao.java
index 73cb1cfa99..971fef122b 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobInstanceDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobInstanceDao.java
@@ -24,6 +24,8 @@
import java.util.stream.Stream;
import org.springframework.batch.core.job.DefaultJobKeyGenerator;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.job.JobKeyGenerator;
@@ -38,7 +40,6 @@
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -166,8 +167,7 @@ public JobInstance createJobInstance(String jobName, JobParameters jobParameters
* @throws IllegalArgumentException if any {@link JobParameters} fields are null.
*/
@Override
- @Nullable
- public JobInstance getJobInstance(final String jobName, final JobParameters jobParameters) {
+ public @Nullable JobInstance getJobInstance(final String jobName, final JobParameters jobParameters) {
Assert.notNull(jobName, "Job name must not be null.");
Assert.notNull(jobParameters, "JobParameters must not be null.");
@@ -185,8 +185,7 @@ public JobInstance getJobInstance(final String jobName, final JobParameters jobP
}
@Override
- @Nullable
- public JobInstance getJobInstance(@Nullable Long instanceId) {
+ public @Nullable JobInstance getJobInstance(@Nullable Long instanceId) {
try {
return getJdbcTemplate().queryForObject(getQuery(GET_JOB_FROM_ID), new JobInstanceRowMapper(), instanceId);
@@ -233,8 +232,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAcce
}
@Override
- @Nullable
- public JobInstance getLastJobInstance(String jobName) {
+ public @Nullable JobInstance getLastJobInstance(String jobName) {
try {
return getJdbcTemplate().queryForObject(getQuery(FIND_LAST_JOB_INSTANCE_BY_JOB_NAME),
new JobInstanceRowMapper(), jobName, jobName);
@@ -245,8 +243,7 @@ public JobInstance getLastJobInstance(String jobName) {
}
@Override
- @Nullable
- public JobInstance getJobInstance(JobExecution jobExecution) {
+ public @Nullable JobInstance getJobInstance(JobExecution jobExecution) {
try {
return getJdbcTemplate().queryForObject(getQuery(GET_JOB_FROM_EXECUTION_ID), new JobInstanceRowMapper(),
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcStepExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcStepExecutionDao.java
index a9c910eb09..b73a52938f 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcStepExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcStepExecutionDao.java
@@ -33,6 +33,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
@@ -46,7 +47,6 @@
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -325,8 +325,7 @@ private String truncateExitDescription(String description) {
}
@Override
- @Nullable
- public StepExecution getStepExecution(JobExecution jobExecution, Long stepExecutionId) {
+ public @Nullable StepExecution getStepExecution(JobExecution jobExecution, Long stepExecutionId) {
try (Stream stream = getJdbcTemplate().queryForStream(getQuery(GET_STEP_EXECUTION),
new StepExecutionRowMapper(jobExecution), stepExecutionId)) {
return stream.findFirst().orElse(null);
@@ -334,7 +333,7 @@ public StepExecution getStepExecution(JobExecution jobExecution, Long stepExecut
}
@Override
- public StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
+ public @Nullable StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
List executions = getJdbcTemplate().query(getQuery(GET_LAST_STEP_EXECUTION), (rs, rowNum) -> {
Long jobExecutionId = rs.getLong(19);
JobExecution jobExecution = new JobExecution(jobExecutionId);
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoJobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoJobExecutionDao.java
index d95c8d9105..3abcfed95d 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoJobExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoJobExecutionDao.java
@@ -20,6 +20,8 @@
import java.util.Set;
import org.springframework.batch.core.job.JobExecution;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.repository.dao.JobExecutionDao;
import org.springframework.batch.core.repository.persistence.converter.JobExecutionConverter;
@@ -91,7 +93,7 @@ public List findJobExecutions(JobInstance jobInstance) {
}
@Override
- public JobExecution getLastJobExecution(JobInstance jobInstance) {
+ public @Nullable JobExecution getLastJobExecution(JobInstance jobInstance) {
Query query = query(where("jobInstanceId").is(jobInstance.getId()));
Sort.Order sortOrder = Sort.Order.desc("jobExecutionId");
org.springframework.batch.core.repository.persistence.JobExecution jobExecution = this.mongoOperations.findOne(
@@ -125,7 +127,7 @@ public Set findRunningJobExecutions(String jobName) {
}
@Override
- public JobExecution getJobExecution(Long executionId) {
+ public @Nullable JobExecution getJobExecution(Long executionId) {
Query jobExecutionQuery = query(where("jobExecutionId").is(executionId));
org.springframework.batch.core.repository.persistence.JobExecution jobExecution = this.mongoOperations.findOne(
jobExecutionQuery, org.springframework.batch.core.repository.persistence.JobExecution.class,
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoJobInstanceDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoJobInstanceDao.java
index a85948b6e5..b95d5581d0 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoJobInstanceDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoJobInstanceDao.java
@@ -18,6 +18,8 @@
import java.util.List;
import org.springframework.batch.core.job.DefaultJobKeyGenerator;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.job.JobKeyGenerator;
@@ -87,7 +89,7 @@ public JobInstance createJobInstance(String jobName, JobParameters jobParameters
}
@Override
- public JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
+ public @Nullable JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
String key = this.jobKeyGenerator.generateKey(jobParameters);
Query query = query(where("jobName").is(jobName).and("jobKey").is(key));
org.springframework.batch.core.repository.persistence.JobInstance jobInstance = this.mongoOperations
@@ -96,7 +98,7 @@ public JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
}
@Override
- public JobInstance getJobInstance(Long instanceId) {
+ public @Nullable JobInstance getJobInstance(Long instanceId) {
Query query = query(where("jobInstanceId").is(instanceId));
org.springframework.batch.core.repository.persistence.JobInstance jobInstance = this.mongoOperations
.findOne(query, org.springframework.batch.core.repository.persistence.JobInstance.class, COLLECTION_NAME);
@@ -125,7 +127,7 @@ public List getJobInstances(String jobName, int start, int count) {
}
@Override
- public JobInstance getLastJobInstance(String jobName) {
+ public @Nullable JobInstance getLastJobInstance(String jobName) {
Query query = query(where("jobName").is(jobName));
Sort.Order sortOrder = Sort.Order.desc("jobInstanceId");
org.springframework.batch.core.repository.persistence.JobInstance jobInstance = this.mongoOperations.findOne(
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoStepExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoStepExecutionDao.java
index a7bac8ce26..72c72f5cf4 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoStepExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoStepExecutionDao.java
@@ -22,6 +22,8 @@
import java.util.Optional;
import org.springframework.batch.core.job.JobExecution;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.batch.core.repository.dao.StepExecutionDao;
@@ -89,7 +91,7 @@ public void updateStepExecution(StepExecution stepExecution) {
}
@Override
- public StepExecution getStepExecution(JobExecution jobExecution, Long stepExecutionId) {
+ public @Nullable StepExecution getStepExecution(JobExecution jobExecution, Long stepExecutionId) {
Query query = query(where("stepExecutionId").is(stepExecutionId));
org.springframework.batch.core.repository.persistence.StepExecution stepExecution = this.mongoOperations
.findOne(query, org.springframework.batch.core.repository.persistence.StepExecution.class,
@@ -98,7 +100,7 @@ public StepExecution getStepExecution(JobExecution jobExecution, Long stepExecut
}
@Override
- public StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
+ public @Nullable StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
// TODO optimize the query
// get all step executions
List stepExecutions = new ArrayList<>();
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/JobExplorer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/JobExplorer.java
index aae7366d76..2953879363 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/JobExplorer.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/JobExplorer.java
@@ -20,13 +20,14 @@
import java.util.Set;
import org.springframework.batch.core.job.JobExecution;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.batch.core.launch.NoSuchJobException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.item.ExecutionContext;
-import org.springframework.lang.Nullable;
/**
* Entry point for browsing the executions of running or historical jobs and steps. Since
@@ -129,8 +130,7 @@ default boolean isJobInstanceExists(String jobName, JobParameters jobParameters)
* @param instanceId {@link Long} The ID for the {@link JobInstance} to obtain.
* @return the {@code JobInstance} that has this ID, or {@code null} if not found.
*/
- @Nullable
- default JobInstance getJobInstance(@Nullable Long instanceId) {
+ default @Nullable JobInstance getJobInstance(@Nullable Long instanceId) {
throw new UnsupportedOperationException();
}
@@ -141,8 +141,7 @@ default JobInstance getJobInstance(@Nullable Long instanceId) {
*
* @since 4.2
*/
- @Nullable
- default JobInstance getLastJobInstance(String jobName) {
+ default @Nullable JobInstance getLastJobInstance(String jobName) {
throw new UnsupportedOperationException();
}
@@ -154,8 +153,7 @@ default JobInstance getLastJobInstance(String jobName) {
*
* @since 5.0
*/
- @Nullable
- default JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
+ default @Nullable JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
throw new UnsupportedOperationException();
}
@@ -186,8 +184,7 @@ default long getJobInstanceCount(@Nullable String jobName) throws NoSuchJobExcep
* @param executionId The job execution ID.
* @return the {@link JobExecution} that has this ID or {@code null} if not found.
*/
- @Nullable
- default JobExecution getJobExecution(@Nullable Long executionId) {
+ default @Nullable JobExecution getJobExecution(@Nullable Long executionId) {
throw new UnsupportedOperationException();
}
@@ -227,8 +224,7 @@ default List findJobExecutions(JobInstance jobInstance) {
*
* @since 4.2
*/
- @Nullable
- default JobExecution getLastJobExecution(JobInstance jobInstance) {
+ default @Nullable JobExecution getLastJobExecution(JobInstance jobInstance) {
throw new UnsupportedOperationException();
}
@@ -237,8 +233,7 @@ default JobExecution getLastJobExecution(JobInstance jobInstance) {
* @param jobParameters parameters identifying the {@link JobInstance}
* @return the last execution of job if exists, null otherwise
*/
- @Nullable
- default JobExecution getLastJobExecution(String jobName, JobParameters jobParameters) {
+ default @Nullable JobExecution getLastJobExecution(String jobName, JobParameters jobParameters) {
throw new UnsupportedOperationException();
}
@@ -271,8 +266,7 @@ default Set findRunningJobExecutions(@Nullable String jobName) {
*
* @see #getJobExecution(Long)
*/
- @Nullable
- default StepExecution getStepExecution(@Nullable Long jobExecutionId, @Nullable Long stepExecutionId) {
+ default @Nullable StepExecution getStepExecution(@Nullable Long jobExecutionId, @Nullable Long stepExecutionId) {
throw new UnsupportedOperationException();
}
@@ -281,8 +275,7 @@ default StepExecution getStepExecution(@Nullable Long jobExecutionId, @Nullable
* @param stepName the name of the step execution that might have run.
* @return the last execution of step for the given job instance.
*/
- @Nullable
- default StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
+ default @Nullable StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
throw new UnsupportedOperationException();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/JobExplorerFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/JobExplorerFactoryBean.java
index 98da269d85..3fe109e587 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/JobExplorerFactoryBean.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/JobExplorerFactoryBean.java
@@ -22,6 +22,8 @@
import javax.sql.DataSource;
import org.springframework.batch.core.job.DefaultJobKeyGenerator;
+
+import org.jspecify.annotations.NonNull;
import org.springframework.batch.core.job.JobKeyGenerator;
import org.springframework.batch.core.converter.DateToStringConverter;
import org.springframework.batch.core.converter.LocalDateTimeToStringConverter;
@@ -51,7 +53,6 @@
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.incrementer.AbstractDataFieldMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
-import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
/**
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/SimpleJobExplorer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/SimpleJobExplorer.java
index f549783baf..195cd839c3 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/SimpleJobExplorer.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/SimpleJobExplorer.java
@@ -28,11 +28,12 @@
import org.springframework.batch.core.repository.dao.StepExecutionDao;
import org.springframework.batch.core.repository.support.SimpleJobRepository;
import org.springframework.batch.item.ExecutionContext;
-import org.springframework.lang.Nullable;
import java.util.List;
import java.util.Set;
+import org.jspecify.annotations.Nullable;
+
/**
* Implementation of {@link JobExplorer} that uses the injected DAOs.
*
@@ -120,21 +121,18 @@ public List findJobInstancesByName(String jobName, int start, int c
return getJobInstances(jobName, start, count);
}
- @Nullable
@Override
- public JobInstance getJobInstance(@Nullable Long instanceId) {
+ public @Nullable JobInstance getJobInstance(@Nullable Long instanceId) {
return jobInstanceDao.getJobInstance(instanceId);
}
- @Nullable
@Override
- public JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
+ public @Nullable JobInstance getJobInstance(String jobName, JobParameters jobParameters) {
return jobInstanceDao.getJobInstance(jobName, jobParameters);
}
- @Nullable
@Override
- public JobInstance getLastJobInstance(String jobName) {
+ public @Nullable JobInstance getLastJobInstance(String jobName) {
return jobInstanceDao.getLastJobInstance(jobName);
}
@@ -166,9 +164,8 @@ public List getJobExecutions(JobInstance jobInstance) {
return executions;
}
- @Nullable
@Override
- public JobExecution getLastJobExecution(JobInstance jobInstance) {
+ public @Nullable JobExecution getLastJobExecution(JobInstance jobInstance) {
JobExecution lastJobExecution = jobExecutionDao.getLastJobExecution(jobInstance);
if (lastJobExecution != null) {
getJobExecutionDependencies(lastJobExecution);
@@ -191,8 +188,7 @@ public List findJobExecutions(JobInstance jobInstance) {
}
@Override
- @Nullable
- public JobExecution getLastJobExecution(String jobName, JobParameters jobParameters) {
+ public @Nullable JobExecution getLastJobExecution(String jobName, JobParameters jobParameters) {
JobInstance jobInstance = jobInstanceDao.getJobInstance(jobName, jobParameters);
if (jobInstance == null) {
return null;
@@ -218,9 +214,8 @@ public Set findRunningJobExecutions(@Nullable String jobName) {
return executions;
}
- @Nullable
@Override
- public JobExecution getJobExecution(@Nullable Long executionId) {
+ public @Nullable JobExecution getJobExecution(@Nullable Long executionId) {
if (executionId == null) {
return null;
}
@@ -253,9 +248,8 @@ private void getJobExecutionDependencies(JobExecution jobExecution) {
* ===================================================================================
*/
- @Nullable
@Override
- public StepExecution getStepExecution(@Nullable Long jobExecutionId, @Nullable Long executionId) {
+ public @Nullable StepExecution getStepExecution(@Nullable Long jobExecutionId, @Nullable Long executionId) {
JobExecution jobExecution = jobExecutionDao.getJobExecution(jobExecutionId);
if (jobExecution == null) {
return null;
@@ -267,8 +261,7 @@ public StepExecution getStepExecution(@Nullable Long jobExecutionId, @Nullable L
}
@Override
- @Nullable
- public StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
+ public @Nullable StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
StepExecution latest = stepExecutionDao.getLastStepExecution(jobInstance, stepName);
if (latest != null) {
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JdbcJobRepositoryFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JdbcJobRepositoryFactoryBean.java
index cab693390e..1f5a52b9d1 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JdbcJobRepositoryFactoryBean.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JdbcJobRepositoryFactoryBean.java
@@ -27,11 +27,12 @@
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.lang.NonNull;
import javax.sql.DataSource;
import java.nio.charset.Charset;
+import org.jspecify.annotations.NonNull;
+
/**
* A {@link FactoryBean} that automates the creation of a {@link SimpleJobRepository}
* using JDBC DAO implementations which persist batch metadata in a relational database.
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java
index a1cc3d9044..bccecf10a2 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java
@@ -18,6 +18,8 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.NonNull;
+
import org.springframework.batch.core.converter.DateToStringConverter;
import org.springframework.batch.core.converter.LocalDateTimeToStringConverter;
import org.springframework.batch.core.converter.LocalDateToStringConverter;
@@ -41,7 +43,6 @@
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobContext.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobContext.java
index bd92302649..0e3e465dc1 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobContext.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobContext.java
@@ -26,6 +26,8 @@
import java.util.Set;
import org.springframework.batch.core.job.JobExecution;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.job.parameters.JobParameter;
import org.springframework.batch.core.job.parameters.JobParameters;
@@ -33,7 +35,6 @@
import org.springframework.batch.core.scope.StepScope;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.context.SynchronizedAttributeAccessor;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -121,8 +122,7 @@ private void unregisterDestructionCallbacks(String name) {
* @see SynchronizedAttributeAccessor#removeAttribute(String)
*/
@Override
- @Nullable
- public Object removeAttribute(String name) {
+ public @Nullable Object removeAttribute(String name) {
unregisterDestructionCallbacks(name);
return super.removeAttribute(name);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobSynchronizationManager.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobSynchronizationManager.java
index e3fa5d2ee3..e448cb711c 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobSynchronizationManager.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/JobSynchronizationManager.java
@@ -15,9 +15,10 @@
*/
package org.springframework.batch.core.scope.context;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.job.Job;
import org.springframework.batch.core.job.JobExecution;
-import org.springframework.lang.Nullable;
/**
* Central convenience class for framework use in managing the job scope context.
@@ -51,8 +52,7 @@ protected void close(JobContext context) {
* @return the current {@link JobContext} or {@code null} if there is none (if one has
* not been registered for this thread).
*/
- @Nullable
- public static JobContext getContext() {
+ public static @Nullable JobContext getContext() {
return manager.getContext();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepContext.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepContext.java
index 579aab3879..fb9057fea2 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepContext.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepContext.java
@@ -26,6 +26,8 @@
import java.util.Set;
import org.springframework.batch.core.job.JobInstance;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.parameters.JobParameter;
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.step.StepExecution;
@@ -33,7 +35,6 @@
import org.springframework.batch.core.scope.StepScope;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.context.SynchronizedAttributeAccessor;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -157,8 +158,7 @@ private void unregisterDestructionCallbacks(String name) {
* @see SynchronizedAttributeAccessor#removeAttribute(String)
*/
@Override
- @Nullable
- public Object removeAttribute(String name) {
+ public @Nullable Object removeAttribute(String name) {
unregisterDestructionCallbacks(name);
return super.removeAttribute(name);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepSynchronizationManager.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepSynchronizationManager.java
index 34c24d0dc0..4f100cf2be 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepSynchronizationManager.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/StepSynchronizationManager.java
@@ -15,9 +15,10 @@
*/
package org.springframework.batch.core.scope.context;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.step.Step;
import org.springframework.batch.core.step.StepExecution;
-import org.springframework.lang.Nullable;
/**
* Central convenience class for framework use in managing the step scope context.
@@ -51,8 +52,7 @@ protected void close(StepContext context) {
* @return the current {@link StepContext} or {@code null} if there is none (if one
* has not been registered for this thread).
*/
- @Nullable
- public static StepContext getContext() {
+ public static @Nullable StepContext getContext() {
return manager.getContext();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/SynchronizationManagerSupport.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/SynchronizationManagerSupport.java
index 1891f55883..63671bbc1e 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/SynchronizationManagerSupport.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/context/SynchronizationManagerSupport.java
@@ -20,7 +20,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Central convenience class for framework use in managing the scope context.
@@ -62,8 +62,7 @@ public abstract class SynchronizationManagerSupport {
* @return the current context or {@code null} if there is none (if one has not been
* registered for this thread).
*/
- @Nullable
- public C getContext() {
+ public @Nullable C getContext() {
if (getCurrent().isEmpty()) {
return null;
}
@@ -79,8 +78,7 @@ public C getContext() {
* @param execution the execution to register
* @return a new context or the current one if it has the same execution
*/
- @Nullable
- public C register(@Nullable E execution) {
+ public @Nullable C register(@Nullable E execution) {
if (execution == null) {
return null;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/NoWorkFoundStepExecutionListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/NoWorkFoundStepExecutionListener.java
index 940230080a..535245564b 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/NoWorkFoundStepExecutionListener.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/NoWorkFoundStepExecutionListener.java
@@ -16,9 +16,10 @@
package org.springframework.batch.core.step;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.listener.StepExecutionListener;
-import org.springframework.lang.Nullable;
/**
* Fails the step if no items have been processed ( item count is 0).
@@ -28,9 +29,8 @@
*/
public class NoWorkFoundStepExecutionListener implements StepExecutionListener {
- @Nullable
@Override
- public ExitStatus afterStep(StepExecution stepExecution) {
+ public @Nullable ExitStatus afterStep(StepExecution stepExecution) {
if (stepExecution.getReadCount() == 0) {
return ExitStatus.FAILED;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/StepExecution.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/StepExecution.java
index 939102aaa5..69d654101d 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/StepExecution.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/StepExecution.java
@@ -29,7 +29,8 @@
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.item.ExecutionContext;
-import org.springframework.lang.Nullable;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@@ -159,8 +160,7 @@ public void setCommitCount(long commitCount) {
* Returns the time when this execution ended or {@code null} if the step is running.
* @return the time when this execution ended or {@code null} if the step is running.
*/
- @Nullable
- public LocalDateTime getEndTime() {
+ public @Nullable LocalDateTime getEndTime() {
return endTime;
}
@@ -256,8 +256,7 @@ public void setCreateTime(LocalDateTime createTime) {
* Gets the time when this execution started.
* @return the time when this execution started.
*/
- @Nullable
- public LocalDateTime getStartTime() {
+ public @Nullable LocalDateTime getStartTime() {
return startTime;
}
@@ -306,7 +305,7 @@ public String getStepName() {
* Accessor for the job execution ID.
* @return the {@code jobExecutionId}.
*/
- public Long getJobExecutionId() {
+ public @Nullable Long getJobExecutionId() {
if (jobExecution != null) {
return jobExecution.getId();
}
@@ -460,8 +459,7 @@ public void setProcessSkipCount(long processSkipCount) {
/**
* @return the Date representing the last time this execution was persisted.
*/
- @Nullable
- public LocalDateTime getLastUpdated() {
+ public @Nullable LocalDateTime getLastUpdated() {
return lastUpdated;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ChunkOrientedTasklet.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ChunkOrientedTasklet.java
index cd780c2977..23e5aca231 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ChunkOrientedTasklet.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ChunkOrientedTasklet.java
@@ -18,12 +18,13 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.step.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.Chunk;
import org.springframework.batch.repeat.RepeatStatus;
-import org.springframework.lang.Nullable;
/**
* A {@link Tasklet} implementing variations on read-process-write item handling.
@@ -59,9 +60,8 @@ public void setBuffering(boolean buffering) {
this.buffering = buffering;
}
- @Nullable
@Override
- public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
+ public @Nullable RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
@SuppressWarnings("unchecked")
Chunk inputs = (Chunk) chunkContext.getAttribute(INPUTS_KEY);
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProcessor.java
index d51b488c52..d5f5d002d0 100755
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProcessor.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProcessor.java
@@ -22,6 +22,7 @@
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Timer;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.step.StepContribution;
import org.springframework.batch.core.step.StepExecution;
@@ -32,7 +33,6 @@
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProvider.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProvider.java
index d5420b6123..9a19c02848 100755
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProvider.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProvider.java
@@ -24,6 +24,8 @@
import io.micrometer.core.instrument.Timer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.batch.core.step.StepContribution;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.batch.core.listener.StepListener;
@@ -33,7 +35,6 @@
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.repeat.RepeatOperations;
import org.springframework.batch.repeat.RepeatStatus;
-import org.springframework.lang.Nullable;
/**
* Simple implementation of the ChunkProvider interface that does basic chunk providing
@@ -101,8 +102,7 @@ public void registerListener(StepListener listener) {
* @return the item or {@code null} if the data source is exhausted
* @throws Exception is thrown if error occurs during read.
*/
- @Nullable
- protected final I doRead() throws Exception {
+ protected final @Nullable I doRead() throws Exception {
try {
listener.beforeRead();
I item = itemReader.read();
@@ -177,8 +177,7 @@ public void postProcess(StepContribution contribution, Chunk chunk) {
* data (e.g. skips) and it wants to force a commit.
* @throws Exception if there is a generic issue
*/
- @Nullable
- protected I read(StepContribution contribution, Chunk chunk) throws SkipOverflowException, Exception {
+ protected @Nullable I read(StepContribution contribution, Chunk chunk) throws SkipOverflowException, Exception {
return doRead();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java
index dcbdb70ac3..fb569f545f 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java
@@ -22,6 +22,8 @@
import java.util.Set;
import org.springframework.batch.core.job.Job;
+
+import org.jspecify.annotations.NonNull;
import org.springframework.batch.core.job.parameters.JobParameter;
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.job.parameters.JobParametersBuilder;
@@ -29,7 +31,6 @@
import org.springframework.batch.core.converter.DefaultJobParametersConverter;
import org.springframework.batch.core.converter.JobParametersConverter;
import org.springframework.batch.item.ExecutionContext;
-import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
/**
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/CallableTaskletAdapter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/CallableTaskletAdapter.java
index d22f2e7360..6f377eab8e 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/CallableTaskletAdapter.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/CallableTaskletAdapter.java
@@ -18,10 +18,11 @@
import java.util.concurrent.Callable;
import org.springframework.batch.core.step.StepContribution;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -75,9 +76,8 @@ public void afterPropertiesSet() {
* {@link StepContribution} and the attributes.
* @see Tasklet#execute(StepContribution, ChunkContext)
*/
- @Nullable
@Override
- public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
+ public @Nullable RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
return callable.call();
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/ConfigurableSystemProcessExitCodeMapper.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/ConfigurableSystemProcessExitCodeMapper.java
index c801d6d255..ad0baa0f73 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/ConfigurableSystemProcessExitCodeMapper.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/ConfigurableSystemProcessExitCodeMapper.java
@@ -19,6 +19,8 @@
import java.util.Map;
import org.springframework.batch.core.ExitStatus;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@@ -36,7 +38,7 @@ public class ConfigurableSystemProcessExitCodeMapper implements SystemProcessExi
private Map
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.json;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/builder/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/builder/package-info.java
index 45fb008395..7657b3593e 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/builder/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/builder/package-info.java
@@ -19,7 +19,7 @@
*
* @author Mathieu Ouellet
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.kafka.builder;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/package-info.java
index c0e084822b..439ed117a0 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/package-info.java
@@ -19,7 +19,7 @@
*
* @author Mathieu Ouellet
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.kafka;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/builder/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/builder/package-info.java
index 2bcd72c032..90ea20093d 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/builder/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/builder/package-info.java
@@ -18,8 +18,9 @@
* Builders for LDIF related components.
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.ldif.builder;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/package-info.java
index f50cc0e797..9fcfa0e641 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/package-info.java
@@ -5,8 +5,9 @@
*
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.ldif;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/builder/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/builder/package-info.java
index 42a7de1483..542dda3fd4 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/builder/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/builder/package-info.java
@@ -18,8 +18,9 @@
* Builders for JavaMail related components.
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.mail.builder;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/javamail/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/javamail/package-info.java
index c1811df0f2..3ba7f21e39 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/javamail/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/javamail/package-info.java
@@ -18,8 +18,9 @@
* JavaMail related components.
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.mail.javamail;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/package-info.java
index 413f4b3833..ee3457634c 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/package-info.java
@@ -3,8 +3,9 @@
*
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.mail;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/package-info.java
index ae555480b6..b0992cd366 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure interfaces and primary dependencies for item concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/builder/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/builder/package-info.java
index 672042949c..36c9e31800 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/builder/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/builder/package-info.java
@@ -19,7 +19,7 @@
*
* @author Mahmoud Ben Hassine
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.support.builder;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/package-info.java
index 3b67e5685a..2eb4f52709 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/package-info.java
@@ -3,7 +3,7 @@
* Internal support package
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.support;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/package-info.java
index 2e35f78b8e..635928175f 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/package-info.java
@@ -18,8 +18,9 @@
* Infrastructure utility classes.
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.util;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/validator/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/validator/package-info.java
index c56d78dab1..d29c02a68b 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/validator/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/validator/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of item validator concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.validator;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/builder/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/builder/package-info.java
index 8f60fbf801..c7061e204e 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/builder/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/builder/package-info.java
@@ -18,8 +18,9 @@
* Builders for Stax event item reader and writer.
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.xml.builder;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/package-info.java
index 6b81565cb7..2d6ce6042e 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of xml input and output.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.xml;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/stax/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/stax/package-info.java
index b1f51036c8..6e9acd60c9 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/stax/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/stax/package-info.java
@@ -18,8 +18,9 @@
* Item reader and writer based on Stax.
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.item.xml.stax;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/package-info.java
index 8293c2f96d..27a2c1d1eb 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of . concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/poller/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/poller/package-info.java
index 5318e22460..8d83b0dad5 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/poller/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/poller/package-info.java
@@ -19,7 +19,7 @@
*
* @author Mahmoud Ben Hassine
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.poller;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/callback/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/callback/package-info.java
index 878daec20c..c27b8fee69 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/callback/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/callback/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of repeat callback concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.repeat.callback;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/context/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/context/package-info.java
index e8d0f11f93..b4b38ceb55 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/context/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/context/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of repeat context concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.repeat.context;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/package-info.java
index e32d20693c..c9fd7223d0 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of repeat exception handler concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.repeat.exception;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/interceptor/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/interceptor/package-info.java
index d67cb6a468..d3ca06f58d 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/interceptor/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/interceptor/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of repeat aop concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.repeat.interceptor;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/listener/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/listener/package-info.java
index db3be41dae..e26921e1e2 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/listener/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/listener/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of repeat interceptor concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.repeat.listener;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/package-info.java
index e247cdbeeb..205c741b57 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of repeat concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.repeat;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/policy/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/policy/package-info.java
index 6cdf5440d6..189c508fd6 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/policy/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/policy/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of repeat policy concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.repeat.policy;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/package-info.java
index 6d690403cc..100283229d 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of repeat support concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.repeat.support;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/package-info.java
index 01ab17a99f..616df1b58c 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of support concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.support;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/transaction/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/transaction/package-info.java
index 19e932270a..5cfd27b96e 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/transaction/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/transaction/package-info.java
@@ -3,7 +3,7 @@
* Infrastructure implementations of support transaction concerns.
*
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.support.transaction;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/package-info.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/package-info.java
index 7285a61bef..af9ae7bbe6 100644
--- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/package-info.java
+++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/package-info.java
@@ -4,8 +4,9 @@
*
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.integration.async;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/package-info.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/package-info.java
index e375ea5649..71b552b10a 100644
--- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/package-info.java
+++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/chunk/package-info.java
@@ -3,8 +3,9 @@
*
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.integration.chunk;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/package-info.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/package-info.java
index 40a894455a..2f520080d4 100644
--- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/package-info.java
+++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/package-info.java
@@ -18,8 +18,9 @@
* APIs for the configuration of Spring Integration components through annotations.
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.integration.config.annotation;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/package-info.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/package-info.java
index aaf3e6a87e..15c8edc22e 100644
--- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/package-info.java
+++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/xml/package-info.java
@@ -18,8 +18,9 @@
* APIs for the configuration of Spring Integration components through XML.
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.integration.config.xml;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/package-info.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/package-info.java
index 0c5d640f42..8ebf51a897 100644
--- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/package-info.java
+++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/launch/package-info.java
@@ -3,8 +3,9 @@
*
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.integration.launch;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/package-info.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/package-info.java
index 060f80d47c..cef4798bd6 100644
--- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/package-info.java
+++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/package-info.java
@@ -1,7 +1,7 @@
/**
* Provides integration with Spring Integration.
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.integration;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/package-info.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/package-info.java
index e8b25768cb..a5f36fe737 100644
--- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/package-info.java
+++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/package-info.java
@@ -3,8 +3,9 @@
*
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.integration.partition;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/context/package-info.java b/spring-batch-test/src/main/java/org/springframework/batch/test/context/package-info.java
index 32d298c926..37ec519a34 100644
--- a/spring-batch-test/src/main/java/org/springframework/batch/test/context/package-info.java
+++ b/spring-batch-test/src/main/java/org/springframework/batch/test/context/package-info.java
@@ -18,8 +18,9 @@
* APIs for the configuration of Spring Batch test support.
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.test.context;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/package-info.java b/spring-batch-test/src/main/java/org/springframework/batch/test/package-info.java
index 747af4e482..6c479e3a5d 100644
--- a/spring-batch-test/src/main/java/org/springframework/batch/test/package-info.java
+++ b/spring-batch-test/src/main/java/org/springframework/batch/test/package-info.java
@@ -18,8 +18,9 @@
* Utility classes for batch job/step testing.
*
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
-@NonNullApi
+@NullMarked
package org.springframework.batch.test;
-import org.springframework.lang.NonNullApi;
+import org.jspecify.annotations.NullMarked;
From 624ab1484aa04f6e39a28bc6160ea73920a754b6 Mon Sep 17 00:00:00 2001
From: Stefano Cordio
Date: Mon, 9 Jun 2025 16:30:42 +0200
Subject: [PATCH 5/6] Remove unnecessary `@NonNull`
Signed-off-by: Stefano Cordio
---
.../DefaultJobParametersConverter.java | 3 +-
.../core/job/parameters/JobParameter.java | 6 ++--
.../job/parameters/JobParametersBuilder.java | 33 +++++++++----------
.../dao/jdbc/JdbcExecutionContextDao.java | 3 +-
.../dao/jdbc/JdbcJobExecutionDao.java | 3 +-
.../support/JobExplorerFactoryBean.java | 5 ++-
.../support/JdbcJobRepositoryFactoryBean.java | 6 ++--
.../support/JobRepositoryFactoryBean.java | 13 +++++---
.../job/DefaultJobParametersExtractor.java | 4 +--
.../batch/item/ItemProcessor.java | 3 +-
.../batch/item/ItemWriter.java | 4 +--
.../batch/support/PropertiesConverter.java | 5 ++-
12 files changed, 38 insertions(+), 50 deletions(-)
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java
index 0078d2fb7a..e148e2e75f 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java
@@ -21,7 +21,6 @@
import org.springframework.batch.core.job.parameters.JobParameter;
-import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.job.parameters.JobParametersBuilder;
@@ -131,7 +130,7 @@ public Properties getProperties(@Nullable JobParameters jobParameters) {
* @param conversionService the conversion service to use. Must not be {@code null}.
* @since 5.0
*/
- public void setConversionService(@NonNull ConfigurableConversionService conversionService) {
+ public void setConversionService(ConfigurableConversionService conversionService) {
Assert.notNull(conversionService, "The conversionService must not be null");
this.conversionService = conversionService;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameter.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameter.java
index 2666b90ad8..8b3048a1fa 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameter.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParameter.java
@@ -20,8 +20,6 @@
import org.springframework.util.Assert;
-import org.jspecify.annotations.NonNull;
-
/**
* Domain representation of a parameter to a batch job. The identifying flag is used to
* indicate if the parameter is to be used as part of the identification of a job
@@ -49,7 +47,7 @@ public class JobParameter implements Serializable {
* @param type the type of the parameter. Must not be {@code null}.
* @param identifying true if the parameter is identifying. false otherwise.
*/
- public JobParameter(@NonNull T value, @NonNull Class type, boolean identifying) {
+ public JobParameter(T value, Class type, boolean identifying) {
Assert.notNull(value, "value must not be null");
Assert.notNull(type, "type must not be null");
this.value = value;
@@ -62,7 +60,7 @@ public JobParameter(@NonNull T value, @NonNull Class type, boolean identifyin
* @param value the value of the parameter. Must not be {@code null}.
* @param type the type of the parameter. Must not be {@code null}.
*/
- public JobParameter(@NonNull T value, @NonNull Class type) {
+ public JobParameter(T value, Class type) {
this(value, type, true);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersBuilder.java
index 3a15e10a2f..89212ecaa5 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersBuilder.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/JobParametersBuilder.java
@@ -28,7 +28,6 @@
import org.springframework.batch.core.job.JobInstance;
import org.springframework.batch.core.repository.explore.JobExplorer;
-import org.jspecify.annotations.NonNull;
import org.springframework.util.Assert;
/**
@@ -96,7 +95,7 @@ public JobParametersBuilder(JobParameters jobParameters, JobExplorer jobExplorer
* @param parameter The runtime parameter. Must not be {@code null}.
* @return a reference to this object.
*/
- public JobParametersBuilder addString(String key, @NonNull String parameter) {
+ public JobParametersBuilder addString(String key, String parameter) {
return addString(key, parameter, true);
}
@@ -108,7 +107,7 @@ public JobParametersBuilder addString(String key, @NonNull String parameter) {
* job instance.
* @return a reference to this object.
*/
- public JobParametersBuilder addString(String key, @NonNull String parameter, boolean identifying) {
+ public JobParametersBuilder addString(String key, String parameter, boolean identifying) {
Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null");
this.parameterMap.put(key, new JobParameter<>(parameter, String.class, identifying));
return this;
@@ -120,7 +119,7 @@ public JobParametersBuilder addString(String key, @NonNull String parameter, boo
* @param parameter The runtime parameter. Must not be {@code null}.
* @return a reference to this object.
*/
- public JobParametersBuilder addDate(String key, @NonNull Date parameter) {
+ public JobParametersBuilder addDate(String key, Date parameter) {
return addDate(key, parameter, true);
}
@@ -132,7 +131,7 @@ public JobParametersBuilder addDate(String key, @NonNull Date parameter) {
* instance
* @return a reference to this object.
*/
- public JobParametersBuilder addDate(String key, @NonNull Date parameter, boolean identifying) {
+ public JobParametersBuilder addDate(String key, Date parameter, boolean identifying) {
Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null");
this.parameterMap.put(key, new JobParameter<>(parameter, Date.class, identifying));
return this;
@@ -144,7 +143,7 @@ public JobParametersBuilder addDate(String key, @NonNull Date parameter, boolean
* @param parameter The runtime parameter. Must not be {@code null}.
* @return a reference to this object.
*/
- public JobParametersBuilder addLocalDate(String key, @NonNull LocalDate parameter) {
+ public JobParametersBuilder addLocalDate(String key, LocalDate parameter) {
return addLocalDate(key, parameter, true);
}
@@ -156,7 +155,7 @@ public JobParametersBuilder addLocalDate(String key, @NonNull LocalDate paramete
* instance
* @return a reference to this object.
*/
- public JobParametersBuilder addLocalDate(String key, @NonNull LocalDate parameter, boolean identifying) {
+ public JobParametersBuilder addLocalDate(String key, LocalDate parameter, boolean identifying) {
Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null");
this.parameterMap.put(key, new JobParameter<>(parameter, LocalDate.class, identifying));
return this;
@@ -168,7 +167,7 @@ public JobParametersBuilder addLocalDate(String key, @NonNull LocalDate paramete
* @param parameter The runtime parameter. Must not be {@code null}.
* @return a reference to this object.
*/
- public JobParametersBuilder addLocalTime(String key, @NonNull LocalTime parameter) {
+ public JobParametersBuilder addLocalTime(String key, LocalTime parameter) {
return addLocalTime(key, parameter, true);
}
@@ -180,7 +179,7 @@ public JobParametersBuilder addLocalTime(String key, @NonNull LocalTime paramete
* instance
* @return a reference to this object.
*/
- public JobParametersBuilder addLocalTime(String key, @NonNull LocalTime parameter, boolean identifying) {
+ public JobParametersBuilder addLocalTime(String key, LocalTime parameter, boolean identifying) {
Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null");
this.parameterMap.put(key, new JobParameter<>(parameter, LocalTime.class, identifying));
return this;
@@ -192,7 +191,7 @@ public JobParametersBuilder addLocalTime(String key, @NonNull LocalTime paramete
* @param parameter The runtime parameter. Must not be {@code null}.
* @return a reference to this object.
*/
- public JobParametersBuilder addLocalDateTime(String key, @NonNull LocalDateTime parameter) {
+ public JobParametersBuilder addLocalDateTime(String key, LocalDateTime parameter) {
return addLocalDateTime(key, parameter, true);
}
@@ -204,7 +203,7 @@ public JobParametersBuilder addLocalDateTime(String key, @NonNull LocalDateTime
* instance
* @return a reference to this object.
*/
- public JobParametersBuilder addLocalDateTime(String key, @NonNull LocalDateTime parameter, boolean identifying) {
+ public JobParametersBuilder addLocalDateTime(String key, LocalDateTime parameter, boolean identifying) {
Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null");
this.parameterMap.put(key, new JobParameter<>(parameter, LocalDateTime.class, identifying));
return this;
@@ -216,7 +215,7 @@ public JobParametersBuilder addLocalDateTime(String key, @NonNull LocalDateTime
* @param parameter The runtime parameter. Must not be {@code null}.
* @return a reference to this object.
*/
- public JobParametersBuilder addLong(String key, @NonNull Long parameter) {
+ public JobParametersBuilder addLong(String key, Long parameter) {
return addLong(key, parameter, true);
}
@@ -228,7 +227,7 @@ public JobParametersBuilder addLong(String key, @NonNull Long parameter) {
* instance.
* @return a reference to this object.
*/
- public JobParametersBuilder addLong(String key, @NonNull Long parameter, boolean identifying) {
+ public JobParametersBuilder addLong(String key, Long parameter, boolean identifying) {
Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null");
this.parameterMap.put(key, new JobParameter<>(parameter, Long.class, identifying));
return this;
@@ -240,7 +239,7 @@ public JobParametersBuilder addLong(String key, @NonNull Long parameter, boolean
* @param parameter The runtime parameter. Must not be {@code null}.
* @return a reference to this object.
*/
- public JobParametersBuilder addDouble(String key, @NonNull Double parameter) {
+ public JobParametersBuilder addDouble(String key, Double parameter) {
return addDouble(key, parameter, true);
}
@@ -252,7 +251,7 @@ public JobParametersBuilder addDouble(String key, @NonNull Double parameter) {
* instance.
* @return a reference to this object.
*/
- public JobParametersBuilder addDouble(String key, @NonNull Double parameter, boolean identifying) {
+ public JobParametersBuilder addDouble(String key, Double parameter, boolean identifying) {
Assert.notNull(parameter, "Value for parameter '" + key + "' must not be null");
this.parameterMap.put(key, new JobParameter<>(parameter, Double.class, identifying));
return this;
@@ -289,7 +288,7 @@ public JobParametersBuilder addJobParameter(String key, JobParameter> jobParam
* @param the type of the parameter
* @since 5.0
*/
- public JobParametersBuilder addJobParameter(String name, @NonNull T value, Class type, boolean identifying) {
+ public JobParametersBuilder addJobParameter(String name, T value, Class type, boolean identifying) {
Assert.notNull(value, "Value for parameter '" + name + "' must not be null");
return addJobParameter(name, new JobParameter<>(value, type, identifying));
}
@@ -303,7 +302,7 @@ public JobParametersBuilder addJobParameter(String name, @NonNull T value, C
* @param the type of the parameter
* @since 5.0
*/
- public JobParametersBuilder addJobParameter(String name, @NonNull T value, Class type) {
+ public JobParametersBuilder addJobParameter(String name, T value, Class type) {
return addJobParameter(name, value, type, true);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java
index 63774beebf..5cd48937af 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java
@@ -35,7 +35,6 @@
import org.springframework.batch.core.job.JobExecution;
-import org.jspecify.annotations.NonNull;
import org.springframework.batch.core.step.StepExecution;
import org.springframework.batch.core.repository.ExecutionContextSerializer;
import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao;
@@ -145,7 +144,7 @@ public void setShortContextLength(int shortContextLength) {
* @param charset to use when serializing/deserializing the execution context.
* @since 5.0
*/
- public void setCharset(@NonNull Charset charset) {
+ public void setCharset(Charset charset) {
Assert.notNull(charset, "Charset must not be null");
this.charset = charset;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java
index 857a0c498f..c86bff0938 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java
@@ -32,7 +32,6 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.BatchStatus;
@@ -196,7 +195,7 @@ public void setJobExecutionIncrementer(DataFieldMaxValueIncrementer jobExecution
* Set the conversion service to use to convert job parameters from String literals to
* typed values and vice versa.
*/
- public void setConversionService(@NonNull ConfigurableConversionService conversionService) {
+ public void setConversionService(ConfigurableConversionService conversionService) {
Assert.notNull(conversionService, "conversionService must not be null");
this.conversionService = conversionService;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/JobExplorerFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/JobExplorerFactoryBean.java
index 3fe109e587..a43fee0ed2 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/JobExplorerFactoryBean.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/explore/support/JobExplorerFactoryBean.java
@@ -23,7 +23,6 @@
import org.springframework.batch.core.job.DefaultJobKeyGenerator;
-import org.jspecify.annotations.NonNull;
import org.springframework.batch.core.job.JobKeyGenerator;
import org.springframework.batch.core.converter.DateToStringConverter;
import org.springframework.batch.core.converter.LocalDateTimeToStringConverter;
@@ -146,7 +145,7 @@ public void setJobKeyGenerator(JobKeyGenerator jobKeyGenerator) {
* @see JdbcExecutionContextDao#setCharset(Charset)
* @since 5.0
*/
- public void setCharset(@NonNull Charset charset) {
+ public void setCharset(Charset charset) {
Assert.notNull(charset, "Charset must not be null");
this.charset = charset;
}
@@ -157,7 +156,7 @@ public void setCharset(@NonNull Charset charset) {
* @param conversionService the conversion service to use
* @since 5.0
*/
- public void setConversionService(@NonNull ConfigurableConversionService conversionService) {
+ public void setConversionService(ConfigurableConversionService conversionService) {
Assert.notNull(conversionService, "ConversionService must not be null");
this.conversionService = conversionService;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JdbcJobRepositoryFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JdbcJobRepositoryFactoryBean.java
index 1f5a52b9d1..d5d920212d 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JdbcJobRepositoryFactoryBean.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JdbcJobRepositoryFactoryBean.java
@@ -31,8 +31,6 @@
import javax.sql.DataSource;
import java.nio.charset.Charset;
-import org.jspecify.annotations.NonNull;
-
/**
* A {@link FactoryBean} that automates the creation of a {@link SimpleJobRepository}
* using JDBC DAO implementations which persist batch metadata in a relational database.
@@ -166,7 +164,7 @@ public void setIncrementerFactory(DataFieldMaxValueIncrementerFactory incremente
* @since 5.0
*/
@Override
- public void setCharset(@NonNull Charset charset) {
+ public void setCharset(Charset charset) {
super.setCharset(charset);
}
@@ -177,7 +175,7 @@ public void setCharset(@NonNull Charset charset) {
* @since 5.0
*/
@Override
- public void setConversionService(@NonNull ConfigurableConversionService conversionService) {
+ public void setConversionService(ConfigurableConversionService conversionService) {
super.setConversionService(conversionService);
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java
index bccecf10a2..a1509b7c38 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java
@@ -18,8 +18,6 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jspecify.annotations.NonNull;
-
import org.springframework.batch.core.converter.DateToStringConverter;
import org.springframework.batch.core.converter.LocalDateTimeToStringConverter;
import org.springframework.batch.core.converter.LocalDateToStringConverter;
@@ -29,7 +27,12 @@
import org.springframework.batch.core.converter.StringToLocalDateTimeConverter;
import org.springframework.batch.core.converter.StringToLocalTimeConverter;
import org.springframework.batch.core.repository.ExecutionContextSerializer;
-import org.springframework.batch.core.repository.dao.*;
+import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao;
+import org.springframework.batch.core.repository.dao.DefaultExecutionContextSerializer;
+import org.springframework.batch.core.repository.dao.ExecutionContextDao;
+import org.springframework.batch.core.repository.dao.JobExecutionDao;
+import org.springframework.batch.core.repository.dao.JobInstanceDao;
+import org.springframework.batch.core.repository.dao.StepExecutionDao;
import org.springframework.batch.core.repository.dao.jdbc.JdbcExecutionContextDao;
import org.springframework.batch.core.repository.dao.jdbc.JdbcJobExecutionDao;
import org.springframework.batch.core.repository.dao.jdbc.JdbcJobInstanceDao;
@@ -202,7 +205,7 @@ public void setIncrementerFactory(DataFieldMaxValueIncrementerFactory incremente
* @see JdbcExecutionContextDao#setCharset(Charset)
* @since 5.0
*/
- public void setCharset(@NonNull Charset charset) {
+ public void setCharset(Charset charset) {
Assert.notNull(charset, "Charset must not be null");
this.charset = charset;
}
@@ -213,7 +216,7 @@ public void setCharset(@NonNull Charset charset) {
* @param conversionService the conversion service to use
* @since 5.0
*/
- public void setConversionService(@NonNull ConfigurableConversionService conversionService) {
+ public void setConversionService(ConfigurableConversionService conversionService) {
Assert.notNull(conversionService, "ConversionService must not be null");
this.conversionService = conversionService;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java
index fb569f545f..71a9fec0c1 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractor.java
@@ -22,8 +22,6 @@
import java.util.Set;
import org.springframework.batch.core.job.Job;
-
-import org.jspecify.annotations.NonNull;
import org.springframework.batch.core.job.parameters.JobParameter;
import org.springframework.batch.core.job.parameters.JobParameters;
import org.springframework.batch.core.job.parameters.JobParametersBuilder;
@@ -104,7 +102,7 @@ public void setUseAllParentParameters(boolean useAllParentParameters) {
* removal in 6.2 or later.
*/
@Deprecated(since = "6.0", forRemoval = true)
- public void setJobParametersConverter(@NonNull JobParametersConverter jobParametersConverter) {
+ public void setJobParametersConverter(JobParametersConverter jobParametersConverter) {
Assert.notNull(jobParametersConverter, "jobParametersConverter must not be null");
this.jobParametersConverter = jobParametersConverter;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java
index feff5ab0c1..7bb2ad7386 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java
@@ -16,7 +16,6 @@
package org.springframework.batch.item;
-import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
/**
@@ -54,6 +53,6 @@ public interface ItemProcessor {
* @throws Exception thrown if exception occurs during processing.
*/
@Nullable
- O process(@NonNull I item) throws Exception;
+ O process(I item) throws Exception;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemWriter.java
index 77a9159b12..76edb408b3 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemWriter.java
@@ -16,8 +16,6 @@
package org.springframework.batch.item;
-import org.jspecify.annotations.NonNull;
-
/**
*
* Basic interface for generic output operations. Class implementing this interface will
@@ -48,6 +46,6 @@ public interface ItemWriter {
* @throws Exception if there are errors. The framework will catch the exception and
* convert or rethrow it as appropriate.
*/
- void write(@NonNull Chunk extends T> chunk) throws Exception;
+ void write(Chunk extends T> chunk) throws Exception;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/PropertiesConverter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/PropertiesConverter.java
index b90fd7c4a1..06a2598dc7 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/PropertiesConverter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/PropertiesConverter.java
@@ -23,7 +23,6 @@
import org.springframework.util.Assert;
-import org.jspecify.annotations.NonNull;
import org.springframework.util.StringUtils;
/**
@@ -51,7 +50,7 @@ private PropertiesConverter() {
* @param stringToParse String to parse. Must not be {@code null}.
* @return Properties parsed from each key=value pair.
*/
- public static Properties stringToProperties(@NonNull String stringToParse) {
+ public static Properties stringToProperties(String stringToParse) {
Assert.notNull(stringToParse, "stringToParse must not be null");
if (!StringUtils.hasText(stringToParse)) {
return new Properties();
@@ -77,7 +76,7 @@ public static Properties stringToProperties(@NonNull String stringToParse) {
* {@code null}.
* @return String representation of the properties object
*/
- public static String propertiesToString(@NonNull Properties propertiesToParse) {
+ public static String propertiesToString(Properties propertiesToParse) {
Assert.notNull(propertiesToParse, "propertiesToParse must not be null");
if (propertiesToParse.isEmpty()) {
return "";
From 3be2fa56b63c7de96213c4a3101aa5618681760b Mon Sep 17 00:00:00 2001
From: Stefano Cordio
Date: Mon, 9 Jun 2025 17:03:11 +0200
Subject: [PATCH 6/6] Fix NullAway findings
Signed-off-by: Stefano Cordio
---
pom.xml | 1 +
.../support/DefaultJobLoader.java | 8 +-
.../batch/core/job/flow/FlowExecutor.java | 3 +-
.../batch/core/job/flow/FlowJob.java | 2 +-
.../job/flow/support/state/SplitState.java | 4 +-
.../support/TaskExecutorJobLauncher.java | 5 +-
.../support/AbstractPartitionHandler.java | 2 +-
.../support/TaskExecutorPartitionHandler.java | 4 +-
.../repository/dao/ExecutionContextDao.java | 10 +--
.../core/repository/dao/JobExecutionDao.java | 12 +--
.../core/repository/dao/JobInstanceDao.java | 9 +--
.../core/repository/dao/StepExecutionDao.java | 3 +-
.../dao/jdbc/JdbcExecutionContextDao.java | 8 +-
.../dao/jdbc/JdbcJobExecutionDao.java | 2 +-
.../dao/jdbc/JdbcJobInstanceDao.java | 2 +-
.../dao/jdbc/JdbcStepExecutionDao.java | 2 +-
.../item/FaultTolerantChunkProcessor.java | 12 +--
.../core/step/item/SimpleChunkProvider.java | 2 +-
.../batch/core/step/tasklet/Tasklet.java | 3 +-
.../batch/core/step/tasklet/TaskletStep.java | 2 +-
.../step/StepLocatorStepFactoryBeanTests.java | 2 +-
.../step/skip/ReprocessExceptionTests.java | 2 +-
.../StepExecutorInterruptionTests.java | 2 +-
.../org/springframework/batch/item/Chunk.java | 14 ++--
.../batch/item/ItemProcessor.java | 3 +-
.../batch/item/ItemReader.java | 3 +-
.../batch/item/ItemStreamException.java | 8 +-
.../batch/item/ItemStreamSupport.java | 4 +-
.../batch/item/KeyValueItemWriter.java | 14 ++--
.../batch/item/PeekableItemReader.java | 3 +-
.../batch/item/SkipWrapper.java | 9 ++-
.../batch/item/SpELItemKeyMapper.java | 9 +--
.../AbstractMethodInvokingDelegator.java | 35 +++++----
.../item/adapter/HippyMethodInvoker.java | 8 +-
...ropertyExtractingDelegatingItemWriter.java | 9 ++-
.../batch/item/amqp/AmqpItemReader.java | 5 +-
.../batch/item/amqp/AmqpItemWriter.java | 4 +-
.../amqp/builder/AmqpItemReaderBuilder.java | 6 +-
.../amqp/builder/AmqpItemWriterBuilder.java | 8 +-
.../batch/item/amqp/builder/package-info.java | 3 +-
.../batch/item/avro/AvroItemReader.java | 11 ++-
.../batch/item/avro/AvroItemWriter.java | 12 +--
.../avro/builder/AvroItemReaderBuilder.java | 24 +++---
.../avro/builder/AvroItemWriterBuilder.java | 8 +-
.../batch/item/avro/builder/package-info.java | 25 +++++++
.../batch/item/avro/package-info.java | 9 +++
.../data/AbstractPaginatedDataItemReader.java | 16 ++--
.../item/data/MongoCursorItemReader.java | 74 +++++++++----------
.../batch/item/data/MongoItemWriter.java | 50 +++++++------
.../item/data/MongoPagingItemReader.java | 38 ++++------
.../batch/item/data/RepositoryItemReader.java | 13 ++--
.../batch/item/data/RepositoryItemWriter.java | 10 ++-
.../builder/MongoCursorItemReaderBuilder.java | 55 +++++++++-----
.../data/builder/MongoItemWriterBuilder.java | 7 +-
.../builder/MongoPagingItemReaderBuilder.java | 47 ++++++++----
.../builder/RepositoryItemReaderBuilder.java | 19 +++--
.../builder/RepositoryItemWriterBuilder.java | 13 ++--
.../database/AbstractCursorItemReader.java | 30 ++++----
.../database/AbstractPagingItemReader.java | 4 +-
.../item/database/JdbcBatchItemWriter.java | 16 ++--
.../item/database/JdbcCursorItemReader.java | 16 ++--
.../item/database/JdbcPagingItemReader.java | 38 ++++++----
.../item/database/JpaCursorItemReader.java | 28 ++++---
.../batch/item/database/JpaItemWriter.java | 6 +-
.../database/StoredProcedureItemReader.java | 24 +++---
.../builder/JpaCursorItemReaderBuilder.java | 14 ++--
.../builder/JpaItemWriterBuilder.java | 4 +-
.../builder/JpaPagingItemReaderBuilder.java | 30 +++++---
.../orm/AbstractJpaQueryProvider.java | 5 +-
.../database/orm/JpaNamedQueryProvider.java | 8 +-
.../database/orm/JpaNativeQueryProvider.java | 13 ++--
.../item/database/orm/JpaQueryProvider.java | 7 +-
.../AbstractSqlPagingQueryProvider.java | 29 ++++----
.../SqlPagingQueryProviderFactoryBean.java | 15 ++--
.../batch/item/file/FlatFileItemReader.java | 20 +++--
.../batch/item/file/FlatFileItemWriter.java | 5 +-
.../builder/FlatFileItemReaderBuilder.java | 73 +++++++++---------
.../builder/FlatFileItemWriterBuilder.java | 56 ++++++++------
.../MultiResourceItemReaderBuilder.java | 10 ++-
.../mapping/BeanWrapperFieldSetMapper.java | 9 ++-
.../file/transform/AbstractLineTokenizer.java | 36 ++++-----
.../transform/DelimitedLineTokenizer.java | 10 +--
.../file/transform/FixedLengthTokenizer.java | 11 ++-
.../transform/FormatterLineAggregator.java | 4 +-
.../transform/RangeArrayPropertyEditor.java | 2 +-
.../batch/item/json/JsonObjectReader.java | 3 +-
.../batch/item/kafka/KafkaItemWriter.java | 6 +-
.../batch/item/ldif/RecordMapper.java | 3 +-
.../item/queue/BlockingQueueItemReader.java | 2 +-
.../batch/item/redis/RedisItemWriter.java | 4 +-
.../batch/item/redis/package-info.java | 25 +++++++
.../util/ExecutionContextUserSupport.java | 6 +-
.../SimpleLimitExceptionHandler.java | 2 +-
.../RepeatOperationsInterceptor.java | 2 +-
.../batch/repeat/support/RepeatTemplate.java | 4 +-
.../support/AnnotationMethodResolver.java | 2 +-
.../batch/support/DatabaseType.java | 26 +++----
.../batch/support/MethodInvoker.java | 3 +-
.../batch/support/MethodInvokerUtils.java | 4 +-
.../batch/support/MethodResolver.java | 6 +-
.../jms/BatchMessageListenerContainer.java | 2 +-
.../item/file/FlatFileItemWriterTests.java | 2 +-
.../batch/poller/DirectPollerTests.java | 2 +-
.../ConcurrentTransactionAwareProxyTests.java | 12 +--
.../integration/async/AsyncItemProcessor.java | 2 +-
.../MessageChannelPartitionHandler.java | 2 +-
.../samples/common/StagingItemWriter.java | 2 +-
.../test/StepScopeTestExecutionListener.java | 6 +-
108 files changed, 720 insertions(+), 609 deletions(-)
create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/package-info.java
create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/package-info.java
create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/redis/package-info.java
diff --git a/pom.xml b/pom.xml
index 4c099cc777..bac95c3512 100644
--- a/pom.xml
+++ b/pom.xml
@@ -191,6 +191,7 @@
-Xep:NullAway:ERROR
-XepOpt:NullAway:OnlyNullMarked
+ -XepOpt:NullAway:CustomContractAnnotations=org.springframework.lang.Contract
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultJobLoader.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultJobLoader.java
index a32371c7ea..ac30a0bfe5 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultJobLoader.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultJobLoader.java
@@ -222,9 +222,9 @@ private Collection doLoad(ApplicationContextFactory factory, boolean unregi
* @return all the {@link Step} defined by the given step locator and context
* @see StepLocator
*/
- private Collection getSteps(final StepLocator stepLocator, final ApplicationContext jobApplicationContext) {
- final Collection stepNames = stepLocator.getStepNames();
- final Collection result = new ArrayList<>();
+ private Collection getSteps(StepLocator stepLocator, ApplicationContext jobApplicationContext) {
+ Collection stepNames = stepLocator.getStepNames();
+ Collection result = new ArrayList<>();
for (String stepName : stepNames) {
result.add(stepLocator.getStep(stepName));
}
@@ -234,7 +234,7 @@ private Collection getSteps(final StepLocator stepLocator, final Applicati
// are more Step instances defined. Right now they are registered as being
// available in the
// context of the job but we have no idea if they are linked to that Job or not.
- final Map allSteps = jobApplicationContext.getBeansOfType(Step.class);
+ Map allSteps = jobApplicationContext.getBeansOfType(Step.class);
for (Map.Entry entry : allSteps.entrySet()) {
if (!stepNames.contains(entry.getKey())) {
result.add(entry.getValue());
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java
index fdda55dabb..126b986084 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java
@@ -51,8 +51,7 @@ public interface FlowExecutor {
/**
* @return the latest {@link StepExecution} or null if there is none
*/
- @Nullable
- StepExecution getStepExecution();
+ @Nullable StepExecution getStepExecution();
/**
* Chance to clean up resources at the end of a flow (whether it completed
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java
index 586efe4bf1..c887df0a67 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java
@@ -127,7 +127,7 @@ public Collection getStepNames() {
* @see AbstractJob#doExecute(JobExecution)
*/
@Override
- protected void doExecute(final JobExecution execution) throws JobExecutionException {
+ protected void doExecute(JobExecution execution) throws JobExecutionException {
try {
JobFlowExecutor executor = new JobFlowExecutor(getJobRepository(),
new SimpleStepHandler(getJobRepository()), execution);
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java
index 11e2ed15ff..a90a93930b 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java
@@ -97,13 +97,13 @@ public Collection getFlows() {
* @see State#handle(FlowExecutor)
*/
@Override
- public FlowExecutionStatus handle(final FlowExecutor executor) throws Exception {
+ public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
// TODO: collect the last StepExecution from the flows as well, so they
// can be abandoned if necessary
Collection> tasks = new ArrayList<>();
- for (final Flow flow : flows) {
+ for (Flow flow : flows) {
final FutureTask task = new FutureTask<>(() -> flow.start(executor));
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/TaskExecutorJobLauncher.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/TaskExecutorJobLauncher.java
index bd8d5bea37..b607e24f45 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/TaskExecutorJobLauncher.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/TaskExecutorJobLauncher.java
@@ -98,9 +98,8 @@ public class TaskExecutorJobLauncher implements JobLauncher, InitializingBean {
* @throws JobParametersInvalidException thrown if jobParameters is invalid.
*/
@Override
- public JobExecution run(final Job job, final JobParameters jobParameters)
- throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException,
- JobParametersInvalidException {
+ public JobExecution run(Job job, final JobParameters jobParameters) throws JobExecutionAlreadyRunningException,
+ JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException {
Assert.notNull(job, "The Job must not be null.");
Assert.notNull(jobParameters, "The JobParameters must not be null.");
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/AbstractPartitionHandler.java b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/AbstractPartitionHandler.java
index 0d7692eba1..fbaeda9cbe 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/AbstractPartitionHandler.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/AbstractPartitionHandler.java
@@ -52,7 +52,7 @@ protected abstract Set doHandle(StepExecution managerStepExecutio
* @see PartitionHandler#handle(StepExecutionSplitter, StepExecution)
*/
@Override
- public Collection handle(final StepExecutionSplitter stepSplitter,
+ public Collection handle(StepExecutionSplitter stepSplitter,
final StepExecution managerStepExecution) throws Exception {
final Set stepExecutions = stepSplitter.split(managerStepExecution, gridSize);
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/TaskExecutorPartitionHandler.java b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/TaskExecutorPartitionHandler.java
index bc0ff6d1a7..f8e7605909 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/TaskExecutorPartitionHandler.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/partition/support/TaskExecutorPartitionHandler.java
@@ -93,7 +93,7 @@ protected Set doHandle(StepExecution managerStepExecution,
final Set> tasks = new HashSet<>(getGridSize());
final Set result = new HashSet<>();
- for (final StepExecution stepExecution : partitionStepExecutions) {
+ for (StepExecution stepExecution : partitionStepExecutions) {
final FutureTask task = createTask(step, stepExecution);
try {
@@ -127,7 +127,7 @@ protected Set doHandle(StepExecution managerStepExecution,
* @param stepExecution the given execution
* @return the task executing the given step
*/
- protected FutureTask createTask(final Step step, final StepExecution stepExecution) {
+ protected FutureTask createTask(Step step, final StepExecution stepExecution) {
return new FutureTask<>(() -> {
step.execute(stepExecution);
return stepExecution;
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/ExecutionContextDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/ExecutionContextDao.java
index 53921956e4..f6ab4ca603 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/ExecutionContextDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/ExecutionContextDao.java
@@ -48,14 +48,14 @@ public interface ExecutionContextDao {
* entry for the context should not exist yet.
* @param jobExecution {@link JobExecution} instance that contains the context.
*/
- void saveExecutionContext(final JobExecution jobExecution);
+ void saveExecutionContext(JobExecution jobExecution);
/**
* Persist the execution context associated with the given stepExecution, persistent
* entry for the context should not exist yet.
* @param stepExecution {@link StepExecution} instance that contains the context.
*/
- void saveExecutionContext(final StepExecution stepExecution);
+ void saveExecutionContext(StepExecution stepExecution);
/**
* Persist the execution context associated with each stepExecution in a given
@@ -63,21 +63,21 @@ public interface ExecutionContextDao {
* @param stepExecutions a collection of {@link StepExecution}s that contain the
* contexts.
*/
- void saveExecutionContexts(final Collection stepExecutions);
+ void saveExecutionContexts(Collection stepExecutions);
/**
* Persist the updates of execution context associated with the given jobExecution.
* Persistent entry should already exist for this context.
* @param jobExecution {@link JobExecution} instance that contains the context.
*/
- void updateExecutionContext(final JobExecution jobExecution);
+ void updateExecutionContext(JobExecution jobExecution);
/**
* Persist the updates of execution context associated with the given stepExecution.
* Persistent entry should already exist for this context.
* @param stepExecution {@link StepExecution} instance that contains the context.
*/
- void updateExecutionContext(final StepExecution stepExecution);
+ void updateExecutionContext(StepExecution stepExecution);
/**
* Delete the execution context of the given {@link JobExecution}.
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java
index 2e830b43b5..37f64d4695 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java
@@ -19,13 +19,9 @@
import java.util.List;
import java.util.Set;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.core.job.JobExecution;
import org.springframework.batch.core.job.JobInstance;
-import org.springframework.lang.Nullable;
-import org.springframework.batch.core.JobExecution;
-
-import org.jspecify.annotations.Nullable;
-import org.springframework.batch.core.JobInstance;
/**
* Data Access Object for job executions.
@@ -68,8 +64,7 @@ public interface JobExecutionDao {
* @return the last {@link JobExecution} to execute for this instance or {@code null}
* if no job execution is found for the given job instance.
*/
- @Nullable
- JobExecution getLastJobExecution(JobInstance jobInstance);
+ @Nullable JobExecution getLastJobExecution(JobInstance jobInstance);
/**
* @param jobName {@link String} containing the name of the job.
@@ -82,8 +77,7 @@ public interface JobExecutionDao {
* @param executionId {@link Long} containing the id of the execution.
* @return the {@link JobExecution} for given identifier.
*/
- @Nullable
- JobExecution getJobExecution(Long executionId);
+ @Nullable JobExecution getJobExecution(Long executionId);
/**
* Because it may be possible that the status of a JobExecution is updated while
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobInstanceDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobInstanceDao.java
index 733193490a..d4eab5f958 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobInstanceDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobInstanceDao.java
@@ -58,16 +58,14 @@ public interface JobInstanceDao {
* @return {@link JobInstance} object matching the job name and {@link JobParameters}
* or {@code null}
*/
- @Nullable
- JobInstance getJobInstance(String jobName, JobParameters jobParameters);
+ @Nullable JobInstance getJobInstance(String jobName, JobParameters jobParameters);
/**
* Fetch the job instance with the provided identifier.
* @param instanceId the job identifier
* @return the job instance with this identifier or {@code null} if it doesn't exist
*/
- @Nullable
- JobInstance getJobInstance(@Nullable Long instanceId);
+ @Nullable JobInstance getJobInstance(@Nullable Long instanceId);
/**
* Fetch the JobInstance for the provided JobExecution.
@@ -75,8 +73,7 @@ public interface JobInstanceDao {
* @return the JobInstance for the provided execution or {@code null} if it doesn't
* exist.
*/
- @Nullable
- JobInstance getJobInstance(JobExecution jobExecution);
+ @Nullable JobInstance getJobInstance(JobExecution jobExecution);
/**
* Fetch the last job instances with the provided name, sorted backwards by primary
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/StepExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/StepExecutionDao.java
index f0e7e23661..a50d0d89b3 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/StepExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/StepExecutionDao.java
@@ -60,8 +60,7 @@ public interface StepExecutionDao {
* @param stepExecutionId the step execution id
* @return a {@link StepExecution}
*/
- @Nullable
- StepExecution getStepExecution(JobExecution jobExecution, Long stepExecutionId);
+ @Nullable StepExecution getStepExecution(JobExecution jobExecution, Long stepExecutionId);
/**
* Retrieve the last {@link StepExecution} for a given {@link JobInstance} ordered by
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java
index 5cd48937af..db717b1f56 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcExecutionContextDao.java
@@ -172,7 +172,7 @@ public ExecutionContext getExecutionContext(StepExecution stepExecution) {
}
@Override
- public void updateExecutionContext(final JobExecution jobExecution) {
+ public void updateExecutionContext(JobExecution jobExecution) {
Long executionId = jobExecution.getId();
ExecutionContext executionContext = jobExecution.getExecutionContext();
Assert.notNull(executionId, "ExecutionId must not be null.");
@@ -184,7 +184,7 @@ public void updateExecutionContext(final JobExecution jobExecution) {
}
@Override
- public void updateExecutionContext(final StepExecution stepExecution) {
+ public void updateExecutionContext(StepExecution stepExecution) {
// Attempt to prevent concurrent modification errors by blocking here if
// someone is already trying to do it.
this.lock.lock();
@@ -271,7 +271,7 @@ public void afterPropertiesSet() throws Exception {
* @param serializedContext the serialized context to persist
* @param sql with parameters (shortContext, longContext, executionId)
*/
- private void persistSerializedContext(final Long executionId, String serializedContext, String sql) {
+ private void persistSerializedContext(Long executionId, String serializedContext, String sql) {
final String shortContext;
final String longContext;
@@ -302,7 +302,7 @@ private void persistSerializedContext(final Long executionId, String serializedC
* @param serializedContexts the execution contexts to serialize
* @param sql with parameters (shortContext, longContext, executionId)
*/
- private void persistSerializedContexts(final Map serializedContexts, String sql) {
+ private void persistSerializedContexts(Map serializedContexts, String sql) {
if (!serializedContexts.isEmpty()) {
final Iterator executionIdIterator = serializedContexts.keySet().iterator();
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java
index c86bff0938..7c31ac4d80 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java
@@ -207,7 +207,7 @@ public void afterPropertiesSet() throws Exception {
}
@Override
- public List findJobExecutions(final JobInstance job) {
+ public List findJobExecutions(JobInstance job) {
Assert.notNull(job, "Job cannot be null.");
Assert.notNull(job.getId(), "Job Id cannot be null.");
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobInstanceDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobInstanceDao.java
index 971fef122b..ed902b9c0f 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobInstanceDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobInstanceDao.java
@@ -167,7 +167,7 @@ public JobInstance createJobInstance(String jobName, JobParameters jobParameters
* @throws IllegalArgumentException if any {@link JobParameters} fields are null.
*/
@Override
- public @Nullable JobInstance getJobInstance(final String jobName, final JobParameters jobParameters) {
+ public @Nullable JobInstance getJobInstance(String jobName, final JobParameters jobParameters) {
Assert.notNull(jobName, "Job name must not be null.");
Assert.notNull(jobParameters, "JobParameters must not be null.");
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcStepExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcStepExecutionDao.java
index b73a52938f..b0c8097901 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcStepExecutionDao.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcStepExecutionDao.java
@@ -176,7 +176,7 @@ public void saveStepExecution(StepExecution stepExecution) {
* @see StepExecutionDao#saveStepExecutions(Collection)
*/
@Override
- public void saveStepExecutions(final Collection stepExecutions) {
+ public void saveStepExecutions(Collection stepExecutions) {
Assert.notNull(stepExecutions, "Attempt to save a null collection of step executions");
if (!stepExecutions.isEmpty()) {
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java
index 9c1296cb0b..8cedc1a705 100755
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java
@@ -200,7 +200,7 @@ protected Chunk getAdjustedOutputs(Chunk inputs, Chunk outputs) {
}
@Override
- protected Chunk transform(final StepContribution contribution, Chunk inputs) throws Exception {
+ protected Chunk transform(StepContribution contribution, Chunk inputs) throws Exception {
Chunk outputs = new Chunk<>();
@SuppressWarnings("unchecked")
@@ -211,7 +211,7 @@ protected Chunk transform(final StepContribution contribution, Chunk input
// final int scanLimit = processorTransactional && data.scanning() ? 1 :
// 0;
- for (final Chunk.ChunkIterator iterator = inputs.iterator(); iterator.hasNext();) {
+ for (Chunk.ChunkIterator iterator = inputs.iterator(); iterator.hasNext();) {
final I item = iterator.next();
@@ -314,7 +314,7 @@ else if (shouldSkip(itemProcessSkipPolicy, e, contribution.getStepSkipCount()))
}
@Override
- protected void write(final StepContribution contribution, final Chunk inputs, final Chunk outputs)
+ protected void write(StepContribution contribution, final Chunk inputs, final Chunk outputs)
throws Exception {
@SuppressWarnings("unchecked")
final UserData data = (UserData) inputs.getUserData();
@@ -432,7 +432,7 @@ protected void write(final StepContribution contribution, final Chunk inputs,
}
- private void callSkipListeners(final Chunk inputs, final Chunk outputs) {
+ private void callSkipListeners(Chunk inputs, final Chunk outputs) {
for (SkipWrapper wrapper : inputs.getSkips()) {
I item = wrapper.getItem();
@@ -500,7 +500,7 @@ private Object getInputKey(I item) {
return keyGenerator.getKey(item);
}
- private List> getInputKeys(final Chunk inputs) {
+ private List> getInputKeys(Chunk inputs) {
if (keyGenerator == null) {
return inputs.getItems();
}
@@ -539,7 +539,7 @@ else if (e instanceof Error error) {
}
}
- private void scan(final StepContribution contribution, final Chunk inputs, final Chunk outputs,
+ private void scan(StepContribution contribution, final Chunk inputs, final Chunk outputs,
ChunkMonitor chunkMonitor, boolean recovery) throws Exception {
@SuppressWarnings("unchecked")
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProvider.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProvider.java
index 9a19c02848..1e733c2f69 100755
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProvider.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProvider.java
@@ -121,7 +121,7 @@ public void registerListener(StepListener listener) {
}
@Override
- public Chunk provide(final StepContribution contribution) throws Exception {
+ public Chunk provide(StepContribution contribution) throws Exception {
final Chunk inputs = new Chunk<>();
repeatOperations.iterate(context -> {
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/Tasklet.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/Tasklet.java
index 27b4fad4c6..dbbadf8276 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/Tasklet.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/Tasklet.java
@@ -44,7 +44,6 @@ public interface Tasklet {
* Returning {@code null} is interpreted as {@link RepeatStatus#FINISHED}
* @throws Exception thrown if error occurs during execution.
*/
- @Nullable
- RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception;
+ @Nullable RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception;
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java
index 6b5c01d85b..8bf8a34099 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java
@@ -476,7 +476,7 @@ private void rollback(StepExecution stepExecution) {
}
}
- private void copy(final StepExecution source, final StepExecution target) {
+ private void copy(StepExecution source, final StepExecution target) {
target.setVersion(source.getVersion());
target.setWriteCount(source.getWriteCount());
target.setFilterCount(source.getFilterCount());
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/StepLocatorStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/StepLocatorStepFactoryBeanTests.java
index db1a99fe3b..39651d67a4 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/StepLocatorStepFactoryBeanTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/StepLocatorStepFactoryBeanTests.java
@@ -46,7 +46,7 @@ void testFoo() throws Exception {
assertEquals(testStep2, stepLocatorStepFactoryBean.getObject());
}
- private Step buildTestStep(final String stepName) {
+ private Step buildTestStep(String stepName) {
return new Step() {
@Override
public String getName() {
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/skip/ReprocessExceptionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/skip/ReprocessExceptionTests.java
index 20bbf6e8dd..ef33c0d006 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/skip/ReprocessExceptionTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/skip/ReprocessExceptionTests.java
@@ -56,7 +56,7 @@ public static class PersonProcessor implements ItemProcessor {
private String mostRecentFirstName;
@Override
- public @Nullable Person process(final Person person) throws Exception {
+ public @Nullable Person process(Person person) throws Exception {
if (person.getFirstName().equals(mostRecentFirstName)) {
throw new RuntimeException("throwing a exception during process after a rollback");
}
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/StepExecutorInterruptionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/StepExecutorInterruptionTests.java
index 951e29a5a7..5a97653153 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/StepExecutorInterruptionTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/StepExecutorInterruptionTests.java
@@ -211,7 +211,7 @@ public void release() {
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
}
- private Thread createThread(final StepExecution stepExecution) {
+ private Thread createThread(StepExecution stepExecution) {
Thread processingThread = new Thread(() -> {
try {
jobRepository.add(stepExecution);
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/Chunk.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/Chunk.java
index c8347996db..a0c1beed23 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/Chunk.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/Chunk.java
@@ -16,6 +16,8 @@
package org.springframework.batch.item;
+import org.jspecify.annotations.Nullable;
+
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
@@ -34,6 +36,7 @@
* @author Dave Syer
* @author Mahmoud Ben Hassine
* @author Jinwoo Bae
+ * @author Stefano Cordio
* @since 2.0
*/
public class Chunk implements Iterable, Serializable {
@@ -44,7 +47,7 @@ public class Chunk implements Iterable, Serializable {
private final List errors = new ArrayList<>();
- private Object userData;
+ private @Nullable Object userData;
private boolean end;
@@ -64,8 +67,7 @@ public Chunk(List extends W> items) {
this(items, null);
}
- public Chunk(List extends W> items, List> skips) {
- super();
+ public Chunk(@Nullable List extends W> items, @Nullable List> skips) {
if (items != null) {
this.items.addAll(items);
}
@@ -200,7 +202,7 @@ public void clearSkips() {
skips.clear();
}
- public Object getUserData() {
+ public @Nullable Object getUserData() {
return userData;
}
@@ -247,9 +249,9 @@ public int hashCode() {
*/
public class ChunkIterator implements Iterator {
- final private Iterator iterator;
+ private final Iterator iterator;
- private W next;
+ private @Nullable W next;
public ChunkIterator(List items) {
iterator = items.iterator();
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java
index 7bb2ad7386..a9a3bb975b 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java
@@ -52,7 +52,6 @@ public interface ItemProcessor {
* processing of the provided item should not continue.
* @throws Exception thrown if exception occurs during processing.
*/
- @Nullable
- O process(I item) throws Exception;
+ @Nullable O process(I item) throws Exception;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemReader.java
index 5b07342dfe..a3cab2656e 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemReader.java
@@ -57,7 +57,6 @@ public interface ItemReader {
* @throws Exception if an there is a non-specific error.
* @return T the item to be processed or {@code null} if the data source is exhausted
*/
- @Nullable
- T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException;
+ @Nullable T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamException.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamException.java
index ef0e5af611..0dc3d7a72d 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamException.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamException.java
@@ -15,12 +15,15 @@
*/
package org.springframework.batch.item;
+import org.jspecify.annotations.Nullable;
+
/**
* Exception representing any errors encountered while processing a stream.
*
* @author Dave Syer
* @author Lucas Ward
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
public class ItemStreamException extends RuntimeException {
@@ -33,11 +36,10 @@ public ItemStreamException(String message) {
/**
* Constructs a new instance with a message and nested exception.
- * @param msg the exception message.
+ * @param msg the exception message (can be {@code null}).
* @param nested the cause of the exception.
- *
*/
- public ItemStreamException(String msg, Throwable nested) {
+ public ItemStreamException(@Nullable String msg, Throwable nested) {
super(msg, nested);
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamSupport.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamSupport.java
index 86446bc0ca..b3d246c9d6 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamSupport.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemStreamSupport.java
@@ -15,6 +15,7 @@
*/
package org.springframework.batch.item;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.util.ExecutionContextUserSupport;
/**
@@ -23,6 +24,7 @@
* @author Dave Syer
* @author Dean de Bree
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*
*/
public abstract class ItemStreamSupport implements ItemStream {
@@ -43,7 +45,7 @@ public void setName(String name) {
* Get the name of the component
* @return the name of the component
*/
- public String getName() {
+ public @Nullable String getName() {
return executionContextUserSupport.getName();
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/KeyValueItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/KeyValueItemWriter.java
index 6354fb1358..e72fec9994 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/KeyValueItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/KeyValueItemWriter.java
@@ -12,6 +12,7 @@
*/
package org.springframework.batch.item;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.Assert;
@@ -22,21 +23,20 @@
*
* @author David Turanski
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @since 2.2
*
*/
public abstract class KeyValueItemWriter implements ItemWriter, InitializingBean {
- protected Converter itemKeyMapper;
+ protected @Nullable Converter itemKeyMapper;
protected boolean delete;
@Override
- public void write(Chunk extends V> items) throws Exception {
- if (items == null) {
- return;
- }
- for (V item : items) {
+ public void write(Chunk extends V> chunk) throws Exception {
+ for (V item : chunk) {
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
K key = itemKeyMapper.convert(item);
writeKeyValue(key, item);
}
@@ -55,7 +55,7 @@ protected void flush() throws Exception {
* @param key the key
* @param value the item
*/
- protected abstract void writeKeyValue(K key, V value);
+ protected abstract void writeKeyValue(@Nullable K key, V value);
/**
* afterPropertiesSet() hook
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/PeekableItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/PeekableItemReader.java
index 5628e4fa58..088c6688b0 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/PeekableItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/PeekableItemReader.java
@@ -45,7 +45,6 @@ public interface PeekableItemReader extends ItemReader {
* @return the next item or {@code null} if the data source is exhausted
* @throws Exception if there is a problem
*/
- @Nullable
- T peek() throws Exception, UnexpectedInputException, ParseException;
+ @Nullable T peek() throws Exception, UnexpectedInputException, ParseException;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/SkipWrapper.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/SkipWrapper.java
index 7a8ebd30d3..1b9a02b959 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/SkipWrapper.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/SkipWrapper.java
@@ -23,13 +23,14 @@
*
* @author Dave Syer
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*
*/
public class SkipWrapper {
- final private Throwable exception;
+ private final @Nullable Throwable exception;
- final private T item;
+ private final @Nullable T item;
/**
* @param item the item being wrapped.
@@ -38,7 +39,7 @@ public SkipWrapper(T item) {
this(item, null);
}
- public SkipWrapper(T item, @Nullable Throwable e) {
+ public SkipWrapper(@Nullable T item, @Nullable Throwable e) {
this.item = item;
this.exception = e;
}
@@ -55,7 +56,7 @@ public SkipWrapper(T item, @Nullable Throwable e) {
* Public getter for the item.
* @return the item
*/
- public T getItem() {
+ public @Nullable T getItem() {
return item;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/SpELItemKeyMapper.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/SpELItemKeyMapper.java
index 13c4f49539..ac4a802ca1 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/SpELItemKeyMapper.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/SpELItemKeyMapper.java
@@ -12,30 +12,29 @@
*/
package org.springframework.batch.item;
+import org.jspecify.annotations.Nullable;
import org.springframework.core.convert.converter.Converter;
import org.springframework.expression.Expression;
-import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
/**
* An implementation of {@link Converter} that uses SpEL to map a Value to a key
*
* @author David Turanski
+ * @author Stefano Cordio
* @since 2.2
*/
public class SpELItemKeyMapper implements Converter {
- private final ExpressionParser parser = new SpelExpressionParser();
-
private final Expression parsedExpression;
public SpELItemKeyMapper(String keyExpression) {
- parsedExpression = parser.parseExpression(keyExpression);
+ parsedExpression = new SpelExpressionParser().parseExpression(keyExpression);
}
@SuppressWarnings("unchecked")
@Override
- public K convert(V item) {
+ public @Nullable K convert(V item) {
return (K) parsedExpression.getValue(item);
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/AbstractMethodInvokingDelegator.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/AbstractMethodInvokingDelegator.java
index 4a0665ab12..94f2a8d7aa 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/AbstractMethodInvokingDelegator.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/AbstractMethodInvokingDelegator.java
@@ -22,6 +22,7 @@
import java.util.Arrays;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -41,21 +42,22 @@
* @author Robert Kasanicky
* @author Mahmoud Ben Hassine
* @author Glenn Renfro
+ * @author Stefano Cordio
*/
public abstract class AbstractMethodInvokingDelegator implements InitializingBean {
- private Object targetObject;
+ private @Nullable Object targetObject;
- private String targetMethod;
+ private @Nullable String targetMethod;
- private Object[] arguments;
+ private @Nullable Object @Nullable [] arguments;
/**
* Invoker the target method with arguments set by {@link #setArguments(Object[])}.
* @return object returned by invoked method
* @throws Exception exception thrown when executing the delegate method.
*/
- protected T invokeDelegateMethod() throws Exception {
+ protected @Nullable T invokeDelegateMethod() throws Exception {
MethodInvoker invoker = createMethodInvoker(targetObject, targetMethod);
invoker.setArguments(arguments);
return doInvoke(invoker);
@@ -67,7 +69,7 @@ protected T invokeDelegateMethod() throws Exception {
* @return object returned by target method
* @throws Exception exception thrown when executing the delegate method.
*/
- protected T invokeDelegateMethodWithArgument(Object object) throws Exception {
+ protected @Nullable T invokeDelegateMethodWithArgument(Object object) throws Exception {
MethodInvoker invoker = createMethodInvoker(targetObject, targetMethod);
invoker.setArguments(object);
return doInvoke(invoker);
@@ -79,7 +81,7 @@ protected T invokeDelegateMethodWithArgument(Object object) throws Exception {
* @return object returned by invoked method
* @throws Exception exception thrown when executing the delegate method.
*/
- protected T invokeDelegateMethodWithArguments(Object[] args) throws Exception {
+ protected @Nullable T invokeDelegateMethodWithArguments(@Nullable Object[] args) throws Exception {
MethodInvoker invoker = createMethodInvoker(targetObject, targetMethod);
invoker.setArguments(args);
return doInvoke(invoker);
@@ -88,7 +90,7 @@ protected T invokeDelegateMethodWithArguments(Object[] args) throws Exception {
/**
* Create a new configured instance of {@link MethodInvoker}.
*/
- private MethodInvoker createMethodInvoker(Object targetObject, String targetMethod) {
+ private MethodInvoker createMethodInvoker(@Nullable Object targetObject, @Nullable String targetMethod) {
HippyMethodInvoker invoker = new HippyMethodInvoker();
invoker.setTargetObject(targetObject);
invoker.setTargetMethod(targetMethod);
@@ -102,7 +104,7 @@ private MethodInvoker createMethodInvoker(Object targetObject, String targetMeth
* @return return value of the invoked method
*/
@SuppressWarnings("unchecked")
- private T doInvoke(MethodInvoker invoker) throws Exception {
+ private @Nullable T doInvoke(MethodInvoker invoker) throws Exception {
try {
invoker.prepare();
}
@@ -141,6 +143,7 @@ public void afterPropertiesSet() throws Exception {
private boolean targetClassDeclaresTargetMethod() {
MethodInvoker invoker = createMethodInvoker(targetObject, targetMethod);
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
Method[] memberMethods = invoker.getTargetClass().getMethods();
Method[] declaredMethods = invoker.getTargetClass().getDeclaredMethods();
@@ -200,11 +203,11 @@ public void setTargetMethod(String targetMethod) {
* providing explicit argument values.
*
* If arguments are set to not-null value {@link #afterPropertiesSet()} will check the
- * values are compatible with target method's signature. In case arguments are null
- * (not set) method signature will not be checked and it is assumed correct values
- * will be supplied at runtime.
+ * values are compatible with target method's signature. In case arguments are
+ * {@code null} (not set), the method signature will not be checked, and it is assumed
+ * correct values will be supplied at runtime.
*/
- public void setArguments(Object[] arguments) {
+ public void setArguments(Object @Nullable [] arguments) {
this.arguments = arguments == null ? null : arguments.clone();
}
@@ -212,7 +215,7 @@ public void setArguments(Object[] arguments) {
* Return arguments.
* @return arguments
*/
- protected Object[] getArguments() {
+ protected @Nullable Object @Nullable [] getArguments() {
return arguments;
}
@@ -220,7 +223,7 @@ protected Object[] getArguments() {
* @return the object on which the method will be invoked.
* @since 5.1
*/
- protected Object getTargetObject() {
+ protected @Nullable Object getTargetObject() {
return targetObject;
}
@@ -228,7 +231,7 @@ protected Object getTargetObject() {
* @return the name of the method to be invoked.
* @since 5.1
*/
- protected String getTargetMethod() {
+ protected @Nullable String getTargetMethod() {
return targetMethod;
}
@@ -240,7 +243,7 @@ protected String getTargetMethod() {
*/
public static class InvocationTargetThrowableWrapper extends RuntimeException {
- public InvocationTargetThrowableWrapper(Throwable cause) {
+ public InvocationTargetThrowableWrapper(@Nullable Throwable cause) {
super(cause);
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/HippyMethodInvoker.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/HippyMethodInvoker.java
index 452c60ddcf..359807fb4c 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/HippyMethodInvoker.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/HippyMethodInvoker.java
@@ -17,14 +17,15 @@
import java.lang.reflect.Method;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.MethodInvoker;
import org.springframework.util.ReflectionUtils;
/**
* A {@link MethodInvoker} that is a bit relaxed about its arguments. You can give it
- * arguments in the wrong order or you can give it too many arguments and it will try and
- * find a method that matches a subset.
+ * arguments in the wrong order, or you can give it too many arguments, and it will try
+ * and find a method that matches a subset.
*
* @author Dave Syer
* @since 2.1
@@ -34,7 +35,8 @@ public class HippyMethodInvoker extends MethodInvoker {
@Override
protected Method findMatchingMethod() {
String targetMethod = getTargetMethod();
- Object[] arguments = getArguments();
+
+ @Nullable Object[] arguments = getArguments();
Method[] candidates = ReflectionUtils.getAllDeclaredMethods(getTargetClass());
int minTypeDiffWeight = Integer.MAX_VALUE;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemWriter.java
index ea1be22468..032d348451 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemWriter.java
@@ -16,8 +16,7 @@
package org.springframework.batch.item.adapter;
-import java.util.Arrays;
-
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.Chunk;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.BeanWrapper;
@@ -41,12 +40,13 @@
public class PropertyExtractingDelegatingItemWriter extends AbstractMethodInvokingDelegator
implements ItemWriter {
- private String[] fieldsUsedAsTargetMethodArguments;
+ private @Nullable String @Nullable [] fieldsUsedAsTargetMethodArguments;
/**
* Extracts values from item's fields named in fieldsUsedAsTargetMethodArguments and
* passes them as arguments to the delegate method.
*/
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
public void write(Chunk extends T> items) throws Exception {
for (T item : items) {
@@ -54,7 +54,8 @@ public void write(Chunk extends T> items) throws Exception {
// helper for extracting property values from a bean
BeanWrapper beanWrapper = new BeanWrapperImpl(item);
- Object[] methodArguments = new Object[fieldsUsedAsTargetMethodArguments.length];
+ @Nullable Object[] methodArguments = new Object[fieldsUsedAsTargetMethodArguments.length];
+
for (int i = 0; i < fieldsUsedAsTargetMethodArguments.length; i++) {
methodArguments[i] = beanWrapper.getPropertyValue(fieldsUsedAsTargetMethodArguments[i]);
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/AmqpItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/AmqpItemReader.java
index b902e10dd8..b1a33a0182 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/AmqpItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/AmqpItemReader.java
@@ -36,18 +36,19 @@
*
* @author Chris Schaefer
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
public class AmqpItemReader implements ItemReader {
private final AmqpTemplate amqpTemplate;
- private Class extends T> itemType;
+ private @Nullable Class extends T> itemType;
/**
* Initialize the AmqpItemReader.
* @param amqpTemplate the template to be used. Must not be null.
*/
- public AmqpItemReader(final AmqpTemplate amqpTemplate) {
+ public AmqpItemReader(AmqpTemplate amqpTemplate) {
Assert.notNull(amqpTemplate, "AmqpTemplate must not be null");
this.amqpTemplate = amqpTemplate;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/AmqpItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/AmqpItemWriter.java
index c825635cf8..1e591d7ee9 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/AmqpItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/AmqpItemWriter.java
@@ -45,14 +45,14 @@ public class AmqpItemWriter implements ItemWriter {
private final Log log = LogFactory.getLog(getClass());
- public AmqpItemWriter(final AmqpTemplate amqpTemplate) {
+ public AmqpItemWriter(AmqpTemplate amqpTemplate) {
Assert.notNull(amqpTemplate, "AmqpTemplate must not be null");
this.amqpTemplate = amqpTemplate;
}
@Override
- public void write(final Chunk extends T> items) throws Exception {
+ public void write(Chunk extends T> items) throws Exception {
if (log.isDebugEnabled()) {
log.debug("Writing to AMQP with " + items.size() + " items.");
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilder.java
index 6f1619ad79..03eda92a92 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilder.java
@@ -16,6 +16,7 @@
package org.springframework.batch.item.amqp.builder;
+import org.jspecify.annotations.Nullable;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.batch.item.amqp.AmqpItemReader;
import org.springframework.util.Assert;
@@ -24,14 +25,15 @@
* A builder implementation for the {@link AmqpItemReader}
*
* @author Glenn Renfro
+ * @author Stefano Cordio
* @since 4.0
* @see AmqpItemReader
*/
public class AmqpItemReaderBuilder {
- private AmqpTemplate amqpTemplate;
+ private @Nullable AmqpTemplate amqpTemplate;
- private Class extends T> itemType;
+ private @Nullable Class extends T> itemType;
/**
* Establish the amqpTemplate to be used by the AmqpItemReader.
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilder.java
index 979a6ad993..a349a54a8e 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilder.java
@@ -16,6 +16,7 @@
package org.springframework.batch.item.amqp.builder;
+import org.jspecify.annotations.Nullable;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.batch.item.amqp.AmqpItemWriter;
import org.springframework.util.Assert;
@@ -24,12 +25,13 @@
* A builder implementation for the {@link AmqpItemWriter}
*
* @author Glenn Renfro
+ * @author Stefano Cordio
* @since 4.0
* @see AmqpItemWriter
*/
public class AmqpItemWriterBuilder {
- private AmqpTemplate amqpTemplate;
+ private @Nullable AmqpTemplate amqpTemplate;
/**
* Establish the amqpTemplate to be used by the AmqpItemWriter.
@@ -50,9 +52,7 @@ public AmqpItemWriterBuilder amqpTemplate(AmqpTemplate amqpTemplate) {
public AmqpItemWriter build() {
Assert.notNull(this.amqpTemplate, "amqpTemplate is required.");
- AmqpItemWriter writer = new AmqpItemWriter<>(this.amqpTemplate);
-
- return writer;
+ return new AmqpItemWriter<>(this.amqpTemplate);
}
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/package-info.java
index 1144e23d27..573347cc1f 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/package-info.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/amqp/builder/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 the original author or authors.
+ * Copyright 2018-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
* @author Mahmoud Ben Hassine
* @author Stefano Cordio
*/
-
@NullMarked
package org.springframework.batch.item.amqp.builder;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemReader.java
index ced3f1b43a..4f887453da 100755
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemReader.java
@@ -54,9 +54,9 @@ public class AvroItemReader extends AbstractItemCountingItemStreamItemReader<
private boolean embeddedSchema = true;
- private InputStreamReader inputStreamReader;
+ private @Nullable InputStreamReader inputStreamReader;
- private DataFileStream dataFileReader;
+ private @Nullable DataFileStream dataFileReader;
private final InputStream inputStream;
@@ -104,12 +104,14 @@ public AvroItemReader(Resource data, Resource schema) {
/**
* Disable or enable reading an embedded Avro schema. True by default.
- * @param embeddedSchema set to false to if the input does not embed an Avro schema.
+ * @param embeddedSchema set to {@code false} if the input does not embed an Avro
+ * schema.
*/
public void setEmbeddedSchema(boolean embeddedSchema) {
this.embeddedSchema = embeddedSchema;
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
protected @Nullable T doRead() throws Exception {
if (this.inputStreamReader != null) {
@@ -123,6 +125,7 @@ protected void doOpen() throws Exception {
initializeReader();
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
protected void doClose() throws Exception {
if (this.inputStreamReader != null) {
@@ -170,7 +173,7 @@ private InputStreamReader(InputStream inputStream, DatumReader datumReader) {
this.binaryDecoder = DecoderFactory.get().binaryDecoder(inputStream, null);
}
- private T read() throws Exception {
+ private @Nullable T read() throws Exception {
if (!this.binaryDecoder.isEnd()) {
return this.datumReader.read(null, this.binaryDecoder);
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemWriter.java
index 99a63b04bf..16d80d827c 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemWriter.java
@@ -30,6 +30,7 @@
import org.apache.avro.specific.SpecificDatumWriter;
import org.apache.avro.specific.SpecificRecordBase;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.Chunk;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
@@ -54,13 +55,13 @@
*/
public class AvroItemWriter extends AbstractItemStreamItemWriter {
- private DataFileWriter dataFileWriter;
+ private @Nullable DataFileWriter dataFileWriter;
- private OutputStreamWriter outputStreamWriter;
+ private @Nullable OutputStreamWriter outputStreamWriter;
private final WritableResource resource;
- private final Resource schemaResource;
+ private final @Nullable Resource schemaResource;
private final Class clazz;
@@ -71,7 +72,7 @@ public class AvroItemWriter extends AbstractItemStreamItemWriter {
* @param schema a {@link Resource} containing the Avro schema.
* @param clazz the data type to be serialized.
*/
- public AvroItemWriter(WritableResource resource, Resource schema, Class clazz) {
+ public AvroItemWriter(WritableResource resource, @Nullable Resource schema, Class clazz) {
this.schemaResource = schema;
this.resource = resource;
this.clazz = clazz;
@@ -87,6 +88,7 @@ public AvroItemWriter(WritableResource resource, Class clazz) {
embedSchema = false;
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
public void write(Chunk extends T> items) throws Exception {
items.forEach(item -> {
@@ -118,6 +120,7 @@ public void open(ExecutionContext executionContext) {
}
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
public void close() {
try {
@@ -155,7 +158,6 @@ private void initializeWriter() throws IOException {
this.outputStreamWriter = createOutputStreamWriter(this.resource.getOutputStream(),
datumWriterForClass(this.clazz));
}
-
}
private static DatumWriter datumWriterForClass(Class clazz) {
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/AvroItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/AvroItemReaderBuilder.java
index c9803e2590..eab6ee661e 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/AvroItemReaderBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/AvroItemReaderBuilder.java
@@ -18,6 +18,7 @@
import org.apache.avro.Schema;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.avro.AvroItemReader;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
@@ -29,6 +30,7 @@
*
* @author David Turanski
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @since 4.2
*/
public class AvroItemReaderBuilder {
@@ -41,11 +43,11 @@ public class AvroItemReaderBuilder {
private int currentItemCount;
- private Resource schema;
+ private @Nullable Resource schema;
- private Resource resource;
+ private @Nullable Resource resource;
- private Class type;
+ private @Nullable Class type;
private boolean embeddedSchema = true;
@@ -162,10 +164,12 @@ public AvroItemReader build() {
Assert.notNull(this.resource, "A 'resource' is required.");
if (this.type != null) {
- avroItemReader = buildForType();
+ Assert.isNull(this.schema, "You cannot specify a schema and 'type'.");
+ avroItemReader = new AvroItemReader<>(this.resource, this.type);
}
else {
- avroItemReader = buildForSchema();
+ Assert.notNull(this.schema, "'schema' is required.");
+ avroItemReader = new AvroItemReader<>(this.resource, this.schema);
}
avroItemReader.setSaveState(this.saveState);
@@ -182,14 +186,4 @@ public AvroItemReader build() {
return avroItemReader;
}
- private AvroItemReader buildForType() {
- Assert.isNull(this.schema, "You cannot specify a schema and 'type'.");
- return new AvroItemReader<>(this.resource, this.type);
- }
-
- private AvroItemReader buildForSchema() {
- Assert.notNull(this.schema, "'schema' is required.");
- return new AvroItemReader<>(this.resource, this.schema);
- }
-
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/AvroItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/AvroItemWriterBuilder.java
index 69c9eb85cc..7bd72ba3c8 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/AvroItemWriterBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/AvroItemWriterBuilder.java
@@ -16,6 +16,7 @@
package org.springframework.batch.item.avro.builder;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.avro.AvroItemWriter;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
@@ -27,15 +28,16 @@
*
* @author David Turanski
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @since 4.2
*/
public class AvroItemWriterBuilder {
- private Class type;
+ private @Nullable Class type;
- private WritableResource resource;
+ private @Nullable WritableResource resource;
- private Resource schema;
+ private @Nullable Resource schema;
private String name = AvroItemWriter.class.getSimpleName();
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/package-info.java
new file mode 100644
index 0000000000..a24fd63cab
--- /dev/null
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/builder/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Builders for Avro item reader and writer.
+ *
+ * @author Stefano Cordio
+ */
+@NullMarked
+package org.springframework.batch.item.avro.builder;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/package-info.java
new file mode 100644
index 0000000000..78781b2c36
--- /dev/null
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * Avro related reader and writer.
+ *
+ * @author Stefano Cordio
+ */
+@NullMarked
+package org.springframework.batch.item.avro;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractPaginatedDataItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractPaginatedDataItemReader.java
index e3fb43c500..eca601e1ad 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractPaginatedDataItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractPaginatedDataItemReader.java
@@ -36,6 +36,7 @@
* @author Michael Minella
* @author Glenn Renfro
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @since 2.2
* @param Type of item to be read
*/
@@ -45,7 +46,7 @@ public abstract class AbstractPaginatedDataItemReader extends AbstractItemCou
protected int pageSize = 10;
- protected Iterator results;
+ protected @Nullable Iterator results;
private final Lock lock = new ReentrantLock();
@@ -69,17 +70,12 @@ public void setPageSize(int pageSize) {
page++;
- if (results == null || !results.hasNext()) {
+ if (!results.hasNext()) {
return null;
}
}
- if (results.hasNext()) {
- return results.next();
- }
- else {
- return null;
- }
+ return results.next();
}
finally {
this.lock.unlock();
@@ -91,8 +87,8 @@ public void setPageSize(int pageSize) {
* page. Each time this method is called, the resulting {@link Iterator} should
* contain the items read within the next page.
*
- * If the {@link Iterator} is empty or null when it is returned, this
- * {@link ItemReader} will assume that the input has been exhausted.
+ * If the {@link Iterator} is empty when it is returned, this {@link ItemReader} will
+ * assume that the input has been exhausted.
* @return an {@link Iterator} containing the items within a page.
*/
protected abstract Iterator doPageRead();
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoCursorItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoCursorItemReader.java
index 1759557d61..5fbfc5d3ed 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoCursorItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoCursorItemReader.java
@@ -25,6 +25,7 @@
import org.bson.Document;
import org.bson.codecs.DecoderContext;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader;
import org.springframework.beans.factory.InitializingBean;
@@ -48,37 +49,36 @@
*/
public class MongoCursorItemReader extends AbstractItemCountingItemStreamItemReader implements InitializingBean {
- private MongoOperations template;
+ private @Nullable MongoOperations template;
- private Class extends T> targetType;
+ private @Nullable Class extends T> targetType;
- private String collection;
+ private @Nullable String collection;
- private Query query;
+ private @Nullable Query query;
- private String queryString;
+ private @Nullable String queryString;
private List parameterValues = new ArrayList<>();
- private String fields;
+ private @Nullable String fields;
- private Sort sort;
+ private @Nullable Sort sort;
- private String hint;
+ private @Nullable String hint;
private int batchSize;
private int limit;
- private Duration maxTime;
+ private @Nullable Duration maxTime;
- private CloseableIterator extends T> cursor;
+ private @Nullable CloseableIterator extends T> cursor;
/**
* Create a new {@link MongoCursorItemReader}.
*/
public MongoCursorItemReader() {
- super();
setName(ClassUtils.getShortName(MongoCursorItemReader.class));
}
@@ -206,15 +206,10 @@ public void afterPropertiesSet() {
}
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
protected void doOpen() throws Exception {
- Query mongoQuery;
- if (queryString != null) {
- mongoQuery = createQuery();
- }
- else {
- mongoQuery = query;
- }
+ Query mongoQuery = queryString != null ? createQuery() : query;
Stream extends T> stream;
if (StringUtils.hasText(collection)) {
@@ -227,27 +222,8 @@ protected void doOpen() throws Exception {
this.cursor = streamToIterator(stream);
}
- @Override
- protected T doRead() throws Exception {
- return cursor.hasNext() ? cursor.next() : null;
- }
-
- @Override
- protected void doClose() throws Exception {
- this.cursor.close();
- }
-
- private Sort convertToSort(Map sorts) {
- List sortValues = new ArrayList<>(sorts.size());
-
- for (Map.Entry curSort : sorts.entrySet()) {
- sortValues.add(new Sort.Order(curSort.getValue(), curSort.getKey()));
- }
-
- return Sort.by(sortValues);
- }
-
private Query createQuery() {
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
String populatedQuery = replacePlaceholders(queryString, parameterValues);
Query mongoQuery;
@@ -276,6 +252,28 @@ private Query createQuery() {
return mongoQuery;
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
+ @Override
+ protected T doRead() throws Exception {
+ return cursor.hasNext() ? cursor.next() : null;
+ }
+
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
+ @Override
+ protected void doClose() throws Exception {
+ this.cursor.close();
+ }
+
+ private Sort convertToSort(Map sorts) {
+ List sortValues = new ArrayList<>(sorts.size());
+
+ for (Map.Entry curSort : sorts.entrySet()) {
+ sortValues.add(new Sort.Order(curSort.getValue(), curSort.getKey()));
+ }
+
+ return Sort.by(sortValues);
+ }
+
private String replacePlaceholders(String input, List values) {
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(input, values.toArray());
DecoderContext decoderContext = DecoderContext.builder().build();
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java
index 9bef3011f3..6c0ec9024d 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java
@@ -53,6 +53,7 @@
* @author Michael Minella
* @author Parikshit Dutta
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*
*/
public class MongoItemWriter implements ItemWriter, InitializingBean {
@@ -84,11 +85,11 @@ public enum Mode {
private static final String ID_KEY = "_id";
- private MongoOperations template;
+ private @Nullable MongoOperations template;
private final Object bufferKey;
- private String collection;
+ private @Nullable String collection;
private Mode mode = Mode.UPSERT;
@@ -103,7 +104,7 @@ public MongoItemWriter() {
* @param mode the mode to be used.
* @since 5.1
*/
- public void setMode(final Mode mode) {
+ public void setMode(Mode mode) {
this.mode = mode;
}
@@ -129,7 +130,7 @@ public void setTemplate(MongoOperations template) {
* called by a subclass if necessary.
* @return template the template implementation to be used.
*/
- protected MongoOperations getTemplate() {
+ protected @Nullable MongoOperations getTemplate() {
return template;
}
@@ -137,7 +138,7 @@ protected MongoOperations getTemplate() {
* Set the name of the Mongo collection to be written to.
* @param collection the name of the collection.
*/
- public void setCollection(String collection) {
+ public void setCollection(@Nullable String collection) {
this.collection = collection;
}
@@ -146,7 +147,7 @@ public void setCollection(String collection) {
* @return the collection name
* @since 5.1
*/
- public String getCollection() {
+ public @Nullable String getCollection() {
return collection;
}
@@ -165,7 +166,9 @@ public void write(Chunk extends T> chunk) throws Exception {
}
Chunk bufferedItems = getCurrentBuffer();
- bufferedItems.addAll(chunk.getItems());
+ if (bufferedItems != null) {
+ bufferedItems.addAll(chunk.getItems());
+ }
}
/**
@@ -183,11 +186,12 @@ protected void doWrite(Chunk extends T> chunk) {
}
}
- private void insert(final Chunk extends T> chunk) {
- final BulkOperations bulkOperations = initBulkOperations(BulkMode.ORDERED, chunk.getItems().get(0));
- final MongoConverter mongoConverter = this.template.getConverter();
- for (final Object item : chunk) {
- final Document document = new Document();
+ private void insert(Chunk extends T> chunk) {
+ BulkOperations bulkOperations = initBulkOperations(chunk.getItems().get(0));
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
+ MongoConverter mongoConverter = this.template.getConverter();
+ for (Object item : chunk) {
+ Document document = new Document();
mongoConverter.write(item, document);
bulkOperations.insert(document);
}
@@ -195,7 +199,8 @@ private void insert(final Chunk extends T> chunk) {
}
private void remove(Chunk extends T> chunk) {
- BulkOperations bulkOperations = initBulkOperations(BulkMode.ORDERED, chunk.getItems().get(0));
+ BulkOperations bulkOperations = initBulkOperations(chunk.getItems().get(0));
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
MongoConverter mongoConverter = this.template.getConverter();
for (Object item : chunk) {
Document document = new Document();
@@ -210,7 +215,8 @@ private void remove(Chunk extends T> chunk) {
}
private void upsert(Chunk extends T> chunk) {
- BulkOperations bulkOperations = initBulkOperations(BulkMode.ORDERED, chunk.getItems().get(0));
+ BulkOperations bulkOperations = initBulkOperations(chunk.getItems().get(0));
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
MongoConverter mongoConverter = this.template.getConverter();
FindAndReplaceOptions upsert = new FindAndReplaceOptions().upsert();
for (Object item : chunk) {
@@ -223,15 +229,11 @@ private void upsert(Chunk extends T> chunk) {
bulkOperations.execute();
}
- private BulkOperations initBulkOperations(BulkMode bulkMode, Object item) {
- BulkOperations bulkOperations;
- if (StringUtils.hasText(this.collection)) {
- bulkOperations = this.template.bulkOps(bulkMode, this.collection);
- }
- else {
- bulkOperations = this.template.bulkOps(bulkMode, ClassUtils.getUserClass(item));
- }
- return bulkOperations;
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
+ private BulkOperations initBulkOperations(Object item) {
+ return StringUtils.hasText(this.collection) //
+ ? this.template.bulkOps(BulkMode.ORDERED, this.collection)
+ : this.template.bulkOps(BulkMode.ORDERED, ClassUtils.getUserClass(item));
}
private boolean transactionActive() {
@@ -248,7 +250,7 @@ private boolean transactionActive() {
public void beforeCommit(boolean readOnly) {
Chunk chunk = (Chunk) TransactionSynchronizationManager.getResource(bufferKey);
- if (!chunk.isEmpty()) {
+ if (chunk != null && !chunk.isEmpty()) {
if (!readOnly) {
doWrite(chunk);
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoPagingItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoPagingItemReader.java
index e9e8ff83d0..b9ae3ba2de 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoPagingItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoPagingItemReader.java
@@ -22,6 +22,7 @@
import org.bson.Document;
import org.bson.codecs.DecoderContext;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.InitializingBean;
@@ -80,26 +81,25 @@
*/
public class MongoPagingItemReader extends AbstractPaginatedDataItemReader implements InitializingBean {
- protected MongoOperations template;
+ protected @Nullable MongoOperations template;
- protected Query query;
+ protected @Nullable Query query;
- protected String queryString;
+ protected @Nullable String queryString;
- protected Class extends T> type;
+ protected @Nullable Class extends T> type;
- protected Sort sort;
+ protected @Nullable Sort sort;
- protected String hint;
+ protected @Nullable String hint;
- protected String fields;
+ protected @Nullable String fields;
- protected String collection;
+ protected @Nullable String collection;
protected List parameterValues = new ArrayList<>();
public MongoPagingItemReader() {
- super();
setName(ClassUtils.getShortName(MongoPagingItemReader.class));
}
@@ -183,8 +183,8 @@ public void setHint(String hint) {
this.hint = hint;
}
+ @SuppressWarnings({ "unchecked", "DataFlowIssue", "NullAway" })
@Override
- @SuppressWarnings("unchecked")
protected Iterator doPageRead() {
if (queryString != null) {
Pageable pageRequest = PageRequest.of(page, pageSize, sort);
@@ -206,24 +206,18 @@ protected Iterator doPageRead() {
mongoQuery.withHint(hint);
}
- if (StringUtils.hasText(collection)) {
- return (Iterator) template.find(mongoQuery, type, collection).iterator();
- }
- else {
- return (Iterator) template.find(mongoQuery, type).iterator();
- }
+ return StringUtils.hasText(collection) //
+ ? (Iterator) template.find(mongoQuery, type, collection).iterator()
+ : (Iterator) template.find(mongoQuery, type).iterator();
}
else {
Pageable pageRequest = PageRequest.of(page, pageSize);
query.with(pageRequest);
- if (StringUtils.hasText(collection)) {
- return (Iterator) template.find(query, type, collection).iterator();
- }
- else {
- return (Iterator) template.find(query, type).iterator();
- }
+ return StringUtils.hasText(collection) //
+ ? (Iterator) template.find(query, type, collection).iterator()
+ : (Iterator) template.find(query, type).iterator();
}
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java
index 8e658bf392..ee6785c05b 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemReader.java
@@ -85,9 +85,9 @@ public class RepositoryItemReader extends AbstractItemCountingItemStreamItemR
protected Log logger = LogFactory.getLog(getClass());
- private PagingAndSortingRepository, ?> repository;
+ private @Nullable PagingAndSortingRepository, ?> repository;
- private Sort sort;
+ private @Nullable Sort sort;
private volatile int page = 0;
@@ -95,13 +95,13 @@ public class RepositoryItemReader extends AbstractItemCountingItemStreamItemR
private volatile int current = 0;
- private List> arguments;
+ private @Nullable List> arguments;
- private volatile List results;
+ private volatile @Nullable List results;
private final Lock lock = new ReentrantLock();
- private String methodName;
+ private @Nullable String methodName;
public RepositoryItemReader() {
setName(ClassUtils.getShortName(RepositoryItemReader.class));
@@ -220,8 +220,10 @@ protected void jumpToItem(int itemLastIndex) throws Exception {
*/
@SuppressWarnings("unchecked")
protected List doPageRead() throws Exception {
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
Pageable pageRequest = PageRequest.of(page, pageSize, sort);
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
MethodInvoker invoker = createMethodInvoker(repository, methodName);
List parameters = new ArrayList<>();
@@ -266,6 +268,7 @@ private Sort convertToSort(Map sorts) {
return Sort.by(sortValues);
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
private Object doInvoke(MethodInvoker invoker) throws Exception {
try {
invoker.prepare();
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemWriter.java
index 996bdf5fd3..0e482872cb 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemWriter.java
@@ -20,6 +20,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.Chunk;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.adapter.AbstractMethodInvokingDelegator.InvocationTargetThrowableWrapper;
@@ -63,9 +64,9 @@ public class RepositoryItemWriter implements ItemWriter, InitializingBean
protected static final Log logger = LogFactory.getLog(RepositoryItemWriter.class);
- private CrudRepository repository;
+ private @Nullable CrudRepository repository;
- private String methodName;
+ private @Nullable String methodName;
/**
* Specifies what method on the repository to call. This method must have the type of
@@ -103,6 +104,7 @@ public void write(Chunk extends T> chunk) throws Exception {
* @param items the list of items to be persisted.
* @throws Exception thrown if error occurs during writing.
*/
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
protected void doWrite(Chunk extends T> items) throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("Writing to the repository with " + items.size() + " items.");
@@ -135,7 +137,7 @@ public void afterPropertiesSet() throws Exception {
}
}
- private Object doInvoke(MethodInvoker invoker) throws Exception {
+ private void doInvoke(MethodInvoker invoker) throws Exception {
try {
invoker.prepare();
}
@@ -144,7 +146,7 @@ private Object doInvoke(MethodInvoker invoker) throws Exception {
}
try {
- return invoker.invoke();
+ invoker.invoke();
}
catch (InvocationTargetException e) {
if (e.getCause() instanceof Exception) {
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoCursorItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoCursorItemReaderBuilder.java
index b7c09835b7..349f314693 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoCursorItemReaderBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoCursorItemReaderBuilder.java
@@ -21,6 +21,7 @@
import java.util.List;
import java.util.Map;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.data.MongoCursorItemReader;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoOperations;
@@ -31,6 +32,7 @@
/**
* @author LEE Juchan
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @since 5.1
* @see MongoCursorItemReader
*/
@@ -38,35 +40,35 @@ public class MongoCursorItemReaderBuilder {
private boolean saveState = true;
- private String name;
+ private @Nullable String name;
private int maxItemCount = Integer.MAX_VALUE;
private int currentItemCount;
- private MongoOperations template;
+ private @Nullable MongoOperations template;
- private Class extends T> targetType;
+ private @Nullable Class extends T> targetType;
- private String collection;
+ private @Nullable String collection;
- private Query query;
+ private @Nullable Query query;
- private String jsonQuery;
+ private @Nullable String jsonQuery;
private List parameterValues = new ArrayList<>();
- private String fields;
+ private @Nullable String fields;
- private Map sorts;
+ private @Nullable Map sorts;
- private String hint;
+ private @Nullable String hint;
private int batchSize;
private int limit;
- private Duration maxTime;
+ private @Nullable Duration maxTime;
/**
* Configure if the state of the
@@ -285,25 +287,38 @@ public MongoCursorItemReader build() {
}
MongoCursorItemReader reader = new MongoCursorItemReader<>();
+
+ if (this.name != null) {
+ reader.setName(this.name);
+ }
+ if (this.collection != null) {
+ reader.setCollection(this.collection);
+ }
+ if (this.query != null) {
+ reader.setQuery(this.query);
+ }
+ if (this.fields != null) {
+ reader.setFields(this.fields);
+ }
+ if (this.sorts != null) {
+ reader.setSort(this.sorts);
+ }
+ if (this.hint != null) {
+ reader.setHint(this.hint);
+ }
+ if (this.maxTime != null) {
+ reader.setMaxTime(this.maxTime);
+ }
+
reader.setSaveState(this.saveState);
- reader.setName(this.name);
reader.setCurrentItemCount(this.currentItemCount);
reader.setMaxItemCount(this.maxItemCount);
-
reader.setTemplate(this.template);
reader.setTargetType(this.targetType);
- reader.setCollection(this.collection);
- reader.setQuery(this.query);
reader.setQuery(this.jsonQuery);
reader.setParameterValues(this.parameterValues);
- reader.setFields(this.fields);
- reader.setSort(this.sorts);
- reader.setHint(this.hint);
reader.setBatchSize(this.batchSize);
reader.setLimit(this.limit);
- if (this.maxTime != null) {
- reader.setMaxTime(this.maxTime);
- }
return reader;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilder.java
index e2cfdcdb48..e95dcba8a1 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoItemWriterBuilder.java
@@ -16,6 +16,7 @@
package org.springframework.batch.item.data.builder;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.data.MongoItemWriter;
import org.springframework.batch.item.data.MongoItemWriter.Mode;
import org.springframework.data.mongodb.core.MongoOperations;
@@ -31,9 +32,9 @@
*/
public class MongoItemWriterBuilder {
- private MongoOperations template;
+ private @Nullable MongoOperations template;
- private String collection;
+ private @Nullable String collection;
private Mode mode = Mode.UPSERT;
@@ -45,7 +46,7 @@ public class MongoItemWriterBuilder {
* @see MongoItemWriter#setMode(Mode)
* @since 5.1
*/
- public MongoItemWriterBuilder mode(final Mode mode) {
+ public MongoItemWriterBuilder mode(Mode mode) {
this.mode = mode;
return this;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoPagingItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoPagingItemReaderBuilder.java
index 480b3a7c92..64fad91bd9 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoPagingItemReaderBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/MongoPagingItemReaderBuilder.java
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.Map;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.data.MongoPagingItemReader;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoOperations;
@@ -35,23 +36,24 @@
* @author Mahmoud Ben Hassine
* @author Drummond Dawson
* @author Parikshit Dutta
+ * @author Stefano Cordio
* @since 5.1
*/
public class MongoPagingItemReaderBuilder {
- protected MongoOperations template;
+ protected @Nullable MongoOperations template;
- protected String jsonQuery;
+ protected @Nullable String jsonQuery;
- protected Class extends T> targetType;
+ protected @Nullable Class extends T> targetType;
- protected Map sorts;
+ protected @Nullable Map sorts;
- protected String hint;
+ protected @Nullable String hint;
- protected String fields;
+ protected @Nullable String fields;
- protected String collection;
+ protected @Nullable String collection;
protected List parameterValues = new ArrayList<>();
@@ -59,13 +61,13 @@ public class MongoPagingItemReaderBuilder {
protected boolean saveState = true;
- protected String name;
+ protected @Nullable String name;
protected int maxItemCount = Integer.MAX_VALUE;
protected int currentItemCount;
- protected Query query;
+ protected @Nullable Query query;
/**
* Configure if the state of the
@@ -270,18 +272,31 @@ public MongoPagingItemReader build() {
}
MongoPagingItemReader reader = new MongoPagingItemReader<>();
+
+ if (this.sorts != null) {
+ reader.setSort(this.sorts);
+ }
+ if (this.hint != null) {
+ reader.setHint(this.hint);
+ }
+ if (this.fields != null) {
+ reader.setFields(this.fields);
+ }
+ if (this.collection != null) {
+ reader.setCollection(this.collection);
+ }
+ if (this.query != null) {
+ reader.setQuery(this.query);
+ }
+ if (this.name != null) {
+ reader.setName(this.name);
+ }
+
reader.setTemplate(this.template);
reader.setTargetType(this.targetType);
reader.setQuery(this.jsonQuery);
- reader.setSort(this.sorts);
- reader.setHint(this.hint);
- reader.setFields(this.fields);
- reader.setCollection(this.collection);
reader.setParameterValues(this.parameterValues);
- reader.setQuery(this.query);
-
reader.setPageSize(this.pageSize);
- reader.setName(this.name);
reader.setSaveState(this.saveState);
reader.setCurrentItemCount(this.currentItemCount);
reader.setMaxItemCount(this.maxItemCount);
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java
index 8b51679673..27b052403b 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.Map;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.data.RepositoryItemReader;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.PagingAndSortingRepository;
@@ -37,19 +38,19 @@
*/
public class RepositoryItemReaderBuilder {
- private PagingAndSortingRepository, ?> repository;
+ private @Nullable PagingAndSortingRepository, ?> repository;
- private Map sorts;
+ private @Nullable Map sorts;
- private List> arguments;
+ private @Nullable List> arguments;
private int pageSize = 10;
- private String methodName;
+ private @Nullable String methodName;
private boolean saveState = true;
- private String name;
+ private @Nullable String name;
private int maxItemCount = Integer.MAX_VALUE;
@@ -194,7 +195,9 @@ public RepositoryItemReader build() {
}
RepositoryItemReader reader = new RepositoryItemReader<>();
- reader.setArguments(this.arguments);
+ if (this.arguments != null) {
+ reader.setArguments(this.arguments);
+ }
reader.setRepository(this.repository);
reader.setMethodName(this.methodName);
reader.setPageSize(this.pageSize);
@@ -202,7 +205,9 @@ public RepositoryItemReader build() {
reader.setMaxItemCount(this.maxItemCount);
reader.setSaveState(this.saveState);
reader.setSort(this.sorts);
- reader.setName(this.name);
+ if (this.name != null) {
+ reader.setName(this.name);
+ }
return reader;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemWriterBuilder.java
index aa33c6a7cc..f6fa402f48 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemWriterBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemWriterBuilder.java
@@ -41,11 +41,11 @@ public class RepositoryItemWriterBuilder {
private static final Log logger = LogFactory.getLog(RepositoryItemWriterBuilder.class.getName());
- private CrudRepository repository;
+ private @Nullable CrudRepository repository;
- private String methodName;
+ private @Nullable String methodName;
- private RepositoryMethodReference repositoryMethodReference;
+ private @Nullable RepositoryMethodReference repositoryMethodReference;
/**
* Specifies what method on the repository to call. This method must have the type of
@@ -164,16 +164,15 @@ String getMethodName() {
private static class RepositoryMethodInterceptor implements MethodInterceptor {
- private String methodName;
+ private @Nullable String methodName;
@Override
- public @Nullable Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
- throws Throwable {
+ public @Nullable Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) {
this.methodName = method.getName();
return null;
}
- String getMethodName() {
+ @Nullable String getMethodName() {
return this.methodName;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractCursorItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractCursorItemReader.java
index a6444f41fc..2f384a8a00 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractCursorItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractCursorItemReader.java
@@ -54,10 +54,10 @@
*
*
*
- * By default the cursor will be opened using a separate connection. The ResultSet for the
- * cursor is held open regardless of commits or roll backs in a surrounding transaction.
- * Clients of this reader are responsible for buffering the items in the case that they
- * need to be re-presented on a rollback. This buffering is handled by the step
+ * By default, the cursor will be opened using a separate connection. The ResultSet for
+ * the cursor is held open regardless of commits or rollbacks in a surrounding
+ * transaction. Clients of this reader are responsible for buffering the items in the case
+ * that they need to be re-presented on a rollback. This buffering is handled by the step
* implementations provided and is only a concern for anyone writing their own step
* implementations.
*
@@ -112,6 +112,7 @@
* @author Thomas Risberg
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
public abstract class AbstractCursorItemReader extends AbstractItemCountingItemStreamItemReader
implements InitializingBean {
@@ -121,11 +122,11 @@ public abstract class AbstractCursorItemReader extends AbstractItemCountingIt
public static final int VALUE_NOT_SET = -1;
- private Connection con;
+ private @Nullable Connection con;
- protected ResultSet rs;
+ protected @Nullable ResultSet rs;
- private DataSource dataSource;
+ private @Nullable DataSource dataSource;
private int fetchSize = VALUE_NOT_SET;
@@ -137,7 +138,7 @@ public abstract class AbstractCursorItemReader extends AbstractItemCountingIt
private boolean verifyCursorPosition = true;
- private SQLExceptionTranslator exceptionTranslator;
+ private @Nullable SQLExceptionTranslator exceptionTranslator;
private boolean initialized = false;
@@ -145,14 +146,10 @@ public abstract class AbstractCursorItemReader extends AbstractItemCountingIt
private boolean useSharedExtendedConnection = false;
- private Boolean connectionAutoCommit;
+ private @Nullable Boolean connectionAutoCommit;
private boolean initialConnectionAutoCommit;
- public AbstractCursorItemReader() {
- super();
- }
-
/**
* Assert that mandatory properties are set.
* @throws IllegalArgumentException if either data source or SQL properties not set.
@@ -174,7 +171,7 @@ public void setDataSource(DataSource dataSource) {
* Public getter for the data source.
* @return the dataSource
*/
- public DataSource getDataSource() {
+ public @Nullable DataSource getDataSource() {
return this.dataSource;
}
@@ -372,7 +369,7 @@ public void setConnectionAutoCommit(boolean autoCommit) {
this.connectionAutoCommit = autoCommit;
}
- public abstract String getSql();
+ public abstract @Nullable String getSql();
/**
* Check the result set is in sync with the currentRow attribute. This is important to
@@ -424,14 +421,13 @@ protected void doClose() throws Exception {
*/
@Override
protected void doOpen() throws Exception {
-
Assert.state(!initialized, "Stream is already initialized. Close before re-opening.");
Assert.isNull(rs, "ResultSet still open! Close before re-opening.");
initializeConnection();
+ // noinspection DataFlowIssue
openCursor(con);
initialized = true;
-
}
protected void initializeConnection() {
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractPagingItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractPagingItemReader.java
index 71d9ddb9c4..c66bb35bde 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractPagingItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractPagingItemReader.java
@@ -44,6 +44,7 @@
* @author Thomas Risberg
* @author Dave Syer
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @since 2.0
*/
public abstract class AbstractPagingItemReader extends AbstractItemCountingItemStreamItemReader
@@ -59,7 +60,7 @@ public abstract class AbstractPagingItemReader extends AbstractItemCountingIt
private volatile int page = 0;
- protected volatile List results;
+ protected volatile @Nullable List results;
private final Lock lock = new ReentrantLock();
@@ -100,6 +101,7 @@ public void afterPropertiesSet() throws Exception {
Assert.state(pageSize > 0, "pageSize must be greater than zero");
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
protected @Nullable T doRead() throws Exception {
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcBatchItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcBatchItemWriter.java
index be5d04eeb3..cba7d381c8 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcBatchItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcBatchItemWriter.java
@@ -23,6 +23,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.Chunk;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.InitializingBean;
@@ -58,19 +59,20 @@
* @author Thomas Risberg
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @since 2.0
*/
public class JdbcBatchItemWriter implements ItemWriter, InitializingBean {
protected static final Log logger = LogFactory.getLog(JdbcBatchItemWriter.class);
- protected NamedParameterJdbcOperations namedParameterJdbcTemplate;
+ protected @Nullable NamedParameterJdbcOperations namedParameterJdbcTemplate;
- protected ItemPreparedStatementSetter itemPreparedStatementSetter;
+ protected @Nullable ItemPreparedStatementSetter itemPreparedStatementSetter;
- protected ItemSqlParameterSourceProvider itemSqlParameterSourceProvider;
+ protected @Nullable ItemSqlParameterSourceProvider itemSqlParameterSourceProvider;
- protected String sql;
+ protected @Nullable String sql;
protected boolean assertUpdates = true;
@@ -143,7 +145,7 @@ public void afterPropertiesSet() {
Assert.state(sql != null, "An SQL statement is required.");
List namedParameters = new ArrayList<>();
parameterCount = JdbcParameterUtils.countParameterPlaceholders(sql, namedParameters);
- if (namedParameters.size() > 0) {
+ if (!namedParameters.isEmpty()) {
if (parameterCount != namedParameters.size()) {
throw new InvalidDataAccessApiUsageException(
"You can't use both named parameters and classic \"?\" placeholders: " + sql);
@@ -156,9 +158,9 @@ public void afterPropertiesSet() {
}
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({ "unchecked", "DataFlowIssue", "NullAway" })
@Override
- public void write(final Chunk extends T> chunk) throws Exception {
+ public void write(Chunk extends T> chunk) throws Exception {
if (!chunk.isEmpty()) {
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java
index 22e07c9a24..e7b1e52c6c 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java
@@ -38,7 +38,7 @@
*
* The statement used to open the cursor is created with the 'READ_ONLY' option since a
* non read-only cursor may unnecessarily lock tables or rows. It is also opened with
- * 'TYPE_FORWARD_ONLY' option. By default the cursor will be opened using a separate
+ * 'TYPE_FORWARD_ONLY' option. By default, the cursor will be opened using a separate
* connection which means that it will not participate in any transactions created as part
* of the step processing.
*
@@ -57,19 +57,19 @@
* @author Robert Kasanicky
* @author Thomas Risberg
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
public class JdbcCursorItemReader extends AbstractCursorItemReader {
- private PreparedStatement preparedStatement;
+ private @Nullable PreparedStatement preparedStatement;
- private PreparedStatementSetter preparedStatementSetter;
+ private @Nullable PreparedStatementSetter preparedStatementSetter;
- private String sql;
+ private @Nullable String sql;
- private RowMapper rowMapper;
+ private @Nullable RowMapper rowMapper;
public JdbcCursorItemReader() {
- super();
setName(ClassUtils.getShortName(JdbcCursorItemReader.class));
}
@@ -112,6 +112,7 @@ public void afterPropertiesSet() throws Exception {
Assert.state(rowMapper != null, "RowMapper must be provided");
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
protected void openCursor(Connection con) {
try {
@@ -136,6 +137,7 @@ protected void openCursor(Connection con) {
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
protected @Nullable T readCursor(ResultSet rs, int currentRow) throws SQLException {
return rowMapper.mapRow(rs, currentRow);
@@ -152,7 +154,7 @@ protected void cleanupOnClose(Connection connection) {
}
@Override
- public String getSql() {
+ public @Nullable String getSql() {
return this.sql;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcPagingItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcPagingItemReader.java
index 547c8e3ff9..a6b535d6f1 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcPagingItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcPagingItemReader.java
@@ -29,6 +29,7 @@
import javax.sql.DataSource;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.beans.factory.InitializingBean;
@@ -49,14 +50,14 @@
* data. The query is executed using paged requests of a size specified in
* {@link #setPageSize(int)}. Additional pages are requested when needed as
* {@link #read()} method is called, returning an object corresponding to current
- * position. On restart it uses the last sort key value to locate the first page to read
+ * position. On restart, it uses the last sort key value to locate the first page to read
* (so it doesn't matter if the successfully processed items have been removed or
* modified). It is important to have a unique key constraint on the sort key to guarantee
* that no data is lost between executions.
*
*
*
- * The performance of the paging depends on the database specific features available to
+ * The performance of the paging depends on the database-specific features available to
* limit the number of returned rows. Setting a fairly large page size and using a commit
* interval that matches the page size should provide better performance.
*
* This query provider creates JPA named {@link Query}s.
- *
*
* @author Mahmoud Ben Hassine
* @author Parikshit Dutta
+ * @author Stefano Cordio
* @since 4.3
* @param entity returned by executing the query
*/
public class JpaNamedQueryProvider extends AbstractJpaQueryProvider {
- private Class entityClass;
+ private @Nullable Class entityClass;
- private String namedQuery;
+ private @Nullable String namedQuery;
@Override
public Query createQuery() {
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/orm/JpaNativeQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/orm/JpaNativeQueryProvider.java
index 8ed7421217..3072709eab 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/orm/JpaNativeQueryProvider.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/orm/JpaNativeQueryProvider.java
@@ -18,25 +18,26 @@
import jakarta.persistence.Query;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
+ * This query provider creates JPA {@link Query queries} from injected native SQL queries.
*
- * This query provider creates JPA {@link Query}s from injected native SQL queries. This
- * is useful if there is a need to utilize database-specific features such as query hints,
- * the CONNECT keyword in Oracle, etc.
- *
+ * This is useful if there is a need to utilize database-specific features such as query
+ * hints, the {@code CONNECT} keyword in Oracle, etc.
*
* @author Anatoly Polinsky
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @param entity returned by executing the query
*/
public class JpaNativeQueryProvider extends AbstractJpaQueryProvider {
- private Class entityClass;
+ private @Nullable Class entityClass;
- private String sqlQuery;
+ private @Nullable String sqlQuery;
@Override
public Query createQuery() {
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/orm/JpaQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/orm/JpaQueryProvider.java
index 1ccdd8f94d..1d8dcfcdd3 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/orm/JpaQueryProvider.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/orm/JpaQueryProvider.java
@@ -22,23 +22,18 @@
import org.springframework.batch.item.ItemReader;
/**
- *
* Interface defining the functionality to be provided for generating queries for use with
- * JPA {@link ItemReader}s or other custom built artifacts.
- *
+ * JPA {@link ItemReader}s or other custom-built artifacts.
*
* @author Anatoly Polinsky
* @author Dave Syer
* @author Mahmoud Ben Hassine
* @since 2.1
- *
*/
public interface JpaQueryProvider {
/**
- *
* Create the query object.
- *
* @return created query
*/
Query createQuery();
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProvider.java
index b60cdfadf9..c80edf6c67 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProvider.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProvider.java
@@ -22,6 +22,7 @@
import java.util.Map;
import javax.sql.DataSource;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.database.JdbcParameterUtils;
import org.springframework.batch.item.database.Order;
import org.springframework.batch.item.database.PagingQueryProvider;
@@ -50,19 +51,20 @@
* @author Michael Minella
* @author Mahmoud Ben Hassine
* @author Benjamin Hetz
+ * @author Stefano Cordio
* @since 2.0
*/
public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvider {
- private String selectClause;
+ private @Nullable String selectClause;
- private String fromClause;
+ private @Nullable String fromClause;
- private String whereClause;
+ private @Nullable String whereClause;
private Map sortKeys = new LinkedHashMap<>();
- private String groupClause;
+ private @Nullable String groupClause;
private int parameterCount;
@@ -73,19 +75,14 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
* @param groupClause SQL GROUP BY clause part of the SQL query string
*/
public void setGroupClause(String groupClause) {
- if (StringUtils.hasText(groupClause)) {
- this.groupClause = removeKeyWord("group by", groupClause);
- }
- else {
- this.groupClause = null;
- }
+ this.groupClause = StringUtils.hasText(groupClause) ? removeKeyWord("group by", groupClause) : null;
}
/**
* The getter for the group by clause
* @return SQL GROUP BY clause part of the SQL query string
*/
- public String getGroupClause() {
+ public @Nullable String getGroupClause() {
return this.groupClause;
}
@@ -99,7 +96,7 @@ public void setSelectClause(String selectClause) {
/**
* @return SQL SELECT clause part of SQL query string
*/
- protected String getSelectClause() {
+ protected @Nullable String getSelectClause() {
return selectClause;
}
@@ -113,7 +110,7 @@ public void setFromClause(String fromClause) {
/**
* @return SQL FROM clause part of SQL query string
*/
- protected String getFromClause() {
+ protected @Nullable String getFromClause() {
return fromClause;
}
@@ -132,7 +129,7 @@ public void setWhereClause(String whereClause) {
/**
* @return SQL WHERE clause part of SQL query string
*/
- protected String getWhereClause() {
+ protected @Nullable String getWhereClause() {
return whereClause;
}
@@ -166,7 +163,7 @@ public boolean isUsingNamedParameters() {
/**
* The sort key placeholder will vary depending on whether named parameters or
* traditional placeholders are used in query strings.
- * @return place holder for sortKey.
+ * @return placeholder for sortKey.
*/
@Override
public String getSortKeyPlaceHolder(String keyName) {
@@ -205,7 +202,7 @@ public void init(DataSource dataSource) throws Exception {
/**
* Method generating the query string to be used for retrieving the first page. This
- * method must be implemented in sub classes.
+ * method must be implemented in subclasses.
* @param pageSize number of rows to read per page
* @return query string
*/
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java
index 608e0f2e5b..38a0f98b13 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java
@@ -37,6 +37,7 @@
import javax.sql.DataSource;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.database.Order;
import org.springframework.batch.item.database.PagingQueryProvider;
import org.springframework.batch.support.DatabaseType;
@@ -56,19 +57,19 @@
*/
public class SqlPagingQueryProviderFactoryBean implements FactoryBean {
- private DataSource dataSource;
+ private @Nullable DataSource dataSource;
- private String databaseType;
+ private @Nullable String databaseType;
- private String fromClause;
+ private @Nullable String fromClause;
- private String whereClause;
+ private @Nullable String whereClause;
- private String selectClause;
+ private @Nullable String selectClause;
- private String groupClause;
+ private @Nullable String groupClause;
- private Map sortKeys;
+ private @Nullable Map sortKeys;
private final Map providers = new HashMap<>();
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java
index 3b0ae7c09d..28481509e8 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java
@@ -49,6 +49,7 @@
*
* @author Robert Kasanicky
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
public class FlatFileItemReader extends AbstractItemCountingItemStreamItemReader
implements ResourceAwareItemReaderItemStream, InitializingBean {
@@ -61,9 +62,9 @@ public class FlatFileItemReader extends AbstractItemCountingItemStreamItemRea
private RecordSeparatorPolicy recordSeparatorPolicy = new SimpleRecordSeparatorPolicy();
- private Resource resource;
+ private @Nullable Resource resource;
- private BufferedReader reader;
+ private @Nullable BufferedReader reader;
private int lineCount = 0;
@@ -73,11 +74,11 @@ public class FlatFileItemReader extends AbstractItemCountingItemStreamItemRea
private String encoding = DEFAULT_CHARSET;
- private LineMapper lineMapper;
+ private @Nullable LineMapper lineMapper;
private int linesToSkip = 0;
- private LineCallbackHandler skippedLinesCallback;
+ private @Nullable LineCallbackHandler skippedLinesCallback;
private boolean strict = true;
@@ -158,7 +159,7 @@ public void setComments(String[] comments) {
* Public setter for the input resource.
*/
@Override
- public void setResource(Resource resource) {
+ public void setResource(@Nullable Resource resource) {
this.resource = resource;
}
@@ -177,6 +178,7 @@ public void setRecordSeparatorPolicy(RecordSeparatorPolicy recordSeparatorPolicy
* {@link #setRecordSeparatorPolicy(RecordSeparatorPolicy)} (might span multiple lines
* in file).
*/
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
protected @Nullable T doRead() throws Exception {
if (noInput) {
@@ -211,18 +213,14 @@ public void setRecordSeparatorPolicy(RecordSeparatorPolicy recordSeparatorPolicy
String line = null;
try {
- line = this.reader.readLine();
- if (line == null) {
- return null;
- }
- lineCount++;
- while (isComment(line)) {
+ do {
line = reader.readLine();
if (line == null) {
return null;
}
lineCount++;
}
+ while (isComment(line));
line = applyRecordSeparatorPolicy(line);
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java
index 889e4ff5dc..e24a79d91d 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java
@@ -16,6 +16,7 @@
package org.springframework.batch.item.file;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.Chunk;
import org.springframework.batch.item.file.transform.LineAggregator;
import org.springframework.batch.item.support.AbstractFileItemWriter;
@@ -38,10 +39,11 @@
* @author Dave Syer
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
public class FlatFileItemWriter extends AbstractFileItemWriter {
- protected LineAggregator lineAggregator;
+ protected @Nullable LineAggregator lineAggregator;
public FlatFileItemWriter() {
this.setExecutionContextName(ClassUtils.getShortName(FlatFileItemWriter.class));
@@ -69,6 +71,7 @@ public void setLineAggregator(LineAggregator lineAggregator) {
this.lineAggregator = lineAggregator;
}
+ @SuppressWarnings({ "DataFlowIssue", "NullAway" })
@Override
public String doWrite(Chunk extends T> items) {
StringBuilder lines = new StringBuilder();
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilder.java
index e52d4dbde9..eb9d9e9817 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemReaderBuilder.java
@@ -29,6 +29,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.file.BufferedReaderFactory;
import org.springframework.batch.item.file.DefaultBufferedReaderFactory;
import org.springframework.batch.item.file.FlatFileItemReader;
@@ -60,6 +61,7 @@
* @author Drummond Dawson
* @author Patrick Baumgartner
* @author François Martin
+ * @author Stefano Cordio
* @since 4.0
* @see FlatFileItemReader
*/
@@ -75,29 +77,29 @@ public class FlatFileItemReaderBuilder {
private BufferedReaderFactory bufferedReaderFactory = new DefaultBufferedReaderFactory();
- private Resource resource;
+ private @Nullable Resource resource;
private List comments = new ArrayList<>(Arrays.asList(FlatFileItemReader.DEFAULT_COMMENT_PREFIXES));
private int linesToSkip = 0;
- private LineCallbackHandler skippedLinesCallback;
+ private @Nullable LineCallbackHandler skippedLinesCallback;
- private LineMapper lineMapper;
+ private @Nullable LineMapper lineMapper;
- private FieldSetMapper fieldSetMapper;
+ private @Nullable FieldSetMapper fieldSetMapper;
- private LineTokenizer lineTokenizer;
+ private @Nullable LineTokenizer lineTokenizer;
- private DelimitedBuilder delimitedBuilder;
+ private @Nullable DelimitedBuilder delimitedBuilder;
- private FixedLengthBuilder fixedLengthBuilder;
+ private @Nullable FixedLengthBuilder fixedLengthBuilder;
- private Class targetType;
+ private @Nullable Class targetType;
- private String prototypeBeanName;
+ private @Nullable String prototypeBeanName;
- private BeanFactory beanFactory;
+ private @Nullable BeanFactory beanFactory;
private final Map, PropertyEditor> customEditors = new HashMap<>();
@@ -109,7 +111,7 @@ public class FlatFileItemReaderBuilder {
private boolean saveState = true;
- private String name;
+ private @Nullable String name;
private int maxItemCount = Integer.MAX_VALUE;
@@ -299,8 +301,7 @@ public FlatFileItemReaderBuilder fieldSetMapper(FieldSetMapper mapper) {
* @see DefaultLineMapper#setLineTokenizer(LineTokenizer)
*/
public FlatFileItemReaderBuilder lineTokenizer(LineTokenizer tokenizer) {
- updateTokenizerValidation(tokenizer, 0);
-
+ this.tokenizerValidator = this.tokenizerValidator.flipBit(0);
this.lineTokenizer = tokenizer;
return this;
}
@@ -315,7 +316,7 @@ public FlatFileItemReaderBuilder lineTokenizer(LineTokenizer tokenizer) {
*/
public DelimitedBuilder delimited() {
this.delimitedBuilder = new DelimitedBuilder<>(this);
- updateTokenizerValidation(this.delimitedBuilder, 1);
+ this.tokenizerValidator = this.tokenizerValidator.flipBit(1);
return this.delimitedBuilder;
}
@@ -328,15 +329,15 @@ public DelimitedBuilder delimited() {
*/
public FixedLengthBuilder fixedLength() {
this.fixedLengthBuilder = new FixedLengthBuilder<>(this);
- updateTokenizerValidation(this.fixedLengthBuilder, 2);
+ this.tokenizerValidator = this.tokenizerValidator.flipBit(2);
return this.fixedLengthBuilder;
}
/**
* The class that will represent the "item" to be returned from the reader. This class
* is used via the {@link BeanWrapperFieldSetMapper}. If more complex logic is
- * required, providing your own {@link FieldSetMapper} via
- * {@link FlatFileItemReaderBuilder#fieldSetMapper} is required.
+ * required, providing your own {@link FieldSetMapper} via {@link #fieldSetMapper} is
+ * required.
* @param targetType The class to map to
* @return The current instance of the builder.
* @see BeanWrapperFieldSetMapper#setTargetType(Class)
@@ -377,10 +378,7 @@ public FlatFileItemReaderBuilder beanFactory(BeanFactory beanFactory) {
* @see BeanWrapperFieldSetMapper#setCustomEditors(Map)
*/
public FlatFileItemReaderBuilder customEditors(Map, PropertyEditor> customEditors) {
- if (customEditors != null) {
- this.customEditors.putAll(customEditors);
- }
-
+ this.customEditors.putAll(customEditors);
return this;
}
@@ -471,10 +469,14 @@ else if (this.delimitedBuilder != null) {
}
else {
BeanWrapperFieldSetMapper mapper = new BeanWrapperFieldSetMapper<>();
+ if (this.prototypeBeanName != null) {
+ mapper.setPrototypeBeanName(this.prototypeBeanName);
+ }
+ if (this.beanFactory != null) {
+ mapper.setBeanFactory(this.beanFactory);
+ }
mapper.setTargetType(this.targetType);
- mapper.setPrototypeBeanName(this.prototypeBeanName);
mapper.setStrict(this.beanMapperStrict);
- mapper.setBeanFactory(this.beanFactory);
mapper.setDistanceLimit(this.distanceLimit);
mapper.setCustomEditors(this.customEditors);
try {
@@ -497,9 +499,11 @@ else if (this.fieldSetMapper != null) {
}
reader.setLinesToSkip(this.linesToSkip);
- reader.setComments(this.comments.toArray(new String[this.comments.size()]));
+ reader.setComments(this.comments.toArray(new String[0]));
- reader.setSkippedLinesCallback(this.skippedLinesCallback);
+ if (this.skippedLinesCallback != null) {
+ reader.setSkippedLinesCallback(this.skippedLinesCallback);
+ }
reader.setRecordSeparatorPolicy(this.recordSeparatorPolicy);
reader.setBufferedReaderFactory(this.bufferedReaderFactory);
reader.setMaxItemCount(this.maxItemCount);
@@ -510,15 +514,6 @@ else if (this.fieldSetMapper != null) {
return reader;
}
- private void updateTokenizerValidation(Object tokenizer, int index) {
- if (tokenizer != null) {
- this.tokenizerValidator = this.tokenizerValidator.flipBit(index);
- }
- else {
- this.tokenizerValidator = this.tokenizerValidator.clearBit(index);
- }
- }
-
/**
* A builder for constructing a {@link DelimitedLineTokenizer}
*
@@ -530,9 +525,9 @@ public static class DelimitedBuilder {
private final List names = new ArrayList<>();
- private String delimiter;
+ private @Nullable String delimiter;
- private Character quoteCharacter;
+ private @Nullable Character quoteCharacter;
private final List includedFields = new ArrayList<>();
@@ -638,7 +633,7 @@ public DelimitedLineTokenizer build() {
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
- tokenizer.setNames(this.names.toArray(new String[this.names.size()]));
+ tokenizer.setNames(this.names.toArray(new String[0]));
if (StringUtils.hasLength(this.delimiter)) {
tokenizer.setDelimiter(this.delimiter);
@@ -780,8 +775,8 @@ public FixedLengthTokenizer build() {
FixedLengthTokenizer tokenizer = new FixedLengthTokenizer();
- tokenizer.setNames(this.names.toArray(new String[this.names.size()]));
- tokenizer.setColumns(this.ranges.toArray(new Range[this.ranges.size()]));
+ tokenizer.setNames(this.names.toArray(new String[0]));
+ tokenizer.setColumns(this.ranges.toArray(new Range[0]));
tokenizer.setFieldSetFactory(this.fieldSetFactory);
tokenizer.setStrict(this.strict);
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilder.java
index 7de7de5301..0ffc9262a4 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilder.java
@@ -23,6 +23,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.file.FlatFileFooterCallback;
import org.springframework.batch.item.file.FlatFileHeaderCallback;
import org.springframework.batch.item.file.FlatFileItemWriter;
@@ -43,6 +44,7 @@
* @author Glenn Renfro
* @author Mahmoud Ben Hassine
* @author Drummond Dawson
+ * @author Stefano Cordio
* @since 4.0
* @see FlatFileItemWriter
*/
@@ -50,13 +52,13 @@ public class FlatFileItemWriterBuilder {
protected Log logger = LogFactory.getLog(getClass());
- private WritableResource resource;
+ private @Nullable WritableResource resource;
private boolean forceSync = false;
private String lineSeparator = FlatFileItemWriter.DEFAULT_LINE_SEPARATOR;
- private LineAggregator lineAggregator;
+ private @Nullable LineAggregator lineAggregator;
private String encoding = FlatFileItemWriter.DEFAULT_CHARSET;
@@ -66,19 +68,19 @@ public class FlatFileItemWriterBuilder {
private boolean shouldDeleteIfEmpty = false;
- private FlatFileHeaderCallback headerCallback;
+ private @Nullable FlatFileHeaderCallback headerCallback;
- private FlatFileFooterCallback footerCallback;
+ private @Nullable FlatFileFooterCallback footerCallback;
private boolean transactional = FlatFileItemWriter.DEFAULT_TRANSACTIONAL;
private boolean saveState = true;
- private String name;
+ private @Nullable String name;
- private DelimitedBuilder delimitedBuilder;
+ private @Nullable DelimitedBuilder delimitedBuilder;
- private FormattedBuilder formattedBuilder;
+ private @Nullable FormattedBuilder formattedBuilder;
/**
* Configure if the state of the
@@ -280,7 +282,7 @@ public static class FormattedBuilder {
private final FlatFileItemWriterBuilder parent;
- private String format;
+ private @Nullable String format;
private Locale locale = Locale.getDefault();
@@ -288,11 +290,11 @@ public static class FormattedBuilder {
private int minimumLength = 0;
- private FieldExtractor fieldExtractor;
+ private @Nullable FieldExtractor fieldExtractor;
private final List names = new ArrayList<>();
- private Class sourceType;
+ private @Nullable Class sourceType;
protected FormattedBuilder(FlatFileItemWriterBuilder parent) {
this.parent = parent;
@@ -380,7 +382,7 @@ public FlatFileItemWriterBuilder names(String... names) {
public FormatterLineAggregator build() {
Assert.notNull(this.format, "A format is required");
- Assert.isTrue((this.names != null && !this.names.isEmpty()) || this.fieldExtractor != null,
+ Assert.isTrue(!this.names.isEmpty() || this.fieldExtractor != null,
"A list of field names or a field extractor is required");
FormatterLineAggregator formatterLineAggregator = new FormatterLineAggregator<>();
@@ -395,7 +397,7 @@ public FormatterLineAggregator build() {
}
else {
BeanWrapperFieldExtractor beanWrapperFieldExtractor = new BeanWrapperFieldExtractor<>();
- beanWrapperFieldExtractor.setNames(this.names.toArray(new String[this.names.size()]));
+ beanWrapperFieldExtractor.setNames(this.names.toArray(new String[0]));
try {
beanWrapperFieldExtractor.afterPropertiesSet();
this.fieldExtractor = beanWrapperFieldExtractor;
@@ -427,9 +429,9 @@ public static class DelimitedBuilder {
private String quoteCharacter = "";
- private FieldExtractor fieldExtractor;
+ private @Nullable FieldExtractor fieldExtractor;
- private Class sourceType;
+ private @Nullable Class sourceType;
protected DelimitedBuilder(FlatFileItemWriterBuilder parent) {
this.parent = parent;
@@ -497,13 +499,12 @@ public FlatFileItemWriterBuilder fieldExtractor(FieldExtractor fieldExtrac
}
public DelimitedLineAggregator build() {
- Assert.isTrue((this.names != null && !this.names.isEmpty()) || this.fieldExtractor != null,
+ Assert.isTrue(!this.names.isEmpty() || this.fieldExtractor != null,
"A list of field names or a field extractor is required");
DelimitedLineAggregator delimitedLineAggregator = new DelimitedLineAggregator<>();
- if (this.delimiter != null) {
- delimitedLineAggregator.setDelimiter(this.delimiter);
- }
+ delimitedLineAggregator.setDelimiter(this.delimiter);
+
if (StringUtils.hasLength(this.quoteCharacter)) {
delimitedLineAggregator.setQuoteCharacter(this.quoteCharacter);
}
@@ -514,7 +515,7 @@ public DelimitedLineAggregator build() {
}
else {
BeanWrapperFieldExtractor beanWrapperFieldExtractor = new BeanWrapperFieldExtractor<>();
- beanWrapperFieldExtractor.setNames(this.names.toArray(new String[this.names.size()]));
+ beanWrapperFieldExtractor.setNames(this.names.toArray(new String[0]));
try {
beanWrapperFieldExtractor.afterPropertiesSet();
this.fieldExtractor = beanWrapperFieldExtractor;
@@ -551,12 +552,18 @@ public FlatFileItemWriter build() {
FlatFileItemWriter writer = new FlatFileItemWriter<>();
- writer.setName(this.name);
+ if (this.name != null) {
+ writer.setName(this.name);
+ }
writer.setAppendAllowed(this.append);
writer.setEncoding(this.encoding);
- writer.setFooterCallback(this.footerCallback);
+ if (this.footerCallback != null) {
+ writer.setFooterCallback(this.footerCallback);
+ }
writer.setForceSync(this.forceSync);
- writer.setHeaderCallback(this.headerCallback);
+ if (this.headerCallback != null) {
+ writer.setHeaderCallback(this.headerCallback);
+ }
if (this.lineAggregator == null) {
Assert.state(this.delimitedBuilder == null || this.formattedBuilder == null,
"Either a DelimitedLineAggregator or a FormatterLineAggregator should be provided, but not both");
@@ -564,12 +571,15 @@ public FlatFileItemWriter build() {
this.lineAggregator = this.delimitedBuilder.build();
}
else {
+ Assert.state(this.formattedBuilder != null, "A FormattedBuilder is required");
this.lineAggregator = this.formattedBuilder.build();
}
}
writer.setLineAggregator(this.lineAggregator);
writer.setLineSeparator(this.lineSeparator);
- writer.setResource(this.resource);
+ if (this.resource != null) {
+ writer.setResource(this.resource);
+ }
writer.setSaveState(this.saveState);
writer.setShouldDeleteIfEmpty(this.shouldDeleteIfEmpty);
writer.setShouldDeleteIfExists(this.shouldDeleteIfExists);
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/MultiResourceItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/MultiResourceItemReaderBuilder.java
index bfb6927518..4ee65dd80c 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/MultiResourceItemReaderBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/builder/MultiResourceItemReaderBuilder.java
@@ -18,6 +18,7 @@
import java.util.Comparator;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.file.MultiResourceItemReader;
import org.springframework.batch.item.file.ResourceAwareItemReaderItemStream;
import org.springframework.core.io.Resource;
@@ -29,22 +30,23 @@
*
* @author Glenn Renfro
* @author Drummond Dawson
+ * @author Stefano Cordio
* @since 4.0
* @see MultiResourceItemReader
*/
public class MultiResourceItemReaderBuilder {
- private ResourceAwareItemReaderItemStream extends T> delegate;
+ private @Nullable ResourceAwareItemReaderItemStream extends T> delegate;
- private Resource[] resources;
+ private Resource @Nullable [] resources;
private boolean strict = false;
- private Comparator comparator;
+ private @Nullable Comparator comparator;
private boolean saveState = true;
- private String name;
+ private @Nullable String name;
/**
* Configure if the state of the
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/mapping/BeanWrapperFieldSetMapper.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/mapping/BeanWrapperFieldSetMapper.java
index 81bfa97739..a6d4b8cba1 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/mapping/BeanWrapperFieldSetMapper.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/mapping/BeanWrapperFieldSetMapper.java
@@ -26,6 +26,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.batch.support.DefaultPropertyEditorRegistrar;
import org.springframework.beans.BeanWrapperImpl;
@@ -93,11 +94,11 @@
public class BeanWrapperFieldSetMapper extends DefaultPropertyEditorRegistrar
implements FieldSetMapper, BeanFactoryAware, InitializingBean {
- private String name;
+ private @Nullable String name;
- private Class extends T> type;
+ private @Nullable Class extends T> type;
- private BeanFactory beanFactory;
+ private @Nullable BeanFactory beanFactory;
private final ConcurrentMap> propertiesMatched = new ConcurrentHashMap<>();
@@ -105,7 +106,7 @@ public class BeanWrapperFieldSetMapper extends DefaultPropertyEditorRegistrar
private boolean strict = true;
- private ConversionService conversionService;
+ private @Nullable ConversionService conversionService;
private boolean isCustomEditorsSet;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/AbstractLineTokenizer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/AbstractLineTokenizer.java
index ad0a8a6344..603e8ff2e9 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/AbstractLineTokenizer.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/AbstractLineTokenizer.java
@@ -17,7 +17,6 @@
package org.springframework.batch.item.file.transform;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import org.springframework.util.StringUtils;
@@ -33,15 +32,16 @@
* @author Lucas Ward
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
public abstract class AbstractLineTokenizer implements LineTokenizer {
+ private static final String EMPTY_TOKEN = "";
+
protected String[] names = new String[0];
private boolean strict = true;
- private final String emptyToken = "";
-
private FieldSetFactory fieldSetFactory = new DefaultFieldSetFactory();
/**
@@ -78,21 +78,16 @@ public void setFieldSetFactory(FieldSetFactory fieldSetFactory) {
* @param names names of each column
*/
public void setNames(String... names) {
- if (names == null) {
- this.names = null;
- }
- else {
- boolean valid = false;
- for (String name : names) {
- if (StringUtils.hasText(name)) {
- valid = true;
- break;
- }
+ boolean valid = false;
+ for (String name : names) {
+ if (StringUtils.hasText(name)) {
+ valid = true;
+ break;
}
+ }
- if (valid) {
- this.names = Arrays.asList(names).toArray(new String[names.length]);
- }
+ if (valid) {
+ this.names = names.clone();
}
}
@@ -101,10 +96,7 @@ public void setNames(String... names) {
* @see #setNames(String[])
*/
public boolean hasNames() {
- if (names != null && names.length > 0) {
- return true;
- }
- return false;
+ return names.length > 0;
}
/**
@@ -126,7 +118,7 @@ public FieldSet tokenize(@Nullable String line) {
adjustTokenCountIfNecessary(tokens);
}
- String[] values = tokens.toArray(new String[tokens.size()]);
+ String[] values = tokens.toArray(new String[0]);
if (names.length == 0) {
return fieldSetFactory.create(values);
@@ -157,7 +149,7 @@ private void adjustTokenCountIfNecessary(List tokens) {
// add empty tokens until the token list size matches
// the expected number of tokens
for (int i = 0; i < (nameLength - tokensSize); i++) {
- tokens.add(emptyToken);
+ tokens.add(EMPTY_TOKEN);
}
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizer.java
index bb14e462dd..8fd965bba6 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizer.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizer.java
@@ -17,9 +17,9 @@
package org.springframework.batch.item.file.transform;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
@@ -63,7 +63,7 @@ public class DelimitedLineTokenizer extends AbstractLineTokenizer implements Ini
private String escapedQuoteString;
- private Collection includedFields = null;
+ private final Set includedFields = new HashSet<>();
/**
* Create a new instance of the {@link DelimitedLineTokenizer} class for the common
@@ -80,6 +80,7 @@ public DelimitedLineTokenizer() {
* Create a new instance of the {@link DelimitedLineTokenizer} class.
* @param delimiter the desired delimiter. This is required
*/
+ @SuppressWarnings("NullAway")
public DelimitedLineTokenizer(String delimiter) {
Assert.notNull(delimiter, "A delimiter is required");
Assert.state(!delimiter.equals(String.valueOf(DEFAULT_QUOTE_CHARACTER)),
@@ -105,7 +106,6 @@ public void setDelimiter(String delimiter) {
* @param includedFields the included fields to set
*/
public void setIncludedFields(int... includedFields) {
- this.includedFields = new HashSet<>();
for (int i : includedFields) {
this.includedFields.add(i);
}
@@ -161,7 +161,7 @@ else if (!isEnd) {
endPosition = (endPosition - delimiter.length()) + 1;
}
- if (includedFields == null || includedFields.contains(fieldCount)) {
+ if (includedFields.contains(fieldCount)) {
String value = substringWithTrimmedWhitespaceAndQuotesIfQuotesPresent(line, lastCut, endPosition);
tokens.add(value);
}
@@ -169,7 +169,7 @@ else if (!isEnd) {
fieldCount++;
if (isEnd && isDelimiter) {
- if (includedFields == null || includedFields.contains(fieldCount)) {
+ if (includedFields.contains(fieldCount)) {
tokens.add("");
}
fieldCount++;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FixedLengthTokenizer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FixedLengthTokenizer.java
index 8d27812a72..a35cc69520 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FixedLengthTokenizer.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FixedLengthTokenizer.java
@@ -16,6 +16,9 @@
package org.springframework.batch.item.file.transform;
+import org.jspecify.annotations.Nullable;
+import org.springframework.util.Assert;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -30,10 +33,11 @@
* @author Lucas Ward
* @author Michael Minella
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
public class FixedLengthTokenizer extends AbstractLineTokenizer {
- private Range[] ranges;
+ private Range @Nullable [] ranges;
private int maxRange = 0;
@@ -50,7 +54,7 @@ public class FixedLengthTokenizer extends AbstractLineTokenizer {
* @param ranges the column ranges expected in the input
*/
public void setColumns(Range... ranges) {
- this.ranges = Arrays.asList(ranges).toArray(new Range[ranges.length]);
+ this.ranges = ranges.clone();
calculateMaxRange(ranges);
}
@@ -60,7 +64,7 @@ public void setColumns(Range... ranges) {
* always a min and max, such as: "1,4-20, 22"
*/
private void calculateMaxRange(Range[] ranges) {
- if (ranges == null || ranges.length == 0) {
+ if (ranges.length == 0) {
maxRange = 0;
return;
}
@@ -95,6 +99,7 @@ private void calculateMaxRange(Range[] ranges) {
*/
@Override
protected List doTokenize(String line) {
+ Assert.state(ranges != null, "ranges must not be null");
List tokens = new ArrayList<>(ranges.length);
int lineLength;
String token;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FormatterLineAggregator.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FormatterLineAggregator.java
index aa37bcfda2..94b77df311 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FormatterLineAggregator.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FormatterLineAggregator.java
@@ -19,6 +19,7 @@
import java.util.Formatter;
import java.util.Locale;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@@ -27,10 +28,11 @@
*
* @see Formatter
* @author Dave Syer
+ * @author Stefano Cordio
*/
public class FormatterLineAggregator extends ExtractorLineAggregator {
- private String format;
+ private @Nullable String format;
private Locale locale = Locale.getDefault();
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/RangeArrayPropertyEditor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/RangeArrayPropertyEditor.java
index e382bfca8c..6e7f16e92c 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/RangeArrayPropertyEditor.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/RangeArrayPropertyEditor.java
@@ -111,7 +111,7 @@ public String getAsText() {
return sb.toString();
}
- private void setMaxValues(final Range[] ranges) {
+ private void setMaxValues(Range[] ranges) {
// Array of integers to track range values by index
Integer[] c = new Integer[ranges.length];
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java
index 921f523b58..75a3685502 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java
@@ -45,8 +45,7 @@ default void open(Resource resource) throws Exception {
* @return the next object or {@code null} if the resource is exhausted
* @throws Exception if unable to read the next object
*/
- @Nullable
- T read() throws Exception;
+ @Nullable T read() throws Exception;
/**
* Close the input resource.
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/KafkaItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/KafkaItemWriter.java
index a542bd87c2..43a1b83460 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/KafkaItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/kafka/KafkaItemWriter.java
@@ -16,6 +16,7 @@
package org.springframework.batch.item.kafka;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.KeyValueItemWriter;
import org.springframework.kafka.core.KafkaTemplate;
@@ -39,19 +40,20 @@
*
* @author Mathieu Ouellet
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @since 4.2
*
*/
public class KafkaItemWriter extends KeyValueItemWriter {
- protected KafkaTemplate kafkaTemplate;
+ protected @Nullable KafkaTemplate kafkaTemplate;
protected final List>> completableFutures = new ArrayList<>();
private long timeout = -1;
@Override
- protected void writeKeyValue(K key, T value) {
+ protected void writeKeyValue(@Nullable K key, T value) {
if (this.delete) {
this.completableFutures.add(this.kafkaTemplate.sendDefault(key, null));
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/RecordMapper.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/RecordMapper.java
index 5f06b0dd63..1c7ebde486 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/RecordMapper.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/RecordMapper.java
@@ -35,7 +35,6 @@ public interface RecordMapper {
* @param attributes attributes
* @return object of type T or {@code null} if unable to map the record to an object.
*/
- @Nullable
- T mapRecord(LdapAttributes attributes);
+ @Nullable T mapRecord(LdapAttributes attributes);
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/queue/BlockingQueueItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/queue/BlockingQueueItemReader.java
index e5e411045b..ceb9e5d6cc 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/queue/BlockingQueueItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/queue/BlockingQueueItemReader.java
@@ -22,7 +22,7 @@
/**
* This is an {@link ItemReader} that reads items from a {@link BlockingQueue}. It stops
- * reading (ie returns {@code null}) if no items are available in the queue after a
+ * reading (i.e., returns {@code null}) if no items are available in the queue after a
* configurable timeout.
*
* @param type of items to read.
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/redis/RedisItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/redis/RedisItemWriter.java
index c9b0ae3ee3..8f11a50226 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/redis/RedisItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/redis/RedisItemWriter.java
@@ -16,6 +16,7 @@
package org.springframework.batch.item.redis;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.KeyValueItemWriter;
import org.springframework.data.redis.core.RedisTemplate;
@@ -28,11 +29,12 @@
*
* @author Santiago Molano
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @since 5.1
*/
public class RedisItemWriter extends KeyValueItemWriter {
- private RedisTemplate redisTemplate;
+ private @Nullable RedisTemplate redisTemplate;
@Override
protected void writeKeyValue(K key, T value) {
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/redis/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/redis/package-info.java
new file mode 100644
index 0000000000..7eb3c84f7e
--- /dev/null
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/redis/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Redis related readers and writers
+ *
+ * @author Stefano Cordio
+ */
+@NullMarked
+package org.springframework.batch.item.redis;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/ExecutionContextUserSupport.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/ExecutionContextUserSupport.java
index 661ab42b88..f26c0331dd 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/ExecutionContextUserSupport.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/util/ExecutionContextUserSupport.java
@@ -15,6 +15,7 @@
*/
package org.springframework.batch.item.util;
+import org.jspecify.annotations.Nullable;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.util.Assert;
@@ -24,10 +25,11 @@
*
* @author Robert Kasanicky
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
public class ExecutionContextUserSupport {
- private String name;
+ private @Nullable String name;
public ExecutionContextUserSupport() {
super();
@@ -41,7 +43,7 @@ public ExecutionContextUserSupport(String name) {
/**
* @return name used to uniquely identify this instance's entries in shared context.
*/
- public String getName() {
+ public @Nullable String getName() {
return this.name;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/SimpleLimitExceptionHandler.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/SimpleLimitExceptionHandler.java
index d3592695a1..ba42ea6842 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/SimpleLimitExceptionHandler.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/SimpleLimitExceptionHandler.java
@@ -116,7 +116,7 @@ public void handleException(RepeatContext context, Throwable throwable) throws T
* rethrown.
* @param limit the limit
*/
- public void setLimit(final int limit) {
+ public void setLimit(int limit) {
this.limit = limit;
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/interceptor/RepeatOperationsInterceptor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/interceptor/RepeatOperationsInterceptor.java
index de3df9427a..5d688c0d09 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/interceptor/RepeatOperationsInterceptor.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/interceptor/RepeatOperationsInterceptor.java
@@ -59,7 +59,7 @@ public void setRepeatOperations(RepeatOperations batchTemplate) {
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
*/
@Override
- public Object invoke(final MethodInvocation invocation) throws Throwable {
+ public Object invoke(MethodInvocation invocation) throws Throwable {
final ResultHolder result = new ResultHolder();
// Cache void return value if intercepted method returns void
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java
index 1fc00e8bbb..359cb3f414 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java
@@ -156,7 +156,7 @@ public RepeatStatus iterate(RepeatCallback callback) {
* the results from the callback.
*
*/
- private RepeatStatus executeInternal(final RepeatCallback callback) {
+ private RepeatStatus executeInternal(RepeatCallback callback) {
// Reset the termination policy if there is one...
RepeatContext context = start();
@@ -408,7 +408,7 @@ private boolean isMarkedComplete(RepeatContext context) {
* @param context the current batch context.
* @param value the result of the callback to process.
*/
- protected void executeAfterInterceptors(final RepeatContext context, RepeatStatus value) {
+ protected void executeAfterInterceptors(RepeatContext context, RepeatStatus value) {
// Don't re-throw exceptions here: let the exception handler deal with
// that...
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/AnnotationMethodResolver.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/AnnotationMethodResolver.java
index 426cef7d5a..4c7c2d1535 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/AnnotationMethodResolver.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/AnnotationMethodResolver.java
@@ -82,7 +82,7 @@ public AnnotationMethodResolver(Class extends Annotation> annotationType) {
* annotation
*/
@Override
- public @Nullable Method findMethod(final Class> clazz) {
+ public @Nullable Method findMethod(Class> clazz) {
Assert.notNull(clazz, "class must not be null");
final AtomicReference annotatedMethod = new AtomicReference<>();
ReflectionUtils.doWithMethods(clazz, method -> {
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java
index 09bc1e314b..d5641a097b 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java
@@ -16,6 +16,7 @@
package org.springframework.batch.support;
+import org.jspecify.annotations.Nullable;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.util.StringUtils;
@@ -23,9 +24,10 @@
import javax.sql.DataSource;
import java.sql.DatabaseMetaData;
-import org.jspecify.annotations.Nullable;
-import java.util.HashMap;
+import java.util.Arrays;
import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
/**
* Enum representing a database type, such as DB2 or oracle. The type also contains a
@@ -34,6 +36,7 @@
*
* @author Lucas Ward
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
* @since 2.0
*/
public enum DatabaseType {
@@ -42,14 +45,9 @@ public enum DatabaseType {
HSQL("HSQL Database Engine"), SQLSERVER("Microsoft SQL Server"), MYSQL("MySQL"), ORACLE("Oracle"),
POSTGRES("PostgreSQL"), SYBASE("Sybase"), H2("H2"), SQLITE("SQLite"), HANA("HDB"), MARIADB("MariaDB");
- private static final Map nameMap;
+ private static final Map DATABASE_TYPES = Arrays.stream(DatabaseType.values())
+ .collect(Collectors.toMap(DatabaseType::getProductName, Function.identity()));
- static {
- nameMap = new HashMap<>();
- for (DatabaseType type : values()) {
- nameMap.put(type.getProductName(), type);
- }
- }
// A description is necessary due to the nature of database descriptions
// in metadata.
private final String productName;
@@ -68,13 +66,11 @@ public String getProductName() {
* @return the {@link DatabaseType} for given product name.
* @throws IllegalArgumentException if none is found.
*/
- public static @Nullable DatabaseType fromProductName(String productName) {
- if (!nameMap.containsKey(productName)) {
+ public static DatabaseType fromProductName(@Nullable String productName) {
+ if (!DATABASE_TYPES.containsKey(productName)) {
throw new IllegalArgumentException("DatabaseType not found for product name: [" + productName + "]");
}
- else {
- return nameMap.get(productName);
- }
+ return DATABASE_TYPES.get(productName);
}
/**
@@ -82,7 +78,7 @@ public String getProductName() {
* metadata.
* @param dataSource {@link DataSource} to the database to be used.
* @return {@link DatabaseType} for the {@link DataSource} specified.
- * @throws MetaDataAccessException thrown if error occured during Metadata lookup.
+ * @throws MetaDataAccessException if an error occurred during Metadata lookup.
*/
public static DatabaseType fromMetaData(DataSource dataSource) throws MetaDataAccessException {
String databaseProductName = JdbcUtils.extractDatabaseMetaData(dataSource,
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodInvoker.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodInvoker.java
index e56ee61ae5..27441b2177 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodInvoker.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodInvoker.java
@@ -26,7 +26,6 @@
*/
public interface MethodInvoker {
- @Nullable
- Object invokeMethod(Object... args);
+ @Nullable Object invokeMethod(Object... args);
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodInvokerUtils.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodInvokerUtils.java
index b873a2a12a..be3eb2953a 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodInvokerUtils.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodInvokerUtils.java
@@ -113,7 +113,7 @@ public static String getParamTypesString(Class>... paramTypes) {
* @param expectedParamTypes the expected parameter types for the method
* @return a MethodInvoker
*/
- public static MethodInvoker getMethodInvokerByAnnotation(final Class extends Annotation> annotationType,
+ public static MethodInvoker getMethodInvokerByAnnotation(Class extends Annotation> annotationType,
final Object target, final Class>... expectedParamTypes) {
MethodInvoker mi = MethodInvokerUtils.getMethodInvokerByAnnotation(annotationType, target);
final Class> targetClass = (target instanceof Advised advised) ? advised.getTargetSource().getTargetClass()
@@ -148,7 +148,7 @@ public static MethodInvoker getMethodInvokerByAnnotation(final Class extends A
* @param target to be invoked
* @return MethodInvoker for the provided annotation, null if none is found.
*/
- public static @Nullable MethodInvoker getMethodInvokerByAnnotation(final Class extends Annotation> annotationType,
+ public static @Nullable MethodInvoker getMethodInvokerByAnnotation(Class extends Annotation> annotationType,
final Object target) {
Assert.notNull(target, "Target must not be null");
Assert.notNull(annotationType, "AnnotationType must not be null");
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodResolver.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodResolver.java
index d548d9fb9e..e8ebd4f82b 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodResolver.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/MethodResolver.java
@@ -36,8 +36,7 @@ public interface MethodResolver {
* @throws IllegalArgumentException if more than one Method defined on the given
* candidate's Class matches this resolver's criteria
*/
- @Nullable
- Method findMethod(Object candidate) throws IllegalArgumentException;
+ @Nullable Method findMethod(Object candidate) throws IllegalArgumentException;
/**
* Find a single Method on the given Class that matches this resolver's
@@ -48,7 +47,6 @@ public interface MethodResolver {
* @throws IllegalArgumentException if more than one Method defined on the given Class
* matches this resolver's criteria
*/
- @Nullable
- Method findMethod(Class> clazz);
+ @Nullable Method findMethod(Class> clazz);
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/container/jms/BatchMessageListenerContainer.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/container/jms/BatchMessageListenerContainer.java
index 5fab1c2686..9a191fbb32 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/container/jms/BatchMessageListenerContainer.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/container/jms/BatchMessageListenerContainer.java
@@ -121,7 +121,7 @@ else if (ex instanceof Error error) {
* jakarta.jms.Session, jakarta.jms.MessageConsumer)
*/
@Override
- protected boolean receiveAndExecute(final Object invoker, final Session session, final MessageConsumer consumer)
+ protected boolean receiveAndExecute(Object invoker, final Session session, final MessageConsumer consumer)
throws JMSException {
return proxy.receiveAndExecute(invoker, session, consumer);
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java
index f8f4df0ccb..be127212c2 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java
@@ -328,7 +328,7 @@ void testWriteStringNotTransactional() {
writeStringTransactionCheck(TEST_STRING);
}
- private void writeStringTransactionCheck(final String expectedInTransaction) {
+ private void writeStringTransactionCheck(String expectedInTransaction) {
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
writer.open(executionContext);
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/poller/DirectPollerTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/poller/DirectPollerTests.java
index 9295e9e535..6a2f77bd00 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/poller/DirectPollerTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/poller/DirectPollerTests.java
@@ -96,7 +96,7 @@ void testWithError() {
assertEquals("Expected", exception.getCause().getMessage());
}
- private void sleepAndCreateStringInBackground(final long duration) {
+ private void sleepAndCreateStringInBackground(long duration) {
new Thread(() -> {
try {
Thread.sleep(duration);
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/ConcurrentTransactionAwareProxyTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/ConcurrentTransactionAwareProxyTests.java
index 7cd708dd10..664418166f 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/ConcurrentTransactionAwareProxyTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/ConcurrentTransactionAwareProxyTests.java
@@ -112,7 +112,7 @@ void testTransactionalContains() {
assertFalse(result);
}
- private void testSet(final Set set) throws Exception {
+ private void testSet(Set set) throws Exception {
for (int i = 0; i < outerMax; i++) {
@@ -138,7 +138,7 @@ private void testSet(final Set set) throws Exception {
}
- private void testList(final List list, final boolean mutate) throws Exception {
+ private void testList(List list, final boolean mutate) throws Exception {
for (int i = 0; i < outerMax; i++) {
@@ -170,7 +170,7 @@ private void testList(final List list, final boolean mutate) throws Exce
}
- private void testMap(final Map> map) throws Exception {
+ private void testMap(Map> map) throws Exception {
int numberOfKeys = outerMax;
@@ -197,7 +197,7 @@ private void testMap(final Map> map) throws Exception
}
- private String saveInSetAndAssert(final Set set, final String value) {
+ private String saveInSetAndAssert(Set set, final String value) {
new TransactionTemplate(transactionManager).execute((TransactionCallback) status -> {
set.add(value);
@@ -210,7 +210,7 @@ private String saveInSetAndAssert(final Set set, final String value) {
}
- private String saveInListAndAssert(final List list, final String value) {
+ private String saveInListAndAssert(List list, final String value) {
new TransactionTemplate(transactionManager).execute((TransactionCallback) status -> {
list.add(value);
@@ -223,7 +223,7 @@ private String saveInListAndAssert(final List list, final String value)
}
- private Map saveInMapAndAssert(final Map> map, final Long id,
+ private Map saveInMapAndAssert(Map> map, final Long id,
final String value) {
new TransactionTemplate(transactionManager).execute((TransactionCallback) status -> {
diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemProcessor.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemProcessor.java
index dd4f7f90ca..717f445f5c 100644
--- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemProcessor.java
+++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemProcessor.java
@@ -89,7 +89,7 @@ public void setTaskExecutor(TaskExecutor taskExecutor) {
* @see ItemProcessor#process(Object)
*/
@Override
- public @Nullable Future process(final I item) throws Exception {
+ public @Nullable Future process(I item) throws Exception {
final StepExecution stepExecution = getStepExecution();
FutureTask task = new FutureTask<>(() -> {
if (stepExecution != null) {
diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandler.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandler.java
index 80db05d98e..be552b537e 100644
--- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandler.java
+++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandler.java
@@ -248,7 +248,7 @@ protected Set doHandle(StepExecution managerStepExecution,
}
}
- private Set pollReplies(final StepExecution managerStepExecution, final Set split)
+ private Set pollReplies(StepExecution managerStepExecution, final Set split)
throws Exception {
Set partitionStepExecutionIds = split.stream().map(StepExecution::getId).collect(Collectors.toSet());
diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/samples/common/StagingItemWriter.java b/spring-batch-samples/src/main/java/org/springframework/batch/samples/common/StagingItemWriter.java
index 885413988c..f1af92c4f1 100644
--- a/spring-batch-samples/src/main/java/org/springframework/batch/samples/common/StagingItemWriter.java
+++ b/spring-batch-samples/src/main/java/org/springframework/batch/samples/common/StagingItemWriter.java
@@ -73,7 +73,7 @@ public void setIncrementer(DataFieldMaxValueIncrementer incrementer) {
* @see ItemWriter#write(Chunk)
*/
@Override
- public void write(final Chunk extends T> chunk) {
+ public void write(Chunk extends T> chunk) {
final ListIterator extends T> itemIterator = chunk.getItems().listIterator();
getJdbcTemplate().batchUpdate("INSERT into BATCH_STAGING (ID, JOB_ID, VALUE, PROCESSED) values (?,?,?,?)",
diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/StepScopeTestExecutionListener.java b/spring-batch-test/src/main/java/org/springframework/batch/test/StepScopeTestExecutionListener.java
index 3c98d4319a..60c22cfacf 100644
--- a/spring-batch-test/src/main/java/org/springframework/batch/test/StepScopeTestExecutionListener.java
+++ b/spring-batch-test/src/main/java/org/springframework/batch/test/StepScopeTestExecutionListener.java
@@ -33,7 +33,7 @@
* injection into unit tests. A {@link StepContext} will be created for the duration of a
* test method and made available to any dependencies that are injected. The default
* behaviour is just to create a {@link StepExecution} with fixed properties.
- * Alternatively it can be provided by the test case as a factory methods returning the
+ * Alternatively, it can be provided by the test case as a factory methods returning the
* correct type. Example:
*
*
@@ -65,6 +65,7 @@
* @author Dave Syer
* @author Chris Schaefer
* @author Mahmoud Ben Hassine
+ * @author Stefano Cordio
*/
public class StepScopeTestExecutionListener implements TestExecutionListener {
@@ -148,10 +149,9 @@ private static final class ExtractorMethodCallback implements MethodCallback {
private final Class> preferredType;
- private Method result;
+ private @Nullable Method result;
public ExtractorMethodCallback(Class> preferredType, String preferredName) {
- super();
this.preferredType = preferredType;
this.preferredName = preferredName;
}