diff --git a/pom.xml b/pom.xml index 21038acc2a..2609e3258b 100644 --- a/pom.xml +++ b/pom.xml @@ -146,8 +146,8 @@ 3.1.4 3.5.0 0.0.47 - 2.44.0 - 0.12.12 + 2.45.0 + 0.12.14 @@ -180,9 +180,10 @@ -Xplugin:ErrorProne + -Xep:RequireExplicitNullMarking:ERROR -Xep:NullAway:ERROR - -XepOpt:NullAway:JSpecifyMode=true - -XepOpt:NullAway:OnlyNullMarked + -XepOpt:NullAway:JSpecifyMode=true + -XepOpt:NullAway:OnlyNullMarked -XepOpt:NullAway:SuppressionNameAliases=DataFlowIssue -XepExcludedPaths:.*/src/test/java/.* diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/annotation/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/annotation/package-info.java index bb88ba4d60..0c8affb963 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/annotation/package-info.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/annotation/package-info.java @@ -3,4 +3,7 @@ * * @author Michael Minella */ -package org.springframework.batch.core.annotation; \ No newline at end of file +@NullMarked +package org.springframework.batch.core.annotation; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/aot/CoreRuntimeHints.java b/spring-batch-core/src/main/java/org/springframework/batch/core/aot/CoreRuntimeHints.java index 3d79b860f8..2dbe0549b5 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/aot/CoreRuntimeHints.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/aot/CoreRuntimeHints.java @@ -44,6 +44,7 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.aop.SpringProxy; import org.springframework.aop.framework.Advised; import org.springframework.aot.hint.ExecutableMode; @@ -91,7 +92,7 @@ public class CoreRuntimeHints implements RuntimeHintsRegistrar { @Override - public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { Set jdkTypes = Set.of("java.time.Ser", "java.util.Collections$SynchronizedSet", "java.util.Collections$SynchronizedCollection", "java.util.concurrent.locks.ReentrantLock$Sync", diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/aot/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/aot/package-info.java new file mode 100644 index 0000000000..5d59cb7dfe --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/aot/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. + */ + +/** + * Core implementations of Spring AOT concerns. + * + * @author Stefano Cordio + */ +@NullMarked +package org.springframework.batch.core.aot; + +import org.jspecify.annotations.NullMarked; 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 57648e077e..10294649ca 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 @@ -15,6 +15,7 @@ */ package org.springframework.batch.core.job.parameters; +import java.util.Collections; import java.util.List; import org.jspecify.annotations.Nullable; @@ -27,11 +28,11 @@ * * @author Morten Andersen-Gott * @author Mahmoud Ben Hassine - * + * @author Stefano Cordio */ public class CompositeJobParametersValidator implements JobParametersValidator, InitializingBean { - private List validators; + private List validators = Collections.emptyList(); /** * Validates the JobParameters according to the injected JobParameterValidators @@ -57,7 +58,6 @@ public void setValidators(List validators) { @Override public void afterPropertiesSet() throws Exception { - Assert.state(validators != null, "The 'validators' may not be null"); Assert.state(!validators.isEmpty(), "The 'validators' may not be empty"); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/package-info.java new file mode 100644 index 0000000000..3d2ca77691 --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/parameters/package-info.java @@ -0,0 +1,9 @@ +/** + * Job parameter concerns. + * + * @author Stefano Cordio + */ +@NullMarked +package org.springframework.batch.core.job.parameters; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/TaskExecutorJobOperator.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/TaskExecutorJobOperator.java index 1a8df5c97a..26c69605e4 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/TaskExecutorJobOperator.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/TaskExecutorJobOperator.java @@ -110,6 +110,8 @@ public JobExecution start(Job job, JobParameters jobParameters) throws JobInstan Assert.notNull(job, "Job must not be null"); Assert.notNull(jobParameters, "JobParameters must not be null"); new JobLaunchEvent(job.getName(), jobParameters.toString()).commit(); + + @SuppressWarnings("DataFlowIssue") Observation observation = MicrometerMetrics .createObservation(METRICS_PREFIX + "job.launch.count", this.observationRegistry) .start(); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/job/JobExecutionEvent.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/job/JobExecutionEvent.java index 416c524444..a414dbf05f 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/job/JobExecutionEvent.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/job/JobExecutionEvent.java @@ -19,6 +19,7 @@ import jdk.jfr.Description; import jdk.jfr.Event; import jdk.jfr.Label; +import org.jspecify.annotations.Nullable; @Label("Job Execution") @Description("Job Execution Event") @@ -35,7 +36,7 @@ public class JobExecutionEvent extends Event { public long jobExecutionId; @Label("Job Exit Status") - public String exitStatus; + public @Nullable String exitStatus; public JobExecutionEvent(String jobName, long jobInstanceId, long jobExecutionId) { this.jobName = jobName; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/job/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/job/package-info.java new file mode 100644 index 0000000000..f38e7d921f --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/job/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2022-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. + */ + +/** + * Job related JFR events. + */ +@NullMarked +package org.springframework.batch.core.observability.jfr.events.job; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/StepExecutionEvent.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/StepExecutionEvent.java index 6e7784fc79..28cb03fb2b 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/StepExecutionEvent.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/StepExecutionEvent.java @@ -19,6 +19,7 @@ import jdk.jfr.Description; import jdk.jfr.Event; import jdk.jfr.Label; +import org.jspecify.annotations.Nullable; @Label("Step Execution") @Description("Step Execution Event") @@ -38,7 +39,7 @@ public class StepExecutionEvent extends Event { public long jobExecutionId; @Label("Step Exit Status") - public String exitStatus; + public @Nullable String exitStatus; public StepExecutionEvent(String stepName, String jobName, long stepExecutionId, long jobExecutionId) { this.stepName = stepName; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ChunkTransactionEvent.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ChunkTransactionEvent.java index 695f3afcfa..09c873e0a6 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ChunkTransactionEvent.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ChunkTransactionEvent.java @@ -19,6 +19,7 @@ import jdk.jfr.Description; import jdk.jfr.Event; import jdk.jfr.Label; +import org.jspecify.annotations.Nullable; @Label("Chunk Transaction") @Description("Chunk Transaction Event") @@ -32,7 +33,7 @@ public class ChunkTransactionEvent extends Event { public long stepExecutionId; @Label("Transaction Status") - public String transactionStatus; + public @Nullable String transactionStatus; public ChunkTransactionEvent(String stepName, long stepExecutionId) { this.stepName = stepName; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ChunkWriteEvent.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ChunkWriteEvent.java index 6139abb60b..a9ca65edd6 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ChunkWriteEvent.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ChunkWriteEvent.java @@ -19,6 +19,7 @@ import jdk.jfr.Description; import jdk.jfr.Event; import jdk.jfr.Label; +import org.jspecify.annotations.Nullable; @Label("Chunk Write") @Description("Chunk Write Event") @@ -32,7 +33,7 @@ public class ChunkWriteEvent extends Event { public long stepExecutionId; @Label("Chunk Write Status") - public String chunkWriteStatus; + public @Nullable String chunkWriteStatus; @Label("Item Count") public long itemCount; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ItemProcessEvent.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ItemProcessEvent.java index 358794dcff..1221e65048 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ItemProcessEvent.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ItemProcessEvent.java @@ -19,6 +19,7 @@ import jdk.jfr.Description; import jdk.jfr.Event; import jdk.jfr.Label; +import org.jspecify.annotations.Nullable; @Label("Item Process") @Description("Item Process Event") @@ -32,7 +33,7 @@ public class ItemProcessEvent extends Event { public long stepExecutionId; @Label("Item Process Status") - public String itemProcessStatus; + public @Nullable String itemProcessStatus; public ItemProcessEvent(String stepName, long stepExecutionId) { this.stepName = stepName; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ItemReadEvent.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ItemReadEvent.java index 5e55c0de3d..e8d1526abc 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ItemReadEvent.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/ItemReadEvent.java @@ -19,6 +19,7 @@ import jdk.jfr.Description; import jdk.jfr.Event; import jdk.jfr.Label; +import org.jspecify.annotations.Nullable; @Label("Item Read") @Description("Item Read Event") @@ -32,7 +33,7 @@ public class ItemReadEvent extends Event { public long stepExecutionId; @Label("Item Read Status") - public String itemReadStatus; + public @Nullable String itemReadStatus; public ItemReadEvent(String stepName, long stepExecutionId) { this.stepName = stepName; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/package-info.java new file mode 100644 index 0000000000..f6be624553 --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/chunk/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/** + * Chunk related JFR events. + */ +@NullMarked +package org.springframework.batch.core.observability.jfr.events.step.chunk; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/package-info.java new file mode 100644 index 0000000000..17bc8b3420 --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2022-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. + */ + +/** + * Step related JFR events. + */ +@NullMarked +package org.springframework.batch.core.observability.jfr.events.step; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/partition/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/partition/package-info.java new file mode 100644 index 0000000000..14f1d947d2 --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/partition/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/** + * Partition related JFR events. + */ +@NullMarked +package org.springframework.batch.core.observability.jfr.events.step.partition; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/tasklet/TaskletExecutionEvent.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/tasklet/TaskletExecutionEvent.java index 97fbb7b6d7..a83201871f 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/tasklet/TaskletExecutionEvent.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/tasklet/TaskletExecutionEvent.java @@ -19,6 +19,7 @@ import jdk.jfr.Description; import jdk.jfr.Event; import jdk.jfr.Label; +import org.jspecify.annotations.Nullable; @Label("Tasklet Execution") @Description("Tasklet Execution Event") @@ -35,7 +36,7 @@ public class TaskletExecutionEvent extends Event { public String taskletType; @Label("Tasklet Status") - public String taskletStatus; + public @Nullable String taskletStatus; public TaskletExecutionEvent(String stepName, long stepExecutionId, String taskletType) { this.taskletType = taskletType; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/tasklet/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/tasklet/package-info.java new file mode 100644 index 0000000000..469afe193a --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/jfr/events/step/tasklet/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/** + * Tasklet related JFR events. + */ +@NullMarked +package org.springframework.batch.core.observability.jfr.events.step.tasklet; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/micrometer/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/micrometer/package-info.java new file mode 100644 index 0000000000..693449236a --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/micrometer/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/** + * Implementation of Micrometer concerns. + */ +@NullMarked +package org.springframework.batch.core.observability.micrometer; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/package-info.java index 7691904a48..0c6ad666e6 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/observability/package-info.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/observability/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 the original author or authors. + * Copyright 2022-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. @@ -17,4 +17,7 @@ /** * This package contains APIs related to batch observability. */ -package org.springframework.batch.core.observability; \ No newline at end of file +@NullMarked +package org.springframework.batch.core.observability; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/AbstractJdbcBatchMetadataDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/AbstractJdbcBatchMetadataDao.java index 846bfe094a..e8411670ec 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/AbstractJdbcBatchMetadataDao.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/AbstractJdbcBatchMetadataDao.java @@ -82,7 +82,7 @@ public void setJdbcTemplate(JdbcOperations jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } - @Nullable protected JdbcOperations getJdbcTemplate() { + protected @Nullable JdbcOperations getJdbcTemplate() { return jdbcTemplate; } @@ -103,7 +103,7 @@ public void setConversionService(ConfigurableConversionService conversionService this.conversionService = conversionService; } - @Nullable public ConfigurableConversionService getConversionService() { + public @Nullable ConfigurableConversionService getConversionService() { return conversionService; } 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 1feaf76ef7..12203e7d68 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 @@ -155,12 +155,7 @@ public ExecutionContext getExecutionContext(JobExecution jobExecution) { List results = getJdbcTemplate().query(getQuery(FIND_JOB_EXECUTION_CONTEXT), new ExecutionContextRowMapper(), executionId); - if (!results.isEmpty()) { - return results.get(0); - } - else { - return new ExecutionContext(); - } + return results.isEmpty() ? new ExecutionContext() : results.get(0); } @Override @@ -170,12 +165,7 @@ public ExecutionContext getExecutionContext(StepExecution stepExecution) { List results = getJdbcTemplate().query(getQuery(FIND_STEP_EXECUTION_CONTEXT), new ExecutionContextRowMapper(), executionId); - if (results.size() > 0) { - return results.get(0); - } - else { - return new ExecutionContext(); - } + return results.isEmpty() ? new ExecutionContext() : results.get(0); } @Override diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/package-info.java new file mode 100644 index 0000000000..ebb86ca6d6 --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/package-info.java @@ -0,0 +1,9 @@ +/** + * JDBC implementations of dao concerns. + * + * @author Stefano Cordio + */ +@NullMarked +package org.springframework.batch.core.repository.dao.jdbc; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/package-info.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/package-info.java new file mode 100644 index 0000000000..8f0ffd6126 --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/package-info.java @@ -0,0 +1,9 @@ +/** + * MongoDB implementations of dao concerns. + * + * @author Stefano Cordio + */ +@NullMarked +package org.springframework.batch.core.repository.dao.mongodb; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/aot/InfrastructureRuntimeHints.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/aot/InfrastructureRuntimeHints.java index 97934167a4..b39f536792 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/aot/InfrastructureRuntimeHints.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/aot/InfrastructureRuntimeHints.java @@ -15,6 +15,7 @@ */ package org.springframework.batch.infrastructure.aot; +import org.jspecify.annotations.Nullable; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; @@ -71,7 +72,7 @@ public class InfrastructureRuntimeHints implements RuntimeHintsRegistrar { @Override - public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { // reflection hints Set> classes = Set.of( // File IO APIs diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/aot/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/aot/package-info.java new file mode 100644 index 0000000000..7b85fd64f2 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/aot/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. + */ + +/** + * Infrastructure implementations of Spring AOT concerns. + * + * @author Stefano Cordio + */ +@NullMarked +package org.springframework.batch.infrastructure.aot; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/package-info.java index 043937c70d..00d1530afe 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/package-info.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/package-info.java @@ -1,7 +1,21 @@ +/* + * Copyright 2018 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. + */ + /** - *

* Infrastructure interfaces and primary dependencies for item concerns. - *

*/ @NullMarked package org.springframework.batch.infrastructure.item; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/BlockingQueueItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/BlockingQueueItemReader.java index ae4f1b9588..c6ffac181e 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/BlockingQueueItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/BlockingQueueItemReader.java @@ -20,7 +20,6 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; -import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; /** @@ -32,7 +31,7 @@ * @author Mahmoud Ben Hassine * @since 5.2.0 */ -public class BlockingQueueItemReader implements ItemReader<@NonNull T> { +public class BlockingQueueItemReader implements ItemReader { private final BlockingQueue queue; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/BlockingQueueItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/BlockingQueueItemWriter.java index 4ede1a9be1..13a2fc6c46 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/BlockingQueueItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/BlockingQueueItemWriter.java @@ -20,8 +20,6 @@ import java.util.concurrent.BlockingQueue; -import org.jspecify.annotations.NonNull; - /** * This is an {@link ItemWriter} that writes items to a {@link BlockingQueue}. * @@ -29,7 +27,7 @@ * @since 5.2.0 * @author Mahmoud Ben Hassine */ -public class BlockingQueueItemWriter implements ItemWriter<@NonNull T> { +public class BlockingQueueItemWriter implements ItemWriter { private final BlockingQueue queue; @@ -42,7 +40,7 @@ public BlockingQueueItemWriter(BlockingQueue queue) { } @Override - public void write(Chunk items) throws Exception { + public void write(Chunk items) throws Exception { for (T item : items) { this.queue.put(item); } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/builder/BlockingQueueItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/builder/BlockingQueueItemReaderBuilder.java index fbe1fe07da..a4beb64d2d 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/builder/BlockingQueueItemReaderBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/builder/BlockingQueueItemReaderBuilder.java @@ -18,6 +18,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.batch.infrastructure.item.queue.BlockingQueueItemReader; import org.springframework.util.Assert; @@ -30,7 +31,7 @@ */ public class BlockingQueueItemReaderBuilder { - private BlockingQueue queue; + private @Nullable BlockingQueue queue; private long timeout = 1L; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/builder/BlockingQueueItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/builder/BlockingQueueItemWriterBuilder.java index 40701e8fca..8284ad6b6d 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/builder/BlockingQueueItemWriterBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/builder/BlockingQueueItemWriterBuilder.java @@ -17,6 +17,7 @@ import java.util.concurrent.BlockingQueue; +import org.jspecify.annotations.Nullable; import org.springframework.batch.infrastructure.item.queue.BlockingQueueItemWriter; import org.springframework.util.Assert; @@ -29,7 +30,7 @@ */ public class BlockingQueueItemWriterBuilder { - private BlockingQueue queue; + private @Nullable BlockingQueue queue; /** * Create a new {@link BlockingQueueItemWriterBuilder} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/builder/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/builder/package-info.java new file mode 100644 index 0000000000..5504f203c4 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/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 Apache Kafka item reader and writer. + * + * @author Stefano Cordio + */ +@NullMarked +package org.springframework.batch.infrastructure.item.queue.builder; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/package-info.java new file mode 100644 index 0000000000..3c1e91e048 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/queue/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. + */ + +/** + * {@link java.util.concurrent.BlockingQueue} related readers and writers. + * + * @author Stefano Cordio + */ +@NullMarked +package org.springframework.batch.infrastructure.item.queue; + +import org.jspecify.annotations.NullMarked; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/builder/RedisItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/builder/RedisItemReaderBuilder.java index 1ee9d6efe9..a8a10173ee 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/builder/RedisItemReaderBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/builder/RedisItemReaderBuilder.java @@ -15,9 +15,11 @@ */ package org.springframework.batch.infrastructure.item.redis.builder; +import org.jspecify.annotations.Nullable; import org.springframework.batch.infrastructure.item.redis.RedisItemReader; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ScanOptions; +import org.springframework.util.Assert; /** * Builder for {@link RedisItemReader}. @@ -29,9 +31,9 @@ */ public class RedisItemReaderBuilder { - private RedisTemplate redisTemplate; + private @Nullable RedisTemplate redisTemplate; - private ScanOptions scanOptions; + private @Nullable ScanOptions scanOptions; /** * Set the {@link RedisTemplate} to use in the reader. @@ -58,6 +60,8 @@ public RedisItemReaderBuilder scanOptions(ScanOptions scanOptions) { * @return a new item reader */ public RedisItemReader build() { + Assert.notNull(redisTemplate, "redisTemplate must not be null"); + Assert.notNull(scanOptions, "scanOptions must no be null"); return new RedisItemReader<>(this.redisTemplate, this.scanOptions); } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/builder/RedisItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/builder/RedisItemWriterBuilder.java index 5e0eb3aac7..9c5db2b7c0 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/builder/RedisItemWriterBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/builder/RedisItemWriterBuilder.java @@ -15,8 +15,7 @@ */ package org.springframework.batch.infrastructure.item.redis.builder; -import org.jspecify.annotations.NonNull; - +import org.jspecify.annotations.Nullable; import org.springframework.batch.infrastructure.item.redis.RedisItemWriter; import org.springframework.core.convert.converter.Converter; import org.springframework.data.redis.core.RedisTemplate; @@ -30,9 +29,9 @@ */ public class RedisItemWriterBuilder { - private RedisTemplate redisTemplate; + private @Nullable RedisTemplate redisTemplate; - private Converter<@NonNull V, @NonNull K> itemKeyMapper; + private @Nullable Converter itemKeyMapper; private boolean delete; @@ -53,7 +52,7 @@ public RedisItemWriterBuilder redisTemplate(RedisTemplate redisTempl * @return The current instance of the builder. * @see RedisItemWriter#setItemKeyMapper(Converter) */ - public RedisItemWriterBuilder itemKeyMapper(Converter<@NonNull V, @NonNull K> itemKeyMapper) { + public RedisItemWriterBuilder itemKeyMapper(Converter itemKeyMapper) { this.itemKeyMapper = itemKeyMapper; return this; } @@ -73,11 +72,11 @@ public RedisItemWriterBuilder delete(boolean delete) { * Validates and builds a {@link RedisItemWriter}. * @return a {@link RedisItemWriter} */ - public RedisItemWriter<@NonNull K, @NonNull V> build() { + public RedisItemWriter build() { Assert.notNull(this.redisTemplate, "RedisTemplate is required."); Assert.notNull(this.itemKeyMapper, "itemKeyMapper is required."); - RedisItemWriter<@NonNull K, @NonNull V> writer = new RedisItemWriter<>(this.itemKeyMapper, this.redisTemplate); + RedisItemWriter writer = new RedisItemWriter<>(this.itemKeyMapper, this.redisTemplate); writer.setDelete(this.delete); return writer; } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/builder/package-info.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/builder/package-info.java new file mode 100644 index 0000000000..4ce00ad2f5 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/infrastructure/item/redis/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 Redis item reader and writer. + * + * @author Stefano Cordio + */ +@NullMarked +package org.springframework.batch.infrastructure.item.redis.builder; + +import org.jspecify.annotations.NullMarked;