From 2a8110ef1771eca685a66237f2f7119a4ec4913b Mon Sep 17 00:00:00 2001 From: Pranav Jandu Date: Sat, 13 May 2023 11:10:16 +0530 Subject: [PATCH 01/68] Update SQLServer DDL script to drop sequences instead of tables Resolves #4373 (cherry picked from commit 384b8a095ccf67a30c995ce849a5b8cf7c4af575) --- .../springframework/batch/core/schema-drop-sqlserver.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlserver.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlserver.sql index d217ec569b..247ae20760 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlserver.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlserver.sql @@ -7,6 +7,6 @@ DROP TABLE BATCH_JOB_EXECUTION_PARAMS; DROP TABLE BATCH_JOB_EXECUTION; DROP TABLE BATCH_JOB_INSTANCE; -DROP TABLE BATCH_STEP_EXECUTION_SEQ; -DROP TABLE BATCH_JOB_EXECUTION_SEQ; -DROP TABLE BATCH_JOB_SEQ; +DROP SEQUENCE BATCH_STEP_EXECUTION_SEQ; +DROP SEQUENCE BATCH_JOB_EXECUTION_SEQ; +DROP SEQUENCE BATCH_JOB_SEQ; From 8abd313ae4fbd8589b51ebd62a4fa15e394f42cb Mon Sep 17 00:00:00 2001 From: Kim Seon Woo Date: Tue, 27 Jun 2023 23:46:00 +0900 Subject: [PATCH 02/68] Fix javadoc of SimpleStepBuilder Resolves #4402 Author: Seon Woo Kim (cherry picked from commit 1c4822313aab75a34614d330df4d169eeaaf9199) --- .../batch/core/step/builder/SimpleStepBuilder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java index 9bf252cbd2..aa51c34e54 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 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. @@ -58,8 +58,8 @@ /** * Step builder for simple item processing (chunk oriented) steps. Items are read and - * cached in chunks, and then processed (transformed) and written (optionally either the - * processor or the writer can be omitted) all in the same transaction. + * cached in chunks, and then processed (transformed) and written (optionally the + * processor can be omitted) all in the same transaction. * * @see FaultTolerantStepBuilder for a step that handles retry and skip of failed items * @author Dave Syer From 26fc7bac4e447a6fae997328f3a955d328a6c174 Mon Sep 17 00:00:00 2001 From: BigLee Date: Sun, 4 Jun 2023 17:01:28 +0900 Subject: [PATCH 03/68] Update migration-h2.sql script to use ALTER instead of MODIFY Resolves #4390 (cherry picked from commit 37fb3f94927c8e5bff8a0a674fc83747a2410a0a) --- .../batch/core/migration/5.0/migration-h2.sql | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/migration/5.0/migration-h2.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/migration/5.0/migration-h2.sql index 8916a0f04e..5bdac69327 100644 --- a/spring-batch-core/src/main/resources/org/springframework/batch/core/migration/5.0/migration-h2.sql +++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/migration/5.0/migration-h2.sql @@ -5,9 +5,12 @@ ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN DATE_VAL; ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN LONG_VAL; ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN DOUBLE_VAL; -ALTER TABLE BATCH_JOB_EXECUTION_PARAMS MODIFY COLUMN TYPE_CD PARAMETER_TYPE VARCHAR(100); -ALTER TABLE BATCH_JOB_EXECUTION_PARAMS MODIFY COLUMN KEY_NAME PARAMETER_NAME VARCHAR(100); -ALTER TABLE BATCH_JOB_EXECUTION_PARAMS MODIFY COLUMN STRING_VAL PARAMETER_VALUE VARCHAR(2500); +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN TYPE_CD RENAME TO PARAMETER_TYPE; +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN PARAMETER_TYPE SET DATA TYPE VARCHAR(100); +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN KEY_NAME RENAME TO PARAMETER_NAME; +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN PARAMETER_NAME SET DATA TYPE VARCHAR(100); +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN STRING_VAL RENAME TO PARAMETER_VALUE; +ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN PARAMETER_VALUE SET DATA TYPE VARCHAR(2500); ALTER TABLE BATCH_JOB_EXECUTION ALTER COLUMN CREATE_TIME SET DATA TYPE TIMESTAMP(9); ALTER TABLE BATCH_JOB_EXECUTION ALTER COLUMN START_TIME SET DATA TYPE TIMESTAMP(9); @@ -17,4 +20,4 @@ ALTER TABLE BATCH_JOB_EXECUTION ALTER COLUMN LAST_UPDATED SET DATA TYPE TIMESTAM ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN CREATE_TIME SET DATA TYPE TIMESTAMP(9); ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN START_TIME SET DATA TYPE TIMESTAMP(9); ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN END_TIME SET DATA TYPE TIMESTAMP(9); -ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN LAST_UPDATED SET DATA TYPE TIMESTAMP(9); \ No newline at end of file +ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN LAST_UPDATED SET DATA TYPE TIMESTAMP(9); From 5b9beecb893df1b737ec3bcef30c5c0fe61d87b4 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Mon, 17 Jul 2023 11:08:38 +0200 Subject: [PATCH 04/68] Document the type and name of the surrounding job in JobLauncherTestUtils#launchStep Resolves #3825 (cherry picked from commit 5e849c6c9531f4cc0197763be545b2594b709a6a) --- .../batch/test/JobLauncherTestUtils.java | 24 +++++++------ .../batch/test/StepRunner.java | 36 +++++++++++-------- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java b/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java index dbeb4dab21..b1a4da0f27 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java @@ -177,9 +177,10 @@ protected StepRunner getStepRunner() { } /** - * Launch just the specified step in the job. A unique set of JobParameters will - * automatically be generated. An IllegalStateException is thrown if there is no Step - * with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. A unique set of JobParameters + * will automatically be generated. An IllegalStateException is thrown if there is no + * Step with the given name. * @param stepName The name of the step to launch * @return JobExecution */ @@ -188,9 +189,10 @@ public JobExecution launchStep(String stepName) { } /** - * Launch just the specified step in the job. A unique set of JobParameters will - * automatically be generated. An IllegalStateException is thrown if there is no Step - * with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. A unique set of JobParameters + * will automatically be generated. An IllegalStateException is thrown if there is no + * Step with the given name. * @param stepName The name of the step to launch * @param jobExecutionContext An ExecutionContext whose values will be loaded into the * Job ExecutionContext prior to launching the step. @@ -201,8 +203,9 @@ public JobExecution launchStep(String stepName, ExecutionContext jobExecutionCon } /** - * Launch just the specified step in the job. An IllegalStateException is thrown if - * there is no Step with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. An IllegalStateException is + * thrown if there is no Step with the given name. * @param stepName The name of the step to launch * @param jobParameters The JobParameters to use during the launch * @return JobExecution @@ -212,8 +215,9 @@ public JobExecution launchStep(String stepName, JobParameters jobParameters) { } /** - * Launch just the specified step in the job. An IllegalStateException is thrown if - * there is no Step with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. An IllegalStateException is + * thrown if there is no Step with the given name. * @param stepName The name of the step to launch * @param jobParameters The JobParameters to use during the launch * @param jobExecutionContext An ExecutionContext whose values will be loaded into the diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/StepRunner.java b/spring-batch-test/src/main/java/org/springframework/batch/test/StepRunner.java index d60a129f38..2f1bc86801 100755 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/StepRunner.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/StepRunner.java @@ -42,9 +42,8 @@ import org.springframework.lang.Nullable; /** - * Utility class for executing steps outside of a {@link Job}. This is useful in end to - * end testing in order to allow for the testing of a step individually without running - * every Step in a job. + * Utility class for executing steps. This is useful in end to end testing in order to + * allow for the testing of a step individually without running every Step in a job. * *
    *
  • launchStep(Step step): Launch the step with new parameters each time. (The @@ -67,6 +66,11 @@ */ public class StepRunner { + /** + * Name of the single-step job surrounding steps when tested individually + */ + public static final String JOB_NAME = "TestJob"; + /** Logger */ protected final Log logger = LogFactory.getLog(getClass()); @@ -80,9 +84,10 @@ public StepRunner(JobLauncher launcher, JobRepository jobRepository) { } /** - * Launch just the specified step as its own job. A unique set of JobParameters will - * automatically be generated. An IllegalStateException is thrown if there is no Step - * with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. A unique set of JobParameters + * will automatically be generated. An IllegalStateException is thrown if there is no + * Step with the given name. * @param step The step to launch * @return JobExecution */ @@ -91,9 +96,10 @@ public JobExecution launchStep(Step step) { } /** - * Launch just the specified step as its own job. A unique set of JobParameters will - * automatically be generated. An IllegalStateException is thrown if there is no Step - * with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. A unique set of JobParameters + * will automatically be generated. An IllegalStateException is thrown if there is no + * Step with the given name. * @param step The step to launch * @param jobExecutionContext An ExecutionContext whose values will be loaded into the * Job ExecutionContext prior to launching the step. @@ -104,8 +110,9 @@ public JobExecution launchStep(Step step, @Nullable ExecutionContext jobExecutio } /** - * Launch just the specified step as its own job. An IllegalStateException is thrown - * if there is no Step with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. An IllegalStateException is + * thrown if there is no Step with the given name. * @param step The step to launch * @param jobParameters The JobParameters to use during the launch * @return JobExecution @@ -115,8 +122,9 @@ public JobExecution launchStep(Step step, JobParameters jobParameters) { } /** - * Launch just the specified step as its own job. An IllegalStateException is thrown - * if there is no Step with the given name. + * Launch just the specified step in a surrounding single-step job of type + * {@link SimpleJob} named {@link StepRunner#JOB_NAME}. An IllegalStateException is + * thrown if there is no Step with the given name. * @param step The step to launch * @param jobParameters The JobParameters to use during the launch * @param jobExecutionContext An ExecutionContext whose values will be loaded into the @@ -129,7 +137,7 @@ public JobExecution launchStep(Step step, JobParameters jobParameters, // Create a fake job // SimpleJob job = new SimpleJob(); - job.setName("TestJob"); + job.setName(JOB_NAME); job.setJobRepository(this.jobRepository); List stepsToExecute = new ArrayList<>(); From 1d197daffc6fde140619b20784bff25a62f874ec Mon Sep 17 00:00:00 2001 From: Stefano Cordio Date: Sat, 20 May 2023 15:48:19 +0200 Subject: [PATCH 05/68] Fix typo in SimpleMailMessageItemWriter Javadoc (cherry picked from commit aaa0aee44f6dfe53744de5ca6363255291d5996f) --- .../batch/item/mail/SimpleMailMessageItemWriter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriter.java index 1964276b72..65cf843acb 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 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. @@ -40,8 +40,8 @@ * Delegates the actual sending of messages to a {@link MailSender}, using the batch * method {@link MailSender#send(SimpleMailMessage[])}, which normally uses a single * server connection for the whole batch (depending on the implementation). The efficiency - * of for large volumes of messages (repeated calls to the item writer) might be improved - * by the use of a special {@link MailSender} that caches connections to the server in + * for large volumes of messages (repeated calls to the item writer) might be improved by + * the use of a special {@link MailSender} that caches connections to the server in * between calls. *

    * From 7cec17a9c695235997800eed09f4c2c96cacca62 Mon Sep 17 00:00:00 2001 From: Shaoqiang Lu Date: Wed, 26 Jul 2023 20:09:10 +0800 Subject: [PATCH 06/68] Auto-detect the class/interface to be mocked Issue #4426 (cherry picked from commit 1add2830f514a851d10bc72879b28bffc6991bd8) --- .../batch/core/JobParametersBuilderTests.java | 2 +- .../annotation/BatchRegistrarTests.java | 12 +++--- .../support/AutomaticJobRegistrarTests.java | 2 +- .../support/JobExplorerFactoryBeanTests.java | 8 ++-- .../support/SimpleJobExplorerTests.java | 8 ++-- .../CompositeJobParametersValidatorTests.java | 4 +- .../batch/core/job/SimpleJobTests.java | 2 +- .../flow/support/state/SplitStateTests.java | 8 ++-- .../launch/TaskExecutorJobLauncherTests.java | 12 +++--- ...MaxValueJobParametersIncrementerTests.java | 2 +- .../support/JobOperatorFactoryBeanTests.java | 14 +++---- .../support/SimpleJobOperatorTests.java | 22 +++++----- .../listener/CompositeChunkListenerTests.java | 2 +- .../CompositeItemProcessListenerTests.java | 2 +- .../CompositeItemReadListenerTests.java | 2 +- .../CompositeItemWriteListenerTests.java | 2 +- .../dao/JdbcExecutionContextDaoTests.java | 2 +- .../JobRepositoryFactoryBeanTests.java | 30 ++++++------- .../support/SimpleJobRepositoryTests.java | 20 ++++----- ...erantStepFactoryBeanNonBufferingTests.java | 2 +- .../MethodInvokingTaskletAdapterTests.java | 4 +- .../SystemCommandTaskletIntegrationTests.java | 8 ++-- .../BatchMessageListenerContainerTests.java | 18 ++++---- .../batch/item/amqp/AmqpItemReaderTests.java | 12 +++--- .../batch/item/amqp/AmqpItemWriterTests.java | 2 +- .../builder/AmqpItemReaderBuilderTests.java | 2 +- .../builder/AmqpItemWriterBuilderTests.java | 2 +- .../batch/item/data/MongoItemWriterTests.java | 6 +-- .../item/data/RepositoryItemReaderTests.java | 2 +- ...xtendedConnectionDataSourceProxyTests.java | 16 +++---- ...sorItemReaderStatefulIntegrationTests.java | 6 +-- .../HibernateItemReaderHelperTests.java | 6 +-- .../database/HibernateItemWriterTests.java | 4 +- .../JdbcBatchItemWriterClassicTests.java | 2 +- ...dbcBatchItemWriterNamedParameterTests.java | 2 +- .../JdbcCursorItemReaderConfigTests.java | 18 ++++---- .../item/database/JpaItemWriterTests.java | 8 ++-- .../StoredprocedureItemReaderConfigTests.java | 24 +++++------ ...StoredProcedureItemReaderBuilderTests.java | 2 +- .../orm/JpaNamedQueryProviderTests.java | 4 +- ...lumnMapExecutionContextRowMapperTests.java | 2 +- ...aFieldMaxValueIncrementerFactoryTests.java | 2 +- .../DerbyPagingQueryProviderTests.java | 18 ++++---- .../HibernateNativeQueryProviderTests.java | 8 ++-- .../support/JpaNativeQueryProviderTests.java | 4 +- .../file/mapping/DefaultLineMapperTests.java | 4 +- .../batch/item/jms/JmsItemReaderTests.java | 12 +++--- .../batch/item/jms/JmsItemWriterTests.java | 2 +- .../JmsMethodArgumentsKeyGeneratorTests.java | 2 +- .../JmsMethodInvocationRecovererTests.java | 2 +- .../JmsNewMethodArgumentsIdentifierTests.java | 2 +- .../builder/JmsItemReaderBuilderTests.java | 8 ++-- .../builder/JmsItemWriterBuilderTests.java | 2 +- .../JsonFileItemWriterBuilderTests.java | 8 ++-- .../SimpleMailMessageItemWriterTests.java | 2 +- ...mpleMailMessageItemWriterBuilderTests.java | 2 +- .../javamail/MimeMessageItemWriterTests.java | 2 +- .../support/CompositeItemProcessorTests.java | 8 ++-- .../support/CompositeItemWriterTests.java | 4 +- .../CompositeItemWriterBuilderTests.java | 8 ++-- .../ValidatingItemProcessorTests.java | 2 +- .../item/xml/StaxEventItemReaderTests.java | 8 ++-- .../item/xml/StaxEventItemWriterTests.java | 2 +- .../stax/AbstractEventReaderWrapperTests.java | 8 ++-- .../stax/AbstractEventWriterWrapperTests.java | 10 ++--- .../stax/NoStartEndDocumentWriterTests.java | 2 +- ...osedElementCollectingEventWriterTests.java | 2 +- ...nopenedElementClosingEventWriterTests.java | 4 +- .../batch/support/DatabaseTypeTestUtils.java | 8 ++-- .../TransactionAwareBufferedWriterTests.java | 4 +- ...RemoteChunkingManagerStepBuilderTests.java | 12 +++--- .../launch/JobLaunchingGatewayTests.java | 2 +- .../MessageChannelPartitionHandlerTests.java | 42 +++++++++---------- ...tePartitioningManagerStepBuilderTests.java | 6 +-- .../domain/order/OrderItemReaderTests.java | 4 +- .../trade/CustomerUpdateProcessorTests.java | 4 +- ...ditUpdatePreparedStatementSetterTests.java | 2 +- .../CustomerCreditUpdateProcessorTests.java | 2 +- .../FlatFileCustomerCreditDaoTests.java | 2 +- .../trade/internal/TradeProcessorTests.java | 2 +- .../quartz/JobLauncherDetailsTests.java | 2 +- .../support/AbstractRowMapperTests.java | 2 +- .../BatchTestContextCustomizerTests.java | 8 ++-- 83 files changed, 274 insertions(+), 274 deletions(-) diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java index a79efcca41..2f5cdb5d6e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java @@ -61,7 +61,7 @@ class JobParametersBuilderTests { @BeforeEach void initialize() { this.job = new SimpleJob("simpleJob"); - this.jobExplorer = mock(JobExplorer.class); + this.jobExplorer = mock(); this.jobInstanceList = new ArrayList<>(1); this.jobExecutionList = new ArrayList<>(1); this.parametersBuilder = new JobParametersBuilder(this.jobExplorer); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java index 066db5b3c7..b07fc71e7e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/BatchRegistrarTests.java @@ -179,7 +179,7 @@ public static class JobConfigurationWithoutTransactionManager { @Bean public DataSource dataSource() { - return Mockito.mock(DataSource.class); + return Mockito.mock(); } } @@ -190,27 +190,27 @@ public static class JobConfigurationWithUserDefinedInfrastructureBeans { @Bean public JobRepository jobRepository() { - return Mockito.mock(JobRepository.class); + return Mockito.mock(); } @Bean public JobExplorer jobExplorer() { - return Mockito.mock(JobExplorer.class); + return Mockito.mock(); } @Bean public JobLauncher jobLauncher() { - return Mockito.mock(JobLauncher.class); + return Mockito.mock(); } @Bean public JobRegistry jobRegistry() { - return Mockito.mock(JobRegistry.class); + return Mockito.mock(); } @Bean public JobOperator jobOperator() { - return Mockito.mock(JobOperator.class); + return Mockito.mock(); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/AutomaticJobRegistrarTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/AutomaticJobRegistrarTests.java index c58894659f..61112f4768 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/AutomaticJobRegistrarTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/AutomaticJobRegistrarTests.java @@ -183,7 +183,7 @@ void testStartStopRunning() { @Test void testStartStopRunningWithCallback() { - Runnable callback = Mockito.mock(Runnable.class); + Runnable callback = Mockito.mock(); Resource[] jobPaths = new Resource[] { new ClassPathResource("org/springframework/batch/core/launch/support/2jobs.xml") }; setUpApplicationContextFactories(jobPaths, null); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBeanTests.java index fa7cef0e7c..5f8b13913b 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBeanTests.java @@ -54,8 +54,8 @@ class JobExplorerFactoryBeanTests { void setUp() { factory = new JobExplorerFactoryBean(); - DataSource dataSource = mock(DataSource.class); - PlatformTransactionManager transactionManager = mock(PlatformTransactionManager.class); + DataSource dataSource = mock(); + PlatformTransactionManager transactionManager = mock(); factory.setDataSource(dataSource); factory.setTransactionManager(transactionManager); factory.setTablePrefix(tablePrefix); @@ -73,7 +73,7 @@ void testDefaultJdbcOperations() throws Exception { @Test void testCustomJdbcOperations() throws Exception { - JdbcOperations customJdbcOperations = mock(JdbcOperations.class); + JdbcOperations customJdbcOperations = mock(); factory.setJdbcOperations(customJdbcOperations); factory.afterPropertiesSet(); assertEquals(customJdbcOperations, ReflectionTestUtils.getField(factory, "jdbcOperations")); @@ -111,7 +111,7 @@ void testCreateExplorer() throws Exception { @Test public void testCustomTransactionAttributesSource() throws Exception { // given - TransactionAttributeSource transactionAttributeSource = Mockito.mock(TransactionAttributeSource.class); + TransactionAttributeSource transactionAttributeSource = Mockito.mock(); this.factory.setTransactionAttributeSource(transactionAttributeSource); this.factory.afterPropertiesSet(); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java index 8b275d9c7d..7e7122d0b0 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/SimpleJobExplorerTests.java @@ -65,10 +65,10 @@ class SimpleJobExplorerTests { @BeforeEach void setUp() { - jobExecutionDao = mock(JobExecutionDao.class); - jobInstanceDao = mock(JobInstanceDao.class); - stepExecutionDao = mock(StepExecutionDao.class); - ecDao = mock(ExecutionContextDao.class); + jobExecutionDao = mock(); + jobInstanceDao = mock(); + stepExecutionDao = mock(); + ecDao = mock(); jobExplorer = new SimpleJobExplorer(jobInstanceDao, jobExecutionDao, stepExecutionDao, ecDao); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/CompositeJobParametersValidatorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/CompositeJobParametersValidatorTests.java index 767df315e3..93694fc764 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/CompositeJobParametersValidatorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/CompositeJobParametersValidatorTests.java @@ -52,7 +52,7 @@ void testValidatorsCanNotBeEmpty() { @Test void testDelegateIsInvoked() throws JobParametersInvalidException { - JobParametersValidator validator = mock(JobParametersValidator.class); + JobParametersValidator validator = mock(); validator.validate(parameters); compositeJobParametersValidator.setValidators(Arrays.asList(validator)); compositeJobParametersValidator.validate(parameters); @@ -60,7 +60,7 @@ void testDelegateIsInvoked() throws JobParametersInvalidException { @Test void testDelegatesAreInvoked() throws JobParametersInvalidException { - JobParametersValidator validator = mock(JobParametersValidator.class); + JobParametersValidator validator = mock(); validator.validate(parameters); validator.validate(parameters); compositeJobParametersValidator.setValidators(Arrays.asList(validator, validator)); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java index ff0ea2a720..29b359ab47 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/SimpleJobTests.java @@ -416,7 +416,7 @@ void testRestart() throws Exception { void testInterruptWithListener() { step1.setProcessException(new JobInterruptedException("job interrupted!")); - JobExecutionListener listener = mock(JobExecutionListener.class); + JobExecutionListener listener = mock(); listener.beforeJob(jobExecution); listener.afterJob(jobExecution); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/SplitStateTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/SplitStateTests.java index 0e89afd8d8..c864d1fbab 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/SplitStateTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/SplitStateTests.java @@ -43,8 +43,8 @@ class SplitStateTests { void testBasicHandling() throws Exception { Collection flows = new ArrayList<>(); - Flow flow1 = mock(Flow.class); - Flow flow2 = mock(Flow.class); + Flow flow1 = mock(); + Flow flow2 = mock(); flows.add(flow1); flows.add(flow2); @@ -61,8 +61,8 @@ void testBasicHandling() throws Exception { @Test void testConcurrentHandling() throws Exception { - Flow flow1 = mock(Flow.class); - Flow flow2 = mock(Flow.class); + Flow flow1 = mock(); + Flow flow2 = mock(); SplitState state = new SplitState(Arrays.asList(flow1, flow2), "foo"); state.setTaskExecutor(new SimpleAsyncTaskExecutor()); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/TaskExecutorJobLauncherTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/TaskExecutorJobLauncherTests.java index a1109852c6..2d8863826e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/TaskExecutorJobLauncherTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/TaskExecutorJobLauncherTests.java @@ -72,7 +72,7 @@ public void execute(JobExecution execution) { void setUp() { jobLauncher = new TaskExecutorJobLauncher(); - jobRepository = mock(JobRepository.class); + jobRepository = mock(); jobLauncher.setJobRepository(jobRepository); } @@ -265,13 +265,13 @@ void testRunStepStatusStopping() { private void testRestartStepExecutionInvalidStatus(BatchStatus status) throws Exception { String jobName = "test_job"; - JobRepository jobRepository = mock(JobRepository.class); + JobRepository jobRepository = mock(); JobParameters parameters = new JobParametersBuilder().addLong("runtime", System.currentTimeMillis()) .toJobParameters(); - JobExecution jobExecution = mock(JobExecution.class); - Job job = mock(Job.class); - JobParametersValidator validator = mock(JobParametersValidator.class); - StepExecution stepExecution = mock(StepExecution.class); + JobExecution jobExecution = mock(); + Job job = mock(); + JobParametersValidator validator = mock(); + StepExecution stepExecution = mock(); when(job.getName()).thenReturn(jobName); when(job.isRestartable()).thenReturn(true); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementerTests.java index 60d55e1680..a56457d06f 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/DataFieldMaxValueJobParametersIncrementerTests.java @@ -31,7 +31,7 @@ */ class DataFieldMaxValueJobParametersIncrementerTests { - private final DataFieldMaxValueIncrementer incrementer = mock(DataFieldMaxValueIncrementer.class); + private final DataFieldMaxValueIncrementer incrementer = mock(); @Test void testInvalidKey() { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBeanTests.java index b984fe438e..c09cbe5925 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBeanTests.java @@ -39,17 +39,17 @@ */ class JobOperatorFactoryBeanTests { - private final PlatformTransactionManager transactionManager = Mockito.mock(PlatformTransactionManager.class); + private final PlatformTransactionManager transactionManager = Mockito.mock(); - private final JobRepository jobRepository = Mockito.mock(JobRepository.class); + private final JobRepository jobRepository = Mockito.mock(); - private final JobLauncher jobLauncher = Mockito.mock(JobLauncher.class); + private final JobLauncher jobLauncher = Mockito.mock(); - private final JobRegistry jobRegistry = Mockito.mock(JobRegistry.class); + private final JobRegistry jobRegistry = Mockito.mock(); - private final JobExplorer jobExplorer = Mockito.mock(JobExplorer.class); + private final JobExplorer jobExplorer = Mockito.mock(); - private final JobParametersConverter jobParametersConverter = Mockito.mock(JobParametersConverter.class); + private final JobParametersConverter jobParametersConverter = Mockito.mock(); @Test public void testJobOperatorCreation() throws Exception { @@ -76,7 +76,7 @@ public void testJobOperatorCreation() throws Exception { @Test public void testCustomTransactionAttributesSource() throws Exception { // given - TransactionAttributeSource transactionAttributeSource = Mockito.mock(TransactionAttributeSource.class); + TransactionAttributeSource transactionAttributeSource = Mockito.mock(); JobOperatorFactoryBean jobOperatorFactoryBean = new JobOperatorFactoryBean(); jobOperatorFactoryBean.setTransactionManager(this.transactionManager); jobOperatorFactoryBean.setJobLauncher(this.jobLauncher); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java index 32f01dae7a..d5d3951c2c 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/SimpleJobOperatorTests.java @@ -120,11 +120,11 @@ public Set getJobNames() { jobOperator.setJobLauncher( (job, jobParameters) -> new JobExecution(new JobInstance(123L, job.getName()), 999L, jobParameters)); - jobExplorer = mock(JobExplorer.class); + jobExplorer = mock(); jobOperator.setJobExplorer(jobExplorer); - jobRepository = mock(JobRepository.class); + jobRepository = mock(); jobOperator.setJobRepository(jobRepository); jobOperator.setJobParametersConverter(new DefaultJobParametersConverter() { @@ -288,7 +288,7 @@ public void testGetJobInstanceWithNameAndParameters() { // given String jobName = "job"; JobParameters jobParameters = new JobParameters(); - JobInstance jobInstance = mock(JobInstance.class); + JobInstance jobInstance = mock(); // when when(this.jobExplorer.getJobInstance(jobName, jobParameters)).thenReturn(jobInstance); @@ -338,14 +338,14 @@ void testStop() throws Exception { void testStopTasklet() throws Exception { JobInstance jobInstance = new JobInstance(123L, job.getName()); JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); - StoppableTasklet tasklet = mock(StoppableTasklet.class); + StoppableTasklet tasklet = mock(); TaskletStep taskletStep = new TaskletStep(); taskletStep.setTasklet(tasklet); MockJob job = new MockJob(); job.taskletStep = taskletStep; - JobRegistry jobRegistry = mock(JobRegistry.class); - TaskletStep step = mock(TaskletStep.class); + JobRegistry jobRegistry = mock(); + TaskletStep step = mock(); when(step.getTasklet()).thenReturn(tasklet); when(step.getName()).thenReturn("test_job.step1"); @@ -363,9 +363,9 @@ void testStopTasklet() throws Exception { void testStopTaskletWhenJobNotRegistered() throws Exception { JobInstance jobInstance = new JobInstance(123L, job.getName()); JobExecution jobExecution = new JobExecution(jobInstance, 111L, jobParameters); - StoppableTasklet tasklet = mock(StoppableTasklet.class); - JobRegistry jobRegistry = mock(JobRegistry.class); - TaskletStep step = mock(TaskletStep.class); + StoppableTasklet tasklet = mock(); + JobRegistry jobRegistry = mock(); + TaskletStep step = mock(); when(step.getTasklet()).thenReturn(tasklet); when(jobRegistry.getJob(job.getName())).thenThrow(new NoSuchJobException("Unable to find job")); @@ -399,8 +399,8 @@ public void stop() { MockJob job = new MockJob(); job.taskletStep = taskletStep; - JobRegistry jobRegistry = mock(JobRegistry.class); - TaskletStep step = mock(TaskletStep.class); + JobRegistry jobRegistry = mock(); + TaskletStep step = mock(); when(step.getTasklet()).thenReturn(tasklet); when(step.getName()).thenReturn("test_job.step1"); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeChunkListenerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeChunkListenerTests.java index 3d1284b060..1ae514a1a1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeChunkListenerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeChunkListenerTests.java @@ -39,7 +39,7 @@ class CompositeChunkListenerTests { @BeforeEach void setUp() { chunkContext = new ChunkContext(null); - listener = mock(ChunkListener.class); + listener = mock(); compositeListener = new CompositeChunkListener(); compositeListener.register(listener); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemProcessListenerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemProcessListenerTests.java index ed00b162a4..c9703acad0 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemProcessListenerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemProcessListenerTests.java @@ -37,7 +37,7 @@ class CompositeItemProcessListenerTests { @SuppressWarnings("unchecked") @BeforeEach void setUp() { - listener = mock(ItemProcessListener.class); + listener = mock(); compositeListener = new CompositeItemProcessListener<>(); compositeListener.register(listener); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemReadListenerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemReadListenerTests.java index f559b8a3ca..ac9bd41bac 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemReadListenerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemReadListenerTests.java @@ -38,7 +38,7 @@ class CompositeItemReadListenerTests { @SuppressWarnings("unchecked") @BeforeEach void setUp() { - listener = mock(ItemReadListener.class); + listener = mock(); compositeListener = new CompositeItemReadListener<>(); compositeListener.register(listener); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemWriteListenerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemWriteListenerTests.java index 714f48bc32..6531b4ef35 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemWriteListenerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/CompositeItemWriteListenerTests.java @@ -40,7 +40,7 @@ class CompositeItemWriteListenerTests { @SuppressWarnings("unchecked") @BeforeEach void setUp() { - listener = mock(ItemWriteListener.class); + listener = mock(); compositeListener = new CompositeItemWriteListener<>(); compositeListener.register(listener); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDaoTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDaoTests.java index d43b250122..b7f69611bc 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDaoTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/JdbcExecutionContextDaoTests.java @@ -30,7 +30,7 @@ class JdbcExecutionContextDaoTests extends AbstractExecutionContextDaoTests { @Test void testNullSerializer() { JdbcExecutionContextDao jdbcExecutionContextDao = new JdbcExecutionContextDao(); - jdbcExecutionContextDao.setJdbcTemplate(mock(JdbcOperations.class)); + jdbcExecutionContextDao.setJdbcTemplate(mock()); Exception exception = assertThrows(IllegalArgumentException.class, () -> jdbcExecutionContextDao.setSerializer(null)); assertEquals("Serializer must not be null", exception.getMessage()); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java index d28daf95a2..26591735c9 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBeanTests.java @@ -78,11 +78,11 @@ class JobRepositoryFactoryBeanTests { void setUp() { factory = new JobRepositoryFactoryBean(); - dataSource = mock(DataSource.class); - transactionManager = mock(PlatformTransactionManager.class); + dataSource = mock(); + transactionManager = mock(); factory.setDataSource(dataSource); factory.setTransactionManager(transactionManager); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); factory.setIncrementerFactory(incrementerFactory); factory.setTablePrefix(tablePrefix); @@ -91,8 +91,8 @@ void setUp() { @Test void testNoDatabaseType() throws Exception { - DatabaseMetaData dmd = mock(DatabaseMetaData.class); - Connection con = mock(Connection.class); + DatabaseMetaData dmd = mock(); + Connection con = mock(); when(dataSource.getConnection()).thenReturn(con); when(con.getMetaData()).thenReturn(dmd); when(dmd.getDatabaseProductName()).thenReturn("Oracle"); @@ -115,7 +115,7 @@ void testOracleLobHandler() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -135,7 +135,7 @@ void testCustomLobHandler() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -158,7 +158,7 @@ void tesDefaultSerializer() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -178,7 +178,7 @@ void testCustomSerializer() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -199,7 +199,7 @@ void testDefaultJdbcOperations() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -219,7 +219,7 @@ void testCustomJdbcOperations() throws Exception { factory.setDatabaseType("ORACLE"); - incrementerFactory = mock(DataFieldMaxValueIncrementerFactory.class); + incrementerFactory = mock(); when(incrementerFactory.isSupportedIncrementerType("ORACLE")).thenReturn(true); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_SEQ")).thenReturn(new StubIncrementer()); when(incrementerFactory.getIncrementer("ORACLE", tablePrefix + "JOB_EXECUTION_SEQ")) @@ -228,7 +228,7 @@ void testCustomJdbcOperations() throws Exception { .thenReturn(new StubIncrementer()); factory.setIncrementerFactory(incrementerFactory); - JdbcOperations customJdbcOperations = mock(JdbcOperations.class); + JdbcOperations customJdbcOperations = mock(); factory.setJdbcOperations(customJdbcOperations); factory.afterPropertiesSet(); @@ -313,7 +313,7 @@ void testTransactionAttributesForCreateMethod() throws Exception { DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW); transactionDefinition.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_SERIALIZABLE); when(transactionManager.getTransaction(transactionDefinition)).thenReturn(null); - Connection conn = mock(Connection.class); + Connection conn = mock(); when(dataSource.getConnection()).thenReturn(conn); Exception exception = assertThrows(IllegalArgumentException.class, () -> repository.createJobExecution("foo", new JobParameters())); @@ -331,7 +331,7 @@ void testSetTransactionAttributesForCreateMethod() throws Exception { DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW); transactionDefinition.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_READ_UNCOMMITTED); when(transactionManager.getTransaction(transactionDefinition)).thenReturn(null); - Connection conn = mock(Connection.class); + Connection conn = mock(); when(dataSource.getConnection()).thenReturn(conn); Exception exception = assertThrows(IllegalArgumentException.class, () -> repository.createJobExecution("foo", new JobParameters())); @@ -341,7 +341,7 @@ void testSetTransactionAttributesForCreateMethod() throws Exception { @Test public void testCustomTransactionAttributesSource() throws Exception { // given - TransactionAttributeSource transactionAttributeSource = Mockito.mock(TransactionAttributeSource.class); + TransactionAttributeSource transactionAttributeSource = Mockito.mock(); this.factory.setTransactionAttributeSource(transactionAttributeSource); // when diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java index 99d0429e42..5b903d0f14 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryTests.java @@ -96,10 +96,10 @@ class SimpleJobRepositoryTests { @BeforeEach void setUp() { - jobExecutionDao = mock(JobExecutionDao.class); - jobInstanceDao = mock(JobInstanceDao.class); - stepExecutionDao = mock(StepExecutionDao.class); - ecDao = mock(ExecutionContextDao.class); + jobExecutionDao = mock(); + jobInstanceDao = mock(); + stepExecutionDao = mock(); + ecDao = mock(); jobRepository = new SimpleJobRepository(jobInstanceDao, jobExecutionDao, stepExecutionDao, ecDao); @@ -348,9 +348,9 @@ public void testGetJobInstanceWithNameAndParameters() { @Test void testDeleteJobExecution() { // given - StepExecution stepExecution1 = mock(StepExecution.class); - StepExecution stepExecution2 = mock(StepExecution.class); - JobExecution jobExecution = mock(JobExecution.class); + StepExecution stepExecution1 = mock(); + StepExecution stepExecution2 = mock(); + JobExecution jobExecution = mock(); when(jobExecution.getStepExecutions()).thenReturn(Arrays.asList(stepExecution1, stepExecution2)); // when @@ -369,9 +369,9 @@ void testDeleteJobExecution() { @Test void testDeleteJobInstance() { // given - JobExecution jobExecution1 = mock(JobExecution.class); - JobExecution jobExecution2 = mock(JobExecution.class); - JobInstance jobInstance = mock(JobInstance.class); + JobExecution jobExecution1 = mock(); + JobExecution jobExecution2 = mock(); + JobInstance jobInstance = mock(); when(this.jobExecutionDao.findJobExecutions(jobInstance)) .thenReturn(Arrays.asList(jobExecution1, jobExecution2)); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java index f775d86cf7..78e138272c 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java @@ -88,7 +88,7 @@ void setUp() throws Exception { @Test void testSkip() throws Exception { @SuppressWarnings("unchecked") - SkipListener skipListener = mock(SkipListener.class); + SkipListener skipListener = mock(); skipListener.onSkipInWrite("3", exception); skipListener.onSkipInWrite("4", exception); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/MethodInvokingTaskletAdapterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/MethodInvokingTaskletAdapterTests.java index 5adc41058a..246e91bdc1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/MethodInvokingTaskletAdapterTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/MethodInvokingTaskletAdapterTests.java @@ -42,8 +42,8 @@ class MethodInvokingTaskletAdapterTests { @BeforeEach void setUp() { - stepContribution = new StepContribution(mock(StepExecution.class)); - chunkContext = mock(ChunkContext.class); + stepContribution = new StepContribution(mock()); + chunkContext = mock(); tasklet = new TestTasklet(); adapter = new MethodInvokingTaskletAdapter(); adapter.setTargetObject(tasklet); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java index f4b401ba3e..006d9ed877 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java @@ -292,8 +292,8 @@ private boolean isRunningOnWindows() { @Test public void testExecuteWithSuccessfulCommandRunnerMockExecution() throws Exception { StepContribution stepContribution = stepExecution.createStepContribution(); - CommandRunner commandRunner = mock(CommandRunner.class); - Process process = mock(Process.class); + CommandRunner commandRunner = mock(); + Process process = mock(); String[] command = new String[] { "invalid command" }; when(commandRunner.exec(eq(command), any(), any())).thenReturn(process); @@ -312,8 +312,8 @@ public void testExecuteWithSuccessfulCommandRunnerMockExecution() throws Excepti @Test public void testExecuteWithFailedCommandRunnerMockExecution() throws Exception { StepContribution stepContribution = stepExecution.createStepContribution(); - CommandRunner commandRunner = mock(CommandRunner.class); - Process process = mock(Process.class); + CommandRunner commandRunner = mock(); + Process process = mock(); String[] command = new String[] { "invalid command" }; when(commandRunner.exec(eq(command), any(), any())).thenReturn(process); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/container/jms/BatchMessageListenerContainerTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/container/jms/BatchMessageListenerContainerTests.java index 33a8678d84..8ad90b66b8 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/container/jms/BatchMessageListenerContainerTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/container/jms/BatchMessageListenerContainerTests.java @@ -53,9 +53,9 @@ void testReceiveAndExecuteWithCallback() throws Exception { container.setMessageListener((MessageListener) arg0 -> { }); - Session session = mock(Session.class); - MessageConsumer consumer = mock(MessageConsumer.class); - Message message = mock(Message.class); + Session session = mock(); + MessageConsumer consumer = mock(); + Message message = mock(); // Expect two calls to consumer (chunk size)... when(session.getTransacted()).thenReturn(true); @@ -73,8 +73,8 @@ void testReceiveAndExecuteWithCallbackReturningNull() throws Exception { template.setCompletionPolicy(new SimpleCompletionPolicy(2)); container = getContainer(template); - Session session = mock(Session.class); - MessageConsumer consumer = mock(MessageConsumer.class); + Session session = mock(); + MessageConsumer consumer = mock(); Message message = null; // Expect one call to consumer (chunk size is 2 but terminates on @@ -119,7 +119,7 @@ void testNonTransactionalReceiveAndExecuteWithCallbackThrowingError() throws Exc } private BatchMessageListenerContainer getContainer(RepeatTemplate template) { - ConnectionFactory connectionFactory = mock(ConnectionFactory.class); + ConnectionFactory connectionFactory = mock(); // Yuck: we need to turn these method in base class to no-ops because the invoker // is a private class // we can't create for test purposes... @@ -151,9 +151,9 @@ private boolean doTestWithException(final Throwable t, boolean expectRollback, i throw (Error) t; }); - Session session = mock(Session.class); - MessageConsumer consumer = mock(MessageConsumer.class); - Message message = mock(Message.class); + Session session = mock(); + MessageConsumer consumer = mock(); + Message message = mock(); if (expectGetTransactionCount > 0) { when(session.getTransacted()).thenReturn(true); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemReaderTests.java index 3838ef6463..a941cd276b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemReaderTests.java @@ -44,7 +44,7 @@ void testNullAmqpTemplate() { @Test void testNoItemType() { - final AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + final AmqpTemplate amqpTemplate = mock(); when(amqpTemplate.receiveAndConvert()).thenReturn("foo"); final AmqpItemReader amqpItemReader = new AmqpItemReader<>(amqpTemplate); @@ -53,7 +53,7 @@ void testNoItemType() { @Test void testNonMessageItemType() { - final AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + final AmqpTemplate amqpTemplate = mock(); when(amqpTemplate.receiveAndConvert()).thenReturn("foo"); final AmqpItemReader amqpItemReader = new AmqpItemReader<>(amqpTemplate); @@ -65,8 +65,8 @@ void testNonMessageItemType() { @Test void testMessageItemType() { - final AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); - final Message message = mock(Message.class); + final AmqpTemplate amqpTemplate = mock(); + final Message message = mock(); when(amqpTemplate.receive()).thenReturn(message); @@ -79,7 +79,7 @@ void testMessageItemType() { @Test void testTypeMismatch() { - final AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + final AmqpTemplate amqpTemplate = mock(); when(amqpTemplate.receiveAndConvert()).thenReturn("foo"); @@ -93,7 +93,7 @@ void testTypeMismatch() { @Test void testNullItemType() { - final AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + final AmqpTemplate amqpTemplate = mock(); final AmqpItemReader amqpItemReader = new AmqpItemReader<>(amqpTemplate); assertThrows(IllegalArgumentException.class, () -> amqpItemReader.setItemType(null)); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemWriterTests.java index eb81d9139e..49b505c3a0 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/AmqpItemWriterTests.java @@ -42,7 +42,7 @@ void testNullAmqpTemplate() { @Test void voidTestWrite() throws Exception { - AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + AmqpTemplate amqpTemplate = mock(); amqpTemplate.convertAndSend("foo"); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilderTests.java index 40efe3f763..bba60288b7 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemReaderBuilderTests.java @@ -59,7 +59,7 @@ void testNonMessageItemType() { @Test void testMessageItemType() { - final Message message = mock(Message.class); + final Message message = mock(); when(this.amqpTemplate.receive()).thenReturn(message); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilderTests.java index 493c8f4368..c5bc741ce7 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/amqp/builder/AmqpItemWriterBuilderTests.java @@ -43,7 +43,7 @@ void testNullAmqpTemplate() { @Test void voidTestWrite() throws Exception { - AmqpTemplate amqpTemplate = mock(AmqpTemplate.class); + AmqpTemplate amqpTemplate = mock(); AmqpItemWriter amqpItemWriter = new AmqpItemWriterBuilder().amqpTemplate(amqpTemplate).build(); amqpItemWriter.write(Chunk.of("foo", "bar")); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java index 208ceb3bb8..eaedf43165 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java @@ -252,9 +252,9 @@ void testResourceKeyCollision() { final String[] results = new String[limit]; for (int i = 0; i < limit; i++) { final int index = i; - MongoOperations mongoOperations = mock(MongoOperations.class); - BulkOperations bulkOperations = mock(BulkOperations.class); - MongoConverter mongoConverter = mock(MongoConverter.class); + MongoOperations mongoOperations = mock(); + BulkOperations bulkOperations = mock(); + MongoConverter mongoConverter = mock(); when(mongoOperations.bulkOps(any(), any(Class.class))).thenReturn(bulkOperations); when(mongoOperations.getConverter()).thenReturn(mongoConverter); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java index 70b49f668a..8513ebf26f 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemReaderTests.java @@ -228,7 +228,7 @@ void testInvalidMethodName() { @Test void testDifferentTypes() throws Exception { - TestRepository differentRepository = mock(TestRepository.class); + TestRepository differentRepository = mock(); RepositoryItemReader reader = new RepositoryItemReader<>(); sorts = Collections.singletonMap("id", Direction.ASC); reader.setRepository(differentRepository); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/ExtendedConnectionDataSourceProxyTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/ExtendedConnectionDataSourceProxyTests.java index 0439f2ad22..dc362b28ce 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/ExtendedConnectionDataSourceProxyTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/ExtendedConnectionDataSourceProxyTests.java @@ -48,8 +48,8 @@ class ExtendedConnectionDataSourceProxyTests { @Test void testOperationWithDataSourceUtils() throws SQLException { - Connection con = mock(Connection.class); - DataSource ds = mock(DataSource.class); + Connection con = mock(); + DataSource ds = mock(); when(ds.getConnection()).thenReturn(con); // con1 con.close(); @@ -94,8 +94,8 @@ void testOperationWithDataSourceUtils() throws SQLException { @Test void testOperationWithDirectCloseCall() throws SQLException { - Connection con = mock(Connection.class); - DataSource ds = mock(DataSource.class); + Connection con = mock(); + DataSource ds = mock(); when(ds.getConnection()).thenReturn(con); // con1 con.close(); @@ -126,10 +126,10 @@ void testOperationWithDirectCloseCall() throws SQLException { @Test void testSuppressOfCloseWithJdbcTemplate() throws Exception { - Connection con = mock(Connection.class); - DataSource ds = mock(DataSource.class); - Statement stmt = mock(Statement.class); - ResultSet rs = mock(ResultSet.class); + Connection con = mock(); + DataSource ds = mock(); + Statement stmt = mock(); + ResultSet rs = mock(); // open and start suppressing close when(ds.getConnection()).thenReturn(con); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateCursorItemReaderStatefulIntegrationTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateCursorItemReaderStatefulIntegrationTests.java index 714295a12b..cc361b11f3 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateCursorItemReaderStatefulIntegrationTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateCursorItemReaderStatefulIntegrationTests.java @@ -44,9 +44,9 @@ protected boolean isUseStatelessSession() { @SuppressWarnings("unchecked") void testStatefulClose() { - SessionFactory sessionFactory = mock(SessionFactory.class); - Session session = mock(Session.class); - Query scrollableResults = mock(Query.class); + SessionFactory sessionFactory = mock(); + Session session = mock(); + Query scrollableResults = mock(); HibernateCursorItemReader itemReader = new HibernateCursorItemReader<>(); itemReader.setSessionFactory(sessionFactory); itemReader.setQueryString("testQuery"); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemReaderHelperTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemReaderHelperTests.java index 85ed47e53e..fd2d54f75e 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemReaderHelperTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemReaderHelperTests.java @@ -36,12 +36,12 @@ class HibernateItemReaderHelperTests { private final HibernateItemReaderHelper helper = new HibernateItemReaderHelper<>(); - private final SessionFactory sessionFactory = mock(SessionFactory.class); + private final SessionFactory sessionFactory = mock(); @Test void testOneSessionForAllPages() { - StatelessSession session = mock(StatelessSession.class); + StatelessSession session = mock(); when(sessionFactory.openStatelessSession()).thenReturn(session); helper.setSessionFactory(sessionFactory); @@ -55,7 +55,7 @@ void testOneSessionForAllPages() { @Test void testSessionReset() { - StatelessSession session = mock(StatelessSession.class); + StatelessSession session = mock(); when(sessionFactory.openStatelessSession()).thenReturn(session); helper.setSessionFactory(sessionFactory); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java index f95791a721..9d4272130f 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateItemWriterTests.java @@ -46,8 +46,8 @@ class HibernateItemWriterTests { @BeforeEach void setUp() { writer = new HibernateItemWriter<>(); - factory = mock(SessionFactory.class); - currentSession = mock(Session.class); + factory = mock(); + currentSession = mock(); when(this.factory.getCurrentSession()).thenReturn(this.currentSession); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterClassicTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterClassicTests.java index a9b49f588a..bc5eb0cc7a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterClassicTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterClassicTests.java @@ -55,7 +55,7 @@ class JdbcBatchItemWriterClassicTests { @BeforeEach void setUp() { - ps = mock(PreparedStatement.class); + ps = mock(); jdbcTemplate = new JdbcTemplate() { @Override public T execute(String sql, PreparedStatementCallback action) throws DataAccessException { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterNamedParameterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterNamedParameterTests.java index 33e1ee9ae7..5cf270059c 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterNamedParameterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcBatchItemWriterNamedParameterTests.java @@ -85,7 +85,7 @@ public void setBar(String bar) { @BeforeEach void setUp() { - namedParameterJdbcOperations = mock(NamedParameterJdbcOperations.class); + namedParameterJdbcOperations = mock(); writer.setSql(sql); writer.setJdbcTemplate(namedParameterJdbcOperations); writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>()); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java index 978ff3534d..0a63671333 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java @@ -41,10 +41,10 @@ class JdbcCursorItemReaderConfigTests { */ @Test void testUsesCurrentTransaction() throws Exception { - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); + DataSource ds = mock(); + Connection con = mock(); when(con.getAutoCommit()).thenReturn(false); - PreparedStatement ps = mock(PreparedStatement.class); + PreparedStatement ps = mock(); when(con.prepareStatement("select foo from bar", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT)) .thenReturn(ps); @@ -71,10 +71,10 @@ void testUsesCurrentTransaction() throws Exception { @Test void testUsesItsOwnTransaction() throws Exception { - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); + DataSource ds = mock(); + Connection con = mock(); when(con.getAutoCommit()).thenReturn(false); - PreparedStatement ps = mock(PreparedStatement.class); + PreparedStatement ps = mock(); when(con.prepareStatement("select foo from bar", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) .thenReturn(ps); when(ds.getConnection()).thenReturn(con); @@ -98,10 +98,10 @@ void testOverrideConnectionAutoCommit() throws Exception { boolean initialAutoCommit = false; boolean neededAutoCommit = true; - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); + DataSource ds = mock(); + Connection con = mock(); when(con.getAutoCommit()).thenReturn(initialAutoCommit); - PreparedStatement ps = mock(PreparedStatement.class); + PreparedStatement ps = mock(); when(con.prepareStatement("select foo from bar", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) .thenReturn(ps); when(ds.getConnection()).thenReturn(con); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaItemWriterTests.java index cab71bf656..d5a8fdffad 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaItemWriterTests.java @@ -51,7 +51,7 @@ void setUp() { TransactionSynchronizationManager.clearSynchronization(); } writer = new JpaItemWriter<>(); - emf = mock(EntityManagerFactory.class, "emf"); + emf = mock(); writer.setEntityManagerFactory(emf); } @@ -65,7 +65,7 @@ void testAfterPropertiesSet() { @Test void testWriteAndFlushSunnyDay() { - EntityManager em = mock(EntityManager.class, "em"); + EntityManager em = mock(); em.contains("foo"); em.contains("bar"); em.merge("bar"); @@ -82,7 +82,7 @@ void testWriteAndFlushSunnyDay() { @Test void testPersist() { writer.setUsePersist(true); - EntityManager em = mock(EntityManager.class, "em"); + EntityManager em = mock(); TransactionSynchronizationManager.bindResource(emf, new EntityManagerHolder(em)); Chunk chunk = Chunk.of("persist1", "persist2"); writer.write(chunk); @@ -94,7 +94,7 @@ void testPersist() { @Test void testWriteAndFlushWithFailure() { final RuntimeException ex = new RuntimeException("ERROR"); - EntityManager em = mock(EntityManager.class, "em"); + EntityManager em = mock(); em.contains("foo"); em.contains("bar"); em.merge("bar"); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/StoredprocedureItemReaderConfigTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/StoredprocedureItemReaderConfigTests.java index 50a02a9c04..c561addcfe 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/StoredprocedureItemReaderConfigTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/StoredprocedureItemReaderConfigTests.java @@ -41,14 +41,14 @@ class StoredprocedureItemReaderConfigTests { */ @Test void testUsesCurrentTransaction() throws Exception { - DataSource ds = mock(DataSource.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductName()).thenReturn("Oracle"); - Connection con = mock(Connection.class); + Connection con = mock(); when(con.getMetaData()).thenReturn(dmd); when(con.getMetaData()).thenReturn(dmd); when(con.getAutoCommit()).thenReturn(false); - CallableStatement cs = mock(CallableStatement.class); + CallableStatement cs = mock(); when(con.prepareCall("{call foo_bar()}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT)) .thenReturn(cs); @@ -75,14 +75,14 @@ void testUsesCurrentTransaction() throws Exception { @Test void testUsesItsOwnTransaction() throws Exception { - DataSource ds = mock(DataSource.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductName()).thenReturn("Oracle"); - Connection con = mock(Connection.class); + Connection con = mock(); when(con.getMetaData()).thenReturn(dmd); when(con.getMetaData()).thenReturn(dmd); when(con.getAutoCommit()).thenReturn(false); - CallableStatement cs = mock(CallableStatement.class); + CallableStatement cs = mock(); when(con.prepareCall("{call foo_bar()}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) .thenReturn(cs); when(ds.getConnection()).thenReturn(con); @@ -107,14 +107,14 @@ void testUsesItsOwnTransaction() throws Exception { @Test void testHandlesRefCursorPosition() throws Exception { - DataSource ds = mock(DataSource.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductName()).thenReturn("Oracle"); - Connection con = mock(Connection.class); + Connection con = mock(); when(con.getMetaData()).thenReturn(dmd); when(con.getMetaData()).thenReturn(dmd); when(con.getAutoCommit()).thenReturn(false); - CallableStatement cs = mock(CallableStatement.class); + CallableStatement cs = mock(); when(con.prepareCall("{call foo_bar(?, ?)}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) .thenReturn(cs); when(ds.getConnection()).thenReturn(con); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/StoredProcedureItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/StoredProcedureItemReaderBuilderTests.java index 57bf5d0322..b522f2b9be 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/StoredProcedureItemReaderBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/StoredProcedureItemReaderBuilderTests.java @@ -38,7 +38,7 @@ */ class StoredProcedureItemReaderBuilderTests { - private final DataSource dataSource = Mockito.mock(DataSource.class); + private final DataSource dataSource = Mockito.mock(); @Test void testConfiguration() { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/orm/JpaNamedQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/orm/JpaNamedQueryProviderTests.java index 3e98b2e875..ac659c8f31 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/orm/JpaNamedQueryProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/orm/JpaNamedQueryProviderTests.java @@ -69,8 +69,8 @@ void testJpaNamedQueryProviderEntityClassIsProvided() { void testNamedQueryCreation() throws Exception { // given String namedQuery = "allFoos"; - TypedQuery query = mock(TypedQuery.class); - EntityManager entityManager = Mockito.mock(EntityManager.class); + TypedQuery query = mock(); + EntityManager entityManager = Mockito.mock(); when(entityManager.createNamedQuery(namedQuery, Foo.class)).thenReturn(query); JpaNamedQueryProvider jpaNamedQueryProvider = new JpaNamedQueryProvider<>(); jpaNamedQueryProvider.setEntityManager(entityManager); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/ColumnMapExecutionContextRowMapperTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/ColumnMapExecutionContextRowMapperTests.java index da677d07a7..8a05a6a09f 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/ColumnMapExecutionContextRowMapperTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/ColumnMapExecutionContextRowMapperTests.java @@ -39,7 +39,7 @@ class ColumnMapExecutionContextRowMapperTests { @BeforeEach void setUp() { - ps = mock(PreparedStatement.class); + ps = mock(); mapper = new ColumnMapItemPreparedStatementSetter(); key = new LinkedHashMap<>(2); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java index 542714a12d..f819ff06d1 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java @@ -48,7 +48,7 @@ class DefaultDataFieldMaxValueIncrementerFactoryTests { @BeforeEach void setUp() { - DataSource dataSource = mock(DataSource.class); + DataSource dataSource = mock(); factory = new DefaultDataFieldMaxValueIncrementerFactory(dataSource); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java index f2be2f7437..5bd891ddfa 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java @@ -43,9 +43,9 @@ class DerbyPagingQueryProviderTests extends AbstractSqlPagingQueryProviderTests @Test void testInit() throws Exception { - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + Connection con = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductVersion()).thenReturn("10.4.1.3"); when(con.getMetaData()).thenReturn(dmd); when(ds.getConnection()).thenReturn(con); @@ -54,9 +54,9 @@ void testInit() throws Exception { @Test void testInitWithRecentVersion() throws Exception { - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + Connection con = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductVersion()).thenReturn("10.10.1.1"); when(con.getMetaData()).thenReturn(dmd); when(ds.getConnection()).thenReturn(con); @@ -65,9 +65,9 @@ void testInitWithRecentVersion() throws Exception { @Test void testInitWithUnsupportedVersion() throws Exception { - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); - DatabaseMetaData dmd = mock(DatabaseMetaData.class); + DataSource ds = mock(); + Connection con = mock(); + DatabaseMetaData dmd = mock(); when(dmd.getDatabaseProductVersion()).thenReturn("10.2.9.9"); when(con.getMetaData()).thenReturn(dmd); when(ds.getConnection()).thenReturn(con); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HibernateNativeQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HibernateNativeQueryProviderTests.java index 22bf07b1ab..a03276fd0e 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HibernateNativeQueryProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HibernateNativeQueryProviderTests.java @@ -47,8 +47,8 @@ void testCreateQueryWithStatelessSession() { String sqlQuery = "select * from T_FOOS"; hibernateQueryProvider.setSqlQuery(sqlQuery); - StatelessSession session = mock(StatelessSession.class); - NativeQuery query = mock(NativeQuery.class); + StatelessSession session = mock(); + NativeQuery query = mock(); when(session.createNativeQuery(sqlQuery)).thenReturn(query); when(query.addEntity(Foo.class)).thenReturn(query); @@ -64,8 +64,8 @@ void shouldCreateQueryWithStatefulSession() { String sqlQuery = "select * from T_FOOS"; hibernateQueryProvider.setSqlQuery(sqlQuery); - Session session = mock(Session.class); - NativeQuery query = mock(NativeQuery.class); + Session session = mock(); + NativeQuery query = mock(); when(session.createNativeQuery(sqlQuery)).thenReturn(query); when(query.addEntity(Foo.class)).thenReturn(query); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/JpaNativeQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/JpaNativeQueryProviderTests.java index 0b48f7d65e..4c25edbf8a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/JpaNativeQueryProviderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/JpaNativeQueryProviderTests.java @@ -49,8 +49,8 @@ void testCreateQuery() { String sqlQuery = "select * from T_FOOS where value >= :limit"; jpaQueryProvider.setSqlQuery(sqlQuery); - EntityManager entityManager = mock(EntityManager.class); - Query query = mock(Query.class); + EntityManager entityManager = mock(); + Query query = mock(); when(entityManager.createNativeQuery(sqlQuery, Foo.class)).thenReturn(query); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/mapping/DefaultLineMapperTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/mapping/DefaultLineMapperTests.java index 47ee5aecc9..17d2aef012 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/mapping/DefaultLineMapperTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/mapping/DefaultLineMapperTests.java @@ -50,11 +50,11 @@ void testMapping() throws Exception { final FieldSet fs = new DefaultFieldSet(new String[] { "token1", "token2" }); final String item = "ITEM"; - LineTokenizer tokenizer = mock(LineTokenizer.class); + LineTokenizer tokenizer = mock(); when(tokenizer.tokenize(line)).thenReturn(fs); @SuppressWarnings("unchecked") - FieldSetMapper fsMapper = mock(FieldSetMapper.class); + FieldSetMapper fsMapper = mock(); when(fsMapper.mapFieldSet(fs)).thenReturn(item); tested.setLineTokenizer(tokenizer); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java index 1613bd9c90..260a2c87f7 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemReaderTests.java @@ -37,7 +37,7 @@ class JmsItemReaderTests { @Test void testNoItemTypeSunnyDay() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); when(jmsTemplate.receiveAndConvert()).thenReturn("foo"); itemReader.setJmsTemplate(jmsTemplate); @@ -46,7 +46,7 @@ void testNoItemTypeSunnyDay() { @Test void testSetItemTypeSunnyDay() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); when(jmsTemplate.receiveAndConvert()).thenReturn("foo"); itemReader.setJmsTemplate(jmsTemplate); @@ -56,7 +56,7 @@ void testSetItemTypeSunnyDay() { @Test void testSetItemSubclassTypeSunnyDay() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); Date date = new java.sql.Date(0L); when(jmsTemplate.receiveAndConvert()).thenReturn(date); @@ -70,7 +70,7 @@ void testSetItemSubclassTypeSunnyDay() { @Test void testSetItemTypeMismatch() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); when(jmsTemplate.receiveAndConvert()).thenReturn("foo"); JmsItemReader itemReader = new JmsItemReader<>(); @@ -82,8 +82,8 @@ void testSetItemTypeMismatch() { @Test void testNextMessageSunnyDay() { - JmsOperations jmsTemplate = mock(JmsOperations.class); - Message message = mock(Message.class); + JmsOperations jmsTemplate = mock(); + Message message = mock(); when(jmsTemplate.receive()).thenReturn(message); JmsItemReader itemReader = new JmsItemReader<>(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemWriterTests.java index cc5c2aa0fb..7a36cdb782 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsItemWriterTests.java @@ -31,7 +31,7 @@ class JmsItemWriterTests { @Test void testNoItemTypeSunnyDay() throws Exception { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); jmsTemplate.convertAndSend("foo"); jmsTemplate.convertAndSend("bar"); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java index 7dc639a655..050f7d393b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodArgumentsKeyGeneratorTests.java @@ -35,7 +35,7 @@ class JmsMethodArgumentsKeyGeneratorTests { @Test void testGetKeyFromMessage() throws Exception { - Message message = mock(Message.class); + Message message = mock(); when(message.getJMSMessageID()).thenReturn("foo"); JmsItemReader itemReader = new JmsItemReader<>(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java index 57aa7d5638..aaf41439ec 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsMethodInvocationRecovererTests.java @@ -31,7 +31,7 @@ class JmsMethodInvocationRecovererTests { @Test void testRecoverWithNoDestination() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); jmsTemplate.convertAndSend("foo"); itemReader.setJmsTemplate(jmsTemplate); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java index 8851c92d5e..d3f7da272a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/JmsNewMethodArgumentsIdentifierTests.java @@ -35,7 +35,7 @@ class JmsNewMethodArgumentsIdentifierTests { @Test void testIsNewForMessage() throws Exception { - Message message = mock(Message.class); + Message message = mock(); when(message.getJMSRedelivered()).thenReturn(true); assertFalse(newMethodArgumentsIdentifier.isNew(new Object[] { message })); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemReaderBuilderTests.java index 45d9692ecc..fbb48ac41b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemReaderBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemReaderBuilderTests.java @@ -42,7 +42,7 @@ class JmsItemReaderBuilderTests { @BeforeEach void setupJmsTemplate() { - this.defaultJmsTemplate = mock(JmsOperations.class); + this.defaultJmsTemplate = mock(); when(this.defaultJmsTemplate.receiveAndConvert()).thenReturn("foo"); } @@ -55,7 +55,7 @@ void testBasicRead() { @Test void testSetItemSubclassType() { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); Date date = new java.sql.Date(0L); when(jmsTemplate.receiveAndConvert()).thenReturn(date); @@ -77,8 +77,8 @@ void testSetItemTypeMismatch() { @Test void testMessageType() { - JmsOperations jmsTemplate = mock(JmsOperations.class); - Message message = mock(Message.class); + JmsOperations jmsTemplate = mock(); + Message message = mock(); when(jmsTemplate.receive()).thenReturn(message); JmsItemReader itemReader = new JmsItemReaderBuilder().jmsTemplate(jmsTemplate) diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemWriterBuilderTests.java index ad256ae325..6b88fea37d 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/jms/builder/JmsItemWriterBuilderTests.java @@ -37,7 +37,7 @@ class JmsItemWriterBuilderTests { @Test void testNoItem() throws Exception { - JmsOperations jmsTemplate = mock(JmsOperations.class); + JmsOperations jmsTemplate = mock(); JmsItemWriter itemWriter = new JmsItemWriterBuilder().jmsTemplate(jmsTemplate).build(); ArgumentCaptor argCaptor = ArgumentCaptor.forClass(String.class); itemWriter.write(Chunk.of("foo", "bar")); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java index 1fa37b7aa0..fc19f18c99 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java @@ -82,8 +82,8 @@ void testJsonFileItemWriterCreation() { boolean shouldDeleteIfExists = true; String encoding = "UTF-8"; String lineSeparator = "#"; - FlatFileHeaderCallback headerCallback = Mockito.mock(FlatFileHeaderCallback.class); - FlatFileFooterCallback footerCallback = Mockito.mock(FlatFileFooterCallback.class); + FlatFileHeaderCallback headerCallback = Mockito.mock(); + FlatFileFooterCallback footerCallback = Mockito.mock(); // when JsonFileItemWriter writer = new JsonFileItemWriterBuilder().name("jsonFileItemWriter") @@ -114,8 +114,8 @@ void testJsonFileItemWriterCreationDefaultEncoding() { boolean shouldDeleteIfExists = true; String encoding = Charset.defaultCharset().name(); String lineSeparator = "#"; - FlatFileHeaderCallback headerCallback = Mockito.mock(FlatFileHeaderCallback.class); - FlatFileFooterCallback footerCallback = Mockito.mock(FlatFileFooterCallback.class); + FlatFileHeaderCallback headerCallback = Mockito.mock(); + FlatFileFooterCallback footerCallback = Mockito.mock(); // when JsonFileItemWriter writer = new JsonFileItemWriterBuilder().name("jsonFileItemWriter") diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriterTests.java index 7d69fc64ce..43cbc5c59a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/SimpleMailMessageItemWriterTests.java @@ -47,7 +47,7 @@ class SimpleMailMessageItemWriterTests { private final SimpleMailMessageItemWriter writer = new SimpleMailMessageItemWriter(); - private final MailSender mailSender = mock(MailSender.class); + private final MailSender mailSender = mock(); @BeforeEach void setUp() { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/builder/SimpleMailMessageItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/builder/SimpleMailMessageItemWriterBuilderTests.java index cc30179ab0..60bc88647c 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/builder/SimpleMailMessageItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/builder/SimpleMailMessageItemWriterBuilderTests.java @@ -52,7 +52,7 @@ class SimpleMailMessageItemWriterBuilderTests { @BeforeEach void setup() { - mailSender = mock(MailSender.class); + mailSender = mock(); this.foo = new SimpleMailMessage(); this.bar = new SimpleMailMessage(); this.items = new SimpleMailMessage[] { this.foo, this.bar }; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/javamail/MimeMessageItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/javamail/MimeMessageItemWriterTests.java index 573c531776..658fb71d0b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/javamail/MimeMessageItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/mail/javamail/MimeMessageItemWriterTests.java @@ -49,7 +49,7 @@ class MimeMessageItemWriterTests { private final MimeMessageItemWriter writer = new MimeMessageItemWriter(); - private final JavaMailSender mailSender = mock(JavaMailSender.class); + private final JavaMailSender mailSender = mock(); private final Session session = Session.getDefaultInstance(new Properties()); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java index f8d15de35b..b4e7e84875 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java @@ -46,8 +46,8 @@ class CompositeItemProcessorTests { @SuppressWarnings("unchecked") @BeforeEach void setUp() throws Exception { - processor1 = mock(ItemProcessor.class); - processor2 = mock(ItemProcessor.class); + processor1 = mock(); + processor2 = mock(); composite.setDelegates(Arrays.asList(processor1, processor2)); @@ -80,8 +80,8 @@ void testTransform() throws Exception { @SuppressWarnings("unchecked") void testItemProcessorGenerics() throws Exception { CompositeItemProcessor composite = new CompositeItemProcessor<>(); - final ItemProcessor processor1 = mock(ItemProcessor.class); - final ItemProcessor processor2 = mock(ItemProcessor.class); + final ItemProcessor processor1 = mock(); + final ItemProcessor processor2 = mock(); composite.setDelegates(Arrays.asList(processor1, processor2)); composite.afterPropertiesSet(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java index 43ba76c879..8d5d3f7b62 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java @@ -52,7 +52,7 @@ void testProcess() throws Exception { for (int i = 0; i < NUMBER_OF_WRITERS; i++) { @SuppressWarnings("unchecked") - ItemWriter writer = mock(ItemWriter.class); + ItemWriter writer = mock(); writer.write(data); @@ -76,7 +76,7 @@ void testItemStreamNotCalled() throws Exception { private void doTestItemStream(boolean expectOpen) throws Exception { @SuppressWarnings("unchecked") - ItemStreamWriter writer = mock(ItemStreamWriter.class); + ItemStreamWriter writer = mock(); Chunk data = Chunk.of(new Object()); ExecutionContext executionContext = new ExecutionContext(); if (expectOpen) { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemWriterBuilderTests.java index 6ecc25f3ef..a5025db078 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemWriterBuilderTests.java @@ -48,7 +48,7 @@ void testProcess() throws Exception { List> writers = new ArrayList<>(); for (int i = 0; i < NUMBER_OF_WRITERS; i++) { - ItemWriter writer = mock(ItemWriter.class); + ItemWriter writer = mock(); writers.add(writer); } CompositeItemWriter itemWriter = new CompositeItemWriterBuilder<>().delegates(writers).build(); @@ -68,9 +68,9 @@ void testProcessVarargs() throws Exception { List> writers = new ArrayList<>(); - ItemWriter writer1 = mock(ItemWriter.class); + ItemWriter writer1 = mock(); writers.add(writer1); - ItemWriter writer2 = mock(ItemWriter.class); + ItemWriter writer2 = mock(); writers.add(writer2); CompositeItemWriter itemWriter = new CompositeItemWriterBuilder<>().delegates(writer1, writer2).build(); @@ -90,7 +90,7 @@ void isStreamOpen() throws Exception { @SuppressWarnings("unchecked") private void ignoreItemStream(boolean ignoreItemStream) throws Exception { - ItemStreamWriter writer = mock(ItemStreamWriter.class); + ItemStreamWriter writer = mock(); Chunk data = Chunk.of(new Object()); ExecutionContext executionContext = new ExecutionContext(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java index 5d6ea420ef..a080e16c8e 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java @@ -29,7 +29,7 @@ class ValidatingItemProcessorTests { @SuppressWarnings("unchecked") - private final Validator validator = mock(Validator.class); + private final Validator validator = mock(); private static final String ITEM = "item"; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java index 7b08eb6b02..2afc86738b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java @@ -168,15 +168,15 @@ void testCustomEncoding() throws Exception { @Test void testNullEncoding() throws Exception { // given - XMLEventReader eventReader = mock(XMLEventReader.class); + XMLEventReader eventReader = mock(); when(eventReader.peek()).thenReturn(mock(StartDocument.class)); - Resource resource = mock(Resource.class); - InputStream inputStream = mock(InputStream.class); + Resource resource = mock(); + InputStream inputStream = mock(); when(resource.getInputStream()).thenReturn(inputStream); when(resource.isReadable()).thenReturn(true); when(resource.exists()).thenReturn(true); - XMLInputFactory xmlInputFactory = mock(XMLInputFactory.class); + XMLInputFactory xmlInputFactory = mock(); when(xmlInputFactory.createXMLEventReader(inputStream)).thenReturn(eventReader); StaxEventItemReader reader = new StaxEventItemReader<>(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java index caeb995fa7..f904c59441 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java @@ -446,7 +446,7 @@ void testOpenAndClose() throws Exception { @Test void testNonExistantResource() throws Exception { - WritableResource doesntExist = mock(WritableResource.class); + WritableResource doesntExist = mock(); when(doesntExist.getFile()).thenReturn(File.createTempFile("arbitrary", null)); when(doesntExist.exists()).thenReturn(false); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventReaderWrapperTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventReaderWrapperTests.java index 500f32c1fb..b7cbd3e773 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventReaderWrapperTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventReaderWrapperTests.java @@ -32,7 +32,7 @@ */ class AbstractEventReaderWrapperTests { - private final XMLEventReader xmlEventReader = mock(XMLEventReader.class); + private final XMLEventReader xmlEventReader = mock(); private final AbstractEventReaderWrapper eventReaderWrapper = new StubEventReader(xmlEventReader); @@ -76,7 +76,7 @@ void testNext() { @Test void testNextEvent() throws XMLStreamException { - XMLEvent event = mock(XMLEvent.class); + XMLEvent event = mock(); when(xmlEventReader.nextEvent()).thenReturn(event); assertEquals(eventReaderWrapper.nextEvent(), event); } @@ -84,7 +84,7 @@ void testNextEvent() throws XMLStreamException { @Test void testNextTag() throws XMLStreamException { - XMLEvent event = mock(XMLEvent.class); + XMLEvent event = mock(); when(xmlEventReader.nextTag()).thenReturn(event); assertEquals(eventReaderWrapper.nextTag(), event); } @@ -92,7 +92,7 @@ void testNextTag() throws XMLStreamException { @Test void testPeek() throws XMLStreamException { - XMLEvent event = mock(XMLEvent.class); + XMLEvent event = mock(); when(xmlEventReader.peek()).thenReturn(event); assertEquals(eventReaderWrapper.peek(), event); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventWriterWrapperTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventWriterWrapperTests.java index c2d279c1e3..2e15b2ee73 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventWriterWrapperTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/AbstractEventWriterWrapperTests.java @@ -35,14 +35,14 @@ */ class AbstractEventWriterWrapperTests { - private final XMLEventWriter xmlEventWriter = mock(XMLEventWriter.class); + private final XMLEventWriter xmlEventWriter = mock(); private final AbstractEventWriterWrapper eventWriterWrapper = new StubEventWriter(xmlEventWriter); @Test void testAdd() throws XMLStreamException { - XMLEvent event = mock(XMLEvent.class); + XMLEvent event = mock(); xmlEventWriter.add(event); eventWriterWrapper.add(event); @@ -51,7 +51,7 @@ void testAdd() throws XMLStreamException { @Test void testAddReader() throws XMLStreamException { - XMLEventReader reader = mock(XMLEventReader.class); + XMLEventReader reader = mock(); xmlEventWriter.add(reader); eventWriterWrapper.add(reader); } @@ -70,7 +70,7 @@ void testFlush() throws XMLStreamException { @Test void testGetNamespaceContext() { - NamespaceContext context = mock(NamespaceContext.class); + NamespaceContext context = mock(); when(xmlEventWriter.getNamespaceContext()).thenReturn(context); assertEquals(eventWriterWrapper.getNamespaceContext(), context); } @@ -92,7 +92,7 @@ void testSetDefaultNamespace() throws XMLStreamException { @Test void testSetNamespaceContext() throws XMLStreamException { - NamespaceContext context = mock(NamespaceContext.class); + NamespaceContext context = mock(); xmlEventWriter.setNamespaceContext(context); eventWriterWrapper.setNamespaceContext(context); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/NoStartEndDocumentWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/NoStartEndDocumentWriterTests.java index 068cce26a1..1af18717f0 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/NoStartEndDocumentWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/NoStartEndDocumentWriterTests.java @@ -34,7 +34,7 @@ */ class NoStartEndDocumentWriterTests { - private final XMLEventWriter wrappedWriter = mock(XMLEventWriter.class); + private final XMLEventWriter wrappedWriter = mock(); private final NoStartEndDocumentStreamWriter writer = new NoStartEndDocumentStreamWriter(wrappedWriter); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnclosedElementCollectingEventWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnclosedElementCollectingEventWriterTests.java index af18881900..de1abda1e5 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnclosedElementCollectingEventWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnclosedElementCollectingEventWriterTests.java @@ -34,7 +34,7 @@ */ class UnclosedElementCollectingEventWriterTests { - private final XMLEventWriter wrappedWriter = mock(XMLEventWriter.class); + private final XMLEventWriter wrappedWriter = mock(); private final UnclosedElementCollectingEventWriter writer = new UnclosedElementCollectingEventWriter(wrappedWriter); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnopenedElementClosingEventWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnopenedElementClosingEventWriterTests.java index 1849ca3fdd..7287eb0fef 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnopenedElementClosingEventWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/UnopenedElementClosingEventWriterTests.java @@ -62,8 +62,8 @@ class UnopenedElementClosingEventWriterTests { @BeforeEach void setUp() { - wrappedWriter = mock(XMLEventWriter.class); - ioWriter = mock(Writer.class); + wrappedWriter = mock(); + ioWriter = mock(); unopenedElements.add(unopenedA); unopenedElements.add(unopenedB); writer = new UnopenedElementClosingEventWriter(wrappedWriter, ioWriter, unopenedElements); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTestUtils.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTestUtils.java index f58592b410..69947429c4 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTestUtils.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTestUtils.java @@ -54,9 +54,9 @@ public static DataSource getMockDataSource(String databaseProductName) throws Ex } public static DataSource getMockDataSource(String databaseProductName, String databaseVersion) throws Exception { - DatabaseMetaData dmd = mock(DatabaseMetaData.class); - DataSource ds = mock(DataSource.class); - Connection con = mock(Connection.class); + DatabaseMetaData dmd = mock(); + DataSource ds = mock(); + Connection con = mock(); when(ds.getConnection()).thenReturn(con); when(con.getMetaData()).thenReturn(dmd); when(dmd.getDatabaseProductName()).thenReturn(databaseProductName); @@ -67,7 +67,7 @@ public static DataSource getMockDataSource(String databaseProductName, String da } public static DataSource getMockDataSource(Exception e) throws Exception { - DataSource ds = mock(DataSource.class); + DataSource ds = mock(); when(ds.getConnection()).thenReturn(null); return ds; } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java index 1c236239df..6ef4df7735 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/transaction/TransactionAwareBufferedWriterTests.java @@ -53,7 +53,7 @@ class TransactionAwareBufferedWriterTests { @BeforeEach void init() { - fileChannel = mock(FileChannel.class); + fileChannel = mock(); writer = new TransactionAwareBufferedWriter(fileChannel, () -> { try { @@ -300,7 +300,7 @@ void testResourceKeyCollision() throws Exception { final String[] results = new String[limit]; for (int i = 0; i < limit; i++) { final int index = i; - FileChannel fileChannel = mock(FileChannel.class); + FileChannel fileChannel = mock(); when(fileChannel.write(any(ByteBuffer.class))).thenAnswer(invocation -> { ByteBuffer buffer = (ByteBuffer) invocation.getArguments()[0]; String val = new String(buffer.array(), StandardCharsets.UTF_8); diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilderTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilderTests.java index ffa1177996..097083fa8b 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilderTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/RemoteChunkingManagerStepBuilderTests.java @@ -232,12 +232,12 @@ void testSetters() throws Exception { NoBackOffPolicy backOffPolicy = new NoBackOffPolicy(); ItemStreamSupport stream = new ItemStreamSupport() { }; - StepExecutionListener stepExecutionListener = mock(StepExecutionListener.class); - ItemReadListener itemReadListener = mock(ItemReadListener.class); - ItemWriteListener itemWriteListener = mock(ItemWriteListener.class); - ChunkListener chunkListener = mock(ChunkListener.class); - SkipListener skipListener = mock(SkipListener.class); - RetryListener retryListener = mock(RetryListener.class); + StepExecutionListener stepExecutionListener = mock(); + ItemReadListener itemReadListener = mock(); + ItemWriteListener itemWriteListener = mock(); + ChunkListener chunkListener = mock(); + SkipListener skipListener = mock(); + RetryListener retryListener = mock(); when(retryListener.open(any(), any())).thenReturn(true); diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java index 9bb3314298..e9419e44c7 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/launch/JobLaunchingGatewayTests.java @@ -45,7 +45,7 @@ void testExceptionRaised() throws Exception { .withPayload(new JobLaunchRequest(new JobSupport("testJob"), new JobParameters())) .build(); - final JobLauncher jobLauncher = mock(JobLauncher.class); + final JobLauncher jobLauncher = mock(); when(jobLauncher.run(any(Job.class), any(JobParameters.class))) .thenThrow(new JobParametersInvalidException("This is a JobExecutionException.")); diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandlerTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandlerTests.java index 97200b2d7a..4f7b677649 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandlerTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/MessageChannelPartitionHandlerTests.java @@ -61,8 +61,8 @@ void testNoPartitions() throws Exception { // execute with no default set messageChannelPartitionHandler = new MessageChannelPartitionHandler(); // mock - StepExecution managerStepExecution = mock(StepExecution.class); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); + StepExecution managerStepExecution = mock(); + StepExecutionSplitter stepExecutionSplitter = mock(); // execute Collection executions = messageChannelPartitionHandler.handle(stepExecutionSplitter, @@ -77,10 +77,10 @@ void testHandleNoReply() throws Exception { // execute with no default set messageChannelPartitionHandler = new MessageChannelPartitionHandler(); // mock - StepExecution managerStepExecution = mock(StepExecution.class); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); - MessagingTemplate operations = mock(MessagingTemplate.class); - Message message = mock(Message.class); + StepExecution managerStepExecution = mock(); + StepExecutionSplitter stepExecutionSplitter = mock(); + MessagingTemplate operations = mock(); + Message message = mock(); // when HashSet stepExecutions = new HashSet<>(); stepExecutions.add(new StepExecution("step1", new JobExecution(5L))); @@ -104,11 +104,11 @@ void testHandleWithReplyChannel() throws Exception { // execute with no default set messageChannelPartitionHandler = new MessageChannelPartitionHandler(); // mock - StepExecution managerStepExecution = mock(StepExecution.class); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); - MessagingTemplate operations = mock(MessagingTemplate.class); - Message message = mock(Message.class); - PollableChannel replyChannel = mock(PollableChannel.class); + StepExecution managerStepExecution = mock(); + StepExecutionSplitter stepExecutionSplitter = mock(); + MessagingTemplate operations = mock(); + Message message = mock(); + PollableChannel replyChannel = mock(); // when HashSet stepExecutions = new HashSet<>(); stepExecutions.add(new StepExecution("step1", new JobExecution(5L))); @@ -134,10 +134,10 @@ void messageReceiveTimeout() throws Exception { // execute with no default set messageChannelPartitionHandler = new MessageChannelPartitionHandler(); // mock - StepExecution managerStepExecution = mock(StepExecution.class); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); - MessagingTemplate operations = mock(MessagingTemplate.class); - Message message = mock(Message.class); + StepExecution managerStepExecution = mock(); + StepExecutionSplitter stepExecutionSplitter = mock(); + MessagingTemplate operations = mock(); + Message message = mock(); // when HashSet stepExecutions = new HashSet<>(); stepExecutions.add(new StepExecution("step1", new JobExecution(5L))); @@ -158,9 +158,9 @@ void testHandleWithJobRepositoryPolling() throws Exception { // mock JobExecution jobExecution = new JobExecution(5L, new JobParameters()); StepExecution managerStepExecution = new StepExecution("step1", jobExecution, 1L); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); - MessagingTemplate operations = mock(MessagingTemplate.class); - JobExplorer jobExplorer = mock(JobExplorer.class); + StepExecutionSplitter stepExecutionSplitter = mock(); + MessagingTemplate operations = mock(); + JobExplorer jobExplorer = mock(); // when HashSet stepExecutions = new HashSet<>(); StepExecution partition1 = new StepExecution("step1:partition1", jobExecution, 2L); @@ -210,9 +210,9 @@ void testHandleWithJobRepositoryPollingTimeout() throws Exception { // mock JobExecution jobExecution = new JobExecution(5L, new JobParameters()); StepExecution managerStepExecution = new StepExecution("step1", jobExecution, 1L); - StepExecutionSplitter stepExecutionSplitter = mock(StepExecutionSplitter.class); - MessagingTemplate operations = mock(MessagingTemplate.class); - JobExplorer jobExplorer = mock(JobExplorer.class); + StepExecutionSplitter stepExecutionSplitter = mock(); + MessagingTemplate operations = mock(); + JobExplorer jobExplorer = mock(); // when HashSet stepExecutions = new HashSet<>(); StepExecution partition1 = new StepExecution("step1:partition1", jobExecution, 2L); diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderTests.java index fc9ca6d282..035bfedaad 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderTests.java @@ -142,7 +142,7 @@ void eitherOutputChannelOrMessagingTemplateMustBeProvided() { @Test void testUnsupportedOperationExceptionWhenSpecifyingPartitionHandler() { // given - PartitionHandler partitionHandler = Mockito.mock(PartitionHandler.class); + PartitionHandler partitionHandler = Mockito.mock(); final RemotePartitioningManagerStepBuilder builder = new RemotePartitioningManagerStepBuilder("step", this.jobRepository); @@ -165,7 +165,7 @@ void testManagerStepCreationWhenPollingRepository() { long timeout = 1000L; long pollInterval = 5000L; DirectChannel outputChannel = new DirectChannel(); - Partitioner partitioner = Mockito.mock(Partitioner.class); + Partitioner partitioner = Mockito.mock(); StepExecutionAggregator stepExecutionAggregator = (result, executions) -> { }; @@ -208,7 +208,7 @@ void testManagerStepCreationWhenAggregatingReplies() { int gridSize = 5; int startLimit = 3; DirectChannel outputChannel = new DirectChannel(); - Partitioner partitioner = Mockito.mock(Partitioner.class); + Partitioner partitioner = Mockito.mock(); StepExecutionAggregator stepExecutionAggregator = (result, executions) -> { }; diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/OrderItemReaderTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/OrderItemReaderTests.java index 01a6e16b30..97ecc7dbfd 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/OrderItemReaderTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/OrderItemReaderTests.java @@ -36,7 +36,7 @@ class OrderItemReaderTests { @BeforeEach @SuppressWarnings("unchecked") void setUp() { - input = mock(ItemReader.class); + input = mock(); provider = new OrderItemReader(); provider.setFieldSetReader(input); @@ -76,7 +76,7 @@ void testNext() throws Exception { LineItem item = new LineItem(); @SuppressWarnings("rawtypes") - FieldSetMapper mapper = mock(FieldSetMapper.class); + FieldSetMapper mapper = mock(); when(mapper.mapFieldSet(headerFS)).thenReturn(order); when(mapper.mapFieldSet(customerFS)).thenReturn(customer); when(mapper.mapFieldSet(billingFS)).thenReturn(billing); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/CustomerUpdateProcessorTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/CustomerUpdateProcessorTests.java index 727fe9acbd..39435aa2fe 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/CustomerUpdateProcessorTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/CustomerUpdateProcessorTests.java @@ -41,8 +41,8 @@ class CustomerUpdateProcessorTests { @BeforeEach void init() { - customerDao = mock(CustomerDao.class); - logger = mock(InvalidCustomerLogger.class); + customerDao = mock(); + logger = mock(); processor = new CustomerUpdateProcessor(); processor.setCustomerDao(customerDao); processor.setInvalidCustomerLogger(logger); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdatePreparedStatementSetterTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdatePreparedStatementSetterTests.java index 07b9db5f94..3c8123edfa 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdatePreparedStatementSetterTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdatePreparedStatementSetterTests.java @@ -40,7 +40,7 @@ class CustomerCreditUpdatePreparedStatementSetterTests { @BeforeEach void setUp() { - ps = mock(PreparedStatement.class); + ps = mock(); credit = new CustomerCredit(); credit.setId(13); credit.setCredit(new BigDecimal(12000)); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdateProcessorTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdateProcessorTests.java index fab13fba93..9a61d998ec 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdateProcessorTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/CustomerCreditUpdateProcessorTests.java @@ -35,7 +35,7 @@ class CustomerCreditUpdateProcessorTests { @BeforeEach void setUp() { - dao = mock(CustomerCreditDao.class); + dao = mock(); writer = new CustomerCreditUpdateWriter(); writer.setDao(dao); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/FlatFileCustomerCreditDaoTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/FlatFileCustomerCreditDaoTests.java index e442ea4142..9a6e41d9a1 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/FlatFileCustomerCreditDaoTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/FlatFileCustomerCreditDaoTests.java @@ -35,7 +35,7 @@ class FlatFileCustomerCreditDaoTests { @BeforeEach void setUp() { - output = mock(ResourceLifecycleItemWriter.class); + output = mock(); writer = new FlatFileCustomerCreditDao(); writer.setItemWriter(output); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessorTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessorTests.java index 4a130314dd..38452d3138 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessorTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessorTests.java @@ -31,7 +31,7 @@ class TradeProcessorTests { @BeforeEach void setUp() { - writer = mock(TradeDao.class); + writer = mock(); processor = new TradeWriter(); processor.setDao(writer); diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/quartz/JobLauncherDetailsTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/quartz/JobLauncherDetailsTests.java index ec270ebba2..0e6bd32b8d 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/quartz/JobLauncherDetailsTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/quartz/JobLauncherDetailsTests.java @@ -133,7 +133,7 @@ void testExecuteWithJobNameAndComplexParameters() { private final class StubJobExecutionContext extends JobExecutionContextImpl { private StubJobExecutionContext() { - super(mock(Scheduler.class), firedBundle, mock(Job.class)); + super(mock(), firedBundle, mock()); } } diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/AbstractRowMapperTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/AbstractRowMapperTests.java index 934c2975ee..10e73b0826 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/AbstractRowMapperTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/AbstractRowMapperTests.java @@ -38,7 +38,7 @@ public abstract class AbstractRowMapperTests { private static final int IGNORED_ROW_NUMBER = 0; // mock result set - private final ResultSet rs = mock(ResultSet.class); + private final ResultSet rs = mock(); /** * @return Expected result of mapping the mock ResultSet by the mapper diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/context/BatchTestContextCustomizerTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/context/BatchTestContextCustomizerTests.java index aad114c2bb..efb96008f6 100644 --- a/spring-batch-test/src/test/java/org/springframework/batch/test/context/BatchTestContextCustomizerTests.java +++ b/spring-batch-test/src/test/java/org/springframework/batch/test/context/BatchTestContextCustomizerTests.java @@ -46,7 +46,7 @@ void removeSystemProperty() { void testCustomizeContext() { // given ConfigurableApplicationContext context = new GenericApplicationContext(); - MergedContextConfiguration mergedConfig = Mockito.mock(MergedContextConfiguration.class); + MergedContextConfiguration mergedConfig = Mockito.mock(); // when this.contextCustomizer.customizeContext(context, mergedConfig); @@ -60,8 +60,8 @@ void testCustomizeContext() { @Test void testCustomizeContext_whenBeanFactoryIsNotAnInstanceOfBeanDefinitionRegistry() { // given - ConfigurableApplicationContext context = Mockito.mock(ConfigurableApplicationContext.class); - MergedContextConfiguration mergedConfig = Mockito.mock(MergedContextConfiguration.class); + ConfigurableApplicationContext context = Mockito.mock(); + MergedContextConfiguration mergedConfig = Mockito.mock(); // when final Exception expectedException = assertThrows(IllegalArgumentException.class, @@ -77,7 +77,7 @@ void testCustomizeContext_whenUsingAotGeneratedArtifactsBatchTestContextIsNotReg // given SpringProperties.setProperty("spring.aot.enabled", "true"); ConfigurableApplicationContext context = new GenericApplicationContext(); - MergedContextConfiguration mergedConfig = Mockito.mock(MergedContextConfiguration.class); + MergedContextConfiguration mergedConfig = Mockito.mock(); // when this.contextCustomizer.customizeContext(context, mergedConfig); From 8822cdfb34a2bb1177ac6e2eb2ed18e0ec60ca31 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Thu, 3 Aug 2023 10:02:47 +0200 Subject: [PATCH 07/68] Upgrade Spring dependencies to latest snapshots --- pom.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 390eab4dbe..8253402cf8 100644 --- a/pom.xml +++ b/pom.xml @@ -61,18 +61,18 @@ 17 - 6.0.9 - 2.0.1 - 6.0.5 - 1.10.7 + 6.0.12-SNAPSHOT + 2.0.3-SNAPSHOT + 6.0.7-SNAPSHOT + 1.10.10-SNAPSHOT - 3.0.6 - 3.0.6 - 4.0.6 - 3.0.7 - 3.0.4 - 3.0.3 + 3.0.9-SNAPSHOT + 3.0.9-SNAPSHOT + 4.0.9-SNAPSHOT + 3.0.10-SNAPSHOT + 3.0.8-SNAPSHOT + 3.0.5-SNAPSHOT 2.14.3 1.9.2 @@ -91,7 +91,7 @@ 3.0.2 - 1.0.5 + 1.1.4-SNAPSHOT 1.4.20 4.13.2 From d9d6a8d0b5c7c98913a01abecd2833d5d1284eb0 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Thu, 3 Aug 2023 11:32:03 +0200 Subject: [PATCH 08/68] Update trusted classes in Jackson2ExecutionContextStringSerializer Resolves #4407 (cherry picked from commit 9323b27d6ad45c0590012221cfbc6aca6f3d9d4f) --- .../dao/Jackson2ExecutionContextStringSerializer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java index 9748d469a1..8b67b6a1d5 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java @@ -295,7 +295,8 @@ static class TrustedTypeIdResolver implements TypeIdResolver { "java.lang.Byte", "java.lang.Short", "java.lang.Integer", "java.lang.Long", "java.lang.Double", "java.lang.Float", "java.math.BigDecimal", "java.math.BigInteger", "java.lang.String", "java.lang.Character", "java.lang.CharSequence", "java.util.Properties", "[Ljava.util.Properties;", - "org.springframework.batch.core.JobParameter", "org.springframework.batch.core.JobParameters"); + "org.springframework.batch.core.JobParameter", "org.springframework.batch.core.JobParameters", + "java.util.concurrent.ConcurrentHashMap", "java.sql.Date"); private final Set trustedClassNames = new LinkedHashSet<>(TRUSTED_CLASS_NAMES); From 7812c00c6cae91717de587972b445f069e2516dd Mon Sep 17 00:00:00 2001 From: Taeik Lim Date: Mon, 11 Apr 2022 23:29:06 +0900 Subject: [PATCH 09/68] Prevent race condition when flow transition is not initialized Resolves #4092 (cherry picked from commit 99e8d58c135e1a195665eaaefb86b0e8e225cdda) --- .../batch/core/job/flow/support/SimpleFlow.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) 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 2101c171d4..f66ce004c2 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 @@ -48,6 +48,7 @@ * @author Dave Syer * @author Michael Minella * @author Mahmoud Ben Hassine + * @author Taeik Lim * @since 2.0 */ public class SimpleFlow implements Flow, InitializingBean { @@ -124,9 +125,7 @@ public Collection getStates() { */ @Override public void afterPropertiesSet() throws Exception { - if (startState == null) { - initializeTransitions(); - } + initializeTransitionsIfNotInitialized(); } /** @@ -134,9 +133,8 @@ public void afterPropertiesSet() throws Exception { */ @Override public FlowExecution start(FlowExecutor executor) throws FlowExecutionException { - if (startState == null) { - initializeTransitions(); - } + initializeTransitionsIfNotInitialized(); + State state = startState; String stateName = state.getName(); return resume(stateName, executor); @@ -262,6 +260,12 @@ protected boolean isFlowContinued(State state, FlowExecutionStatus status, StepE return continued; } + private synchronized void initializeTransitionsIfNotInitialized() { + if (startState == null) { + initializeTransitions(); + } + } + /** * Analyse the transitions provided and generate all the information needed to execute * the flow. From 1b08c26d3feb4a5bb94ea4dd916ff81228719d6f Mon Sep 17 00:00:00 2001 From: Shaoqiang Lu Date: Sun, 16 Jul 2023 12:13:16 +0800 Subject: [PATCH 10/68] Replace Charset.defaultCharset() with StandardCharsets.UTF_8 in tests Resolves #4417 (cherry picked from commit 14b6c66543213e4f8a4bd247b313079525390c1d) --- .../item/file/builder/FlatFileItemWriterBuilderTests.java | 6 +++--- .../batch/item/json/JsonFileItemWriterFunctionalTests.java | 3 +-- .../item/json/builder/JsonFileItemWriterBuilderTests.java | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilderTests.java index 1f94531a7a..855876c322 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/builder/FlatFileItemWriterBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 the original author or authors. + * Copyright 2016-2023 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. @@ -19,7 +19,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import org.junit.jupiter.api.Test; @@ -266,7 +266,7 @@ void testFlags() throws Exception { WritableResource output = new FileSystemResource(File.createTempFile("foo", "txt")); - String encoding = Charset.defaultCharset().name(); + String encoding = StandardCharsets.UTF_8.name(); FlatFileItemWriter writer = new FlatFileItemWriterBuilder().name("foo") .resource(output) diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonFileItemWriterFunctionalTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonFileItemWriterFunctionalTests.java index 3612ba984d..a8d24a2534 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonFileItemWriterFunctionalTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonFileItemWriterFunctionalTests.java @@ -19,7 +19,6 @@ import java.io.File; import java.io.IOException; import java.math.BigDecimal; -import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -334,7 +333,7 @@ private void assertFileEquals(File expected, File actual) throws Exception { } private String getContent(File file) throws IOException { - return Files.readString(file.toPath(), Charset.defaultCharset()); + return Files.readString(file.toPath()); } } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java index fc19f18c99..da3e032beb 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/builder/JsonFileItemWriterBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 the original author or authors. + * Copyright 2018-2023 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,7 +17,7 @@ package org.springframework.batch.item.json.builder; import java.io.File; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import org.junit.jupiter.api.BeforeEach; @@ -112,7 +112,7 @@ void testJsonFileItemWriterCreationDefaultEncoding() { boolean transactional = true; boolean shouldDeleteIfEmpty = true; boolean shouldDeleteIfExists = true; - String encoding = Charset.defaultCharset().name(); + String encoding = StandardCharsets.UTF_8.name(); String lineSeparator = "#"; FlatFileHeaderCallback headerCallback = Mockito.mock(); FlatFileFooterCallback footerCallback = Mockito.mock(); From 52251ef323b7d1cf680e0107ae2cbe863dd1c08e Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 23 Aug 2023 09:23:23 -0700 Subject: [PATCH 11/68] Prepare release 5.0.3 --- pom.xml | 66 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index 8253402cf8..3a395ef430 100644 --- a/pom.xml +++ b/pom.xml @@ -61,25 +61,25 @@ 17 - 6.0.12-SNAPSHOT - 2.0.3-SNAPSHOT - 6.0.7-SNAPSHOT - 1.10.10-SNAPSHOT + 6.0.11 + 2.0.2 + 6.0.7 + 1.10.10 - 3.0.9-SNAPSHOT - 3.0.9-SNAPSHOT - 4.0.9-SNAPSHOT - 3.0.10-SNAPSHOT - 3.0.8-SNAPSHOT - 3.0.5-SNAPSHOT + 3.0.9 + 3.0.9 + 4.0.9 + 3.0.10 + 3.0.8 + 3.0.5 2.14.3 1.9.2 2.9.1 6.1.7.Final 2.1.1 - 2.1.1 + 2.1.2 3.1.0 3.0.2 3.1.0 @@ -91,49 +91,49 @@ 3.0.2 - 1.1.4-SNAPSHOT + 1.1.4 1.4.20 4.13.2 ${junit-jupiter.version} 2.2 3.24.2 - 5.3.1 + 5.5.0 2.9.1 - 2.11.0 + 2.13.0 2.9.0 2.0.7 - 2.7.1 - 2.1.214 - 3.41.2.1 + 2.7.2 + 2.2.220 + 3.42.0.0 10.16.1.1 2.16.14 - 2.28.0 - 4.0.2 + 2.30.0 + 4.0.3 2.20.0 - 8.0.0.Final + 8.0.1.Final 5.0.1 4.0.2 2.0.1 4.0.0 - 2.0.1 + 2.0.2 6.5.1 - 1.9.19 - 8.0.33 + 1.9.20 + 8.1.0 3.1.4 42.6.0 11.5.8.0 - 19.18.0.0 + 19.20.0.0 11.2.3.jre17 1.3.1 - 1.18.1 + 1.19.0 1.5.1 ${spring-amqp.version} 2.3.2 0.16.0 - 3.0.15 + 3.0.19 1.6.2 @@ -141,19 +141,19 @@ 0.0.5 - 3.10.1 - 3.1.0 - 3.1.0 + 3.11.0 + 3.1.2 + 3.1.2 3.5.0 - 3.2.1 + 3.3.0 0.8.10 1.5.0 3.1.1 - 2.2.3 + 2.2.4 3.6.0 - 3.5.0 + 3.6.0 3.12.1 - 3.4.3 + 3.4.5 3.3.0 0.0.39 From 06614a591f15427d1bdba55cddb16d10d597b78d Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 23 Aug 2023 09:47:10 -0700 Subject: [PATCH 12/68] Add branch reference in artifactory staging workflow --- .github/workflows/artifactory-staging.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/artifactory-staging.yml b/.github/workflows/artifactory-staging.yml index ae8a04859c..13dbf9298e 100644 --- a/.github/workflows/artifactory-staging.yml +++ b/.github/workflows/artifactory-staging.yml @@ -14,6 +14,8 @@ jobs: steps: - name: Checkout source code uses: actions/checkout@v3 + with: + ref: '5.0.x' - name: Set up JDK 17 uses: actions/setup-java@v3 From 1c81b8237ea9912110042b05e8dc09d928787a9f Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 23 Aug 2023 10:27:29 -0700 Subject: [PATCH 13/68] Release version 5.0.3 --- pom.xml | 2 +- spring-batch-bom/pom.xml | 2 +- spring-batch-core/pom.xml | 2 +- spring-batch-docs/pom.xml | 2 +- spring-batch-infrastructure/pom.xml | 2 +- spring-batch-integration/pom.xml | 2 +- spring-batch-samples/pom.xml | 2 +- spring-batch-test/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 3a395ef430..d6c4f73115 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. Spring Batch is part of the Spring Portfolio. - 5.0.3-SNAPSHOT + 5.0.3 pom https://projects.spring.io/spring-batch diff --git a/spring-batch-bom/pom.xml b/spring-batch-bom/pom.xml index 88cab82c3c..f0fadb8b4e 100644 --- a/spring-batch-bom/pom.xml +++ b/spring-batch-bom/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.3 spring-batch-bom pom diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index 6527acf379..e226ae0b8f 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.3 spring-batch-core jar diff --git a/spring-batch-docs/pom.xml b/spring-batch-docs/pom.xml index f59eb521be..852e3846f9 100644 --- a/spring-batch-docs/pom.xml +++ b/spring-batch-docs/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.3 spring-batch-docs Spring Batch Docs diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index 432a276385..f9a607b1c9 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.3 spring-batch-infrastructure jar diff --git a/spring-batch-integration/pom.xml b/spring-batch-integration/pom.xml index bd69db83b1..358869c183 100644 --- a/spring-batch-integration/pom.xml +++ b/spring-batch-integration/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.3 spring-batch-integration Spring Batch Integration diff --git a/spring-batch-samples/pom.xml b/spring-batch-samples/pom.xml index 5f340c5c8e..087fcfc0b6 100644 --- a/spring-batch-samples/pom.xml +++ b/spring-batch-samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.3 spring-batch-samples jar diff --git a/spring-batch-test/pom.xml b/spring-batch-test/pom.xml index 31df071856..b323132aee 100644 --- a/spring-batch-test/pom.xml +++ b/spring-batch-test/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3-SNAPSHOT + 5.0.3 spring-batch-test Spring Batch Test From 2fd446b2b48f166169ccf03f4d1b98413a23b510 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 23 Aug 2023 10:27:59 -0700 Subject: [PATCH 14/68] Next development version --- pom.xml | 2 +- spring-batch-bom/pom.xml | 2 +- spring-batch-core/pom.xml | 2 +- spring-batch-docs/pom.xml | 2 +- spring-batch-infrastructure/pom.xml | 2 +- spring-batch-integration/pom.xml | 2 +- spring-batch-samples/pom.xml | 2 +- spring-batch-test/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index d6c4f73115..1fa3556afd 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. Spring Batch is part of the Spring Portfolio. - 5.0.3 + 5.0.4-SNAPSHOT pom https://projects.spring.io/spring-batch diff --git a/spring-batch-bom/pom.xml b/spring-batch-bom/pom.xml index f0fadb8b4e..3909a20064 100644 --- a/spring-batch-bom/pom.xml +++ b/spring-batch-bom/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3 + 5.0.4-SNAPSHOT spring-batch-bom pom diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index e226ae0b8f..cf7a2e33b5 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3 + 5.0.4-SNAPSHOT spring-batch-core jar diff --git a/spring-batch-docs/pom.xml b/spring-batch-docs/pom.xml index 852e3846f9..5f3298b703 100644 --- a/spring-batch-docs/pom.xml +++ b/spring-batch-docs/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3 + 5.0.4-SNAPSHOT spring-batch-docs Spring Batch Docs diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index f9a607b1c9..cfaa79160e 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3 + 5.0.4-SNAPSHOT spring-batch-infrastructure jar diff --git a/spring-batch-integration/pom.xml b/spring-batch-integration/pom.xml index 358869c183..a92c734b4f 100644 --- a/spring-batch-integration/pom.xml +++ b/spring-batch-integration/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3 + 5.0.4-SNAPSHOT spring-batch-integration Spring Batch Integration diff --git a/spring-batch-samples/pom.xml b/spring-batch-samples/pom.xml index 087fcfc0b6..73b894a807 100644 --- a/spring-batch-samples/pom.xml +++ b/spring-batch-samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3 + 5.0.4-SNAPSHOT spring-batch-samples jar diff --git a/spring-batch-test/pom.xml b/spring-batch-test/pom.xml index b323132aee..780884c908 100644 --- a/spring-batch-test/pom.xml +++ b/spring-batch-test/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.3 + 5.0.4-SNAPSHOT spring-batch-test Spring Batch Test From 721f3781000e601e6f41054158454247b20a4454 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 13 Sep 2023 16:04:44 +0200 Subject: [PATCH 15/68] Add utility method to get identifying job parameters (cherry picked from commit 8a6c7ac3c532639a026e423cc1c9d512c0fe06b8) --- .../batch/core/JobParameters.java | 15 +++++++++++++++ ...kson2ExecutionContextStringSerializer.java | 3 +++ .../batch/core/JobParametersTests.java | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java index 44078f7db0..586f7ab62f 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java @@ -330,6 +330,21 @@ public Map> getParameters() { return Collections.unmodifiableMap(parameters); } + /** + * Get a map of identifying parameters. + * @since 5.1 + * @return an unmodifiable map containing identifying parameters. + */ + public Map> getIdentifyingParameters() { + Map> identifyingParameters = new HashMap<>(); + for (Map.Entry> entry : this.parameters.entrySet()) { + if (entry.getValue().isIdentifying()) { + identifyingParameters.put(entry.getKey(), entry.getValue()); + } + } + return Collections.unmodifiableMap(identifyingParameters); + } + /** * @return {@code true} if the parameters object is empty or {@code false} otherwise. */ diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java index 8b67b6a1d5..3e5fe34e2c 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/Jackson2ExecutionContextStringSerializer.java @@ -174,6 +174,9 @@ private abstract class JobParametersMixIn { @JsonIgnore abstract boolean isEmpty(); + @JsonIgnore + abstract Map> getIdentifyingParameters(); + } private class JobParameterSerializer extends StdSerializer { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersTests.java index b3a4b310d8..28c70c7615 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersTests.java @@ -187,6 +187,25 @@ void testSerialization() { assertEquals(params, SerializationUtils.clone(params)); } + @Test + void testGetIdentifyingParameters() { + // given + Map> parametersMap = new HashMap<>(); + JobParameter jobParameter1 = new JobParameter<>("value1", String.class, true); + JobParameter jobParameter2 = new JobParameter<>("value2", String.class, false); + parametersMap.put("key1", jobParameter1); + parametersMap.put("key2", jobParameter2); + JobParameters parameters = new JobParameters(parametersMap); + + // when + Map> identifyingParameters = parameters.getIdentifyingParameters(); + + // then + assertEquals(1, identifyingParameters.size()); + JobParameter key1 = identifyingParameters.get("key1"); + assertEquals(jobParameter1, key1); + } + @Test void testLongReturnsNullWhenKeyDoesntExit() { assertNull(new JobParameters().getLong("keythatdoesntexist")); From f7c3af1f90977966fea8935abc8a2c906c6d0f2c Mon Sep 17 00:00:00 2001 From: Mark John Moreno Date: Tue, 16 May 2023 19:37:28 +0800 Subject: [PATCH 16/68] Align exception message with exception handling condition Resolves #4025 (cherry picked from commit 11169bae108e2fe7825dbe34a482f400a40fb513) --- .../repository/support/SimpleJobRepository.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java index 20eaacafe6..a427dbfa35 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java @@ -21,7 +21,6 @@ import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; -import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; @@ -54,6 +53,7 @@ * @author Mahmoud Ben Hassine * @author Baris Cubukcuoglu * @author Parikshit Dutta + * @author Mark John Moreno * @see JobRepository * @see JobInstanceDao * @see JobExecutionDao @@ -151,15 +151,14 @@ public JobExecution createJobExecution(String jobName, JobParameters jobParamete + "The last execution ended with a failure that could not be rolled back, " + "so it may be dangerous to proceed. Manual intervention is probably necessary."); } - Collection> allJobParameters = execution.getJobParameters().getParameters().values(); - long identifyingJobParametersCount = allJobParameters.stream() - .filter(JobParameter::isIdentifying) - .count(); - if (identifyingJobParametersCount > 0 + JobParameters allJobParameters = execution.getJobParameters(); + JobParameters identifyingJobParameters = new JobParameters(allJobParameters.getIdentifyingParameters()); + if (!identifyingJobParameters.isEmpty() && (status == BatchStatus.COMPLETED || status == BatchStatus.ABANDONED)) { throw new JobInstanceAlreadyCompleteException( - "A job instance already exists and is complete for parameters=" + jobParameters - + ". If you want to run this job again, change the parameters."); + "A job instance already exists and is complete for identifying parameters=" + + identifyingJobParameters + ". If you want to run this job again, " + + "change the parameters."); } } executionContext = ecDao.getExecutionContext(jobExecutionDao.getLastJobExecution(jobInstance)); From b4cb1f3d56956e59cb34da25b88c5f671659fe24 Mon Sep 17 00:00:00 2001 From: sjh836 Date: Wed, 15 Sep 2021 01:53:48 +0900 Subject: [PATCH 17/68] Change from arrayList to immutableList in OrderedComposite#iterator (cherry picked from commit d9bf57e57288be6147c921c05ca9a4bb56735a13) --- .../springframework/batch/core/listener/OrderedComposite.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/OrderedComposite.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/OrderedComposite.java index abd24cbc77..75f9c2516c 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/OrderedComposite.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/OrderedComposite.java @@ -83,7 +83,7 @@ else if (!unordered.contains(item)) { * @return an iterator over the list of items */ public Iterator iterator() { - return new ArrayList<>(list).iterator(); + return Collections.unmodifiableList(list).iterator(); } /** From 87d0c4d3a39ee461043e9716ec71ce8d27351748 Mon Sep 17 00:00:00 2001 From: ParadiseCHOI Date: Thu, 30 Sep 2021 07:52:36 +0900 Subject: [PATCH 18/68] Remove unnecessary expressions in AsyncItemWriter Issue #4009 (cherry picked from commit 48925f0db4da8e9f2d69779f82a4e25adb3aa6dc) --- .../batch/integration/async/AsyncItemWriter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemWriter.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemWriter.java index 4b3336afc6..1d69d4d18a 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemWriter.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/async/AsyncItemWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 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. @@ -67,13 +67,13 @@ public void write(Chunk> items) throws Exception { T item = future.get(); if (item != null) { - list.add(future.get()); + list.add(item); } } catch (ExecutionException e) { Throwable cause = e.getCause(); - if (cause != null && cause instanceof Exception) { + if (cause instanceof Exception) { logger.debug("An exception was thrown while processing an item", e); throw (Exception) cause; From 566b68089b9b862037134caba9c576e8d891f5fe Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Thu, 14 Sep 2023 11:50:00 +0200 Subject: [PATCH 19/68] Update Spring dependencies to latest snapshots --- pom.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 1fa3556afd..32f5ea138f 100644 --- a/pom.xml +++ b/pom.xml @@ -61,18 +61,18 @@ 17 - 6.0.11 - 2.0.2 - 6.0.7 - 1.10.10 + 6.0.13-SNAPSHOT + 2.0.4-SNAPSHOT + 6.0.8-SNAPSHOT + 1.10.12-SNAPSHOT - 3.0.9 - 3.0.9 - 4.0.9 - 3.0.10 - 3.0.8 - 3.0.5 + 3.0.11-SNAPSHOT + 3.0.11-SNAPSHOT + 4.0.11-SNAPSHOT + 3.0.12-SNAPSHOT + 3.0.10-SNAPSHOT + 3.0.6-SNAPSHOT 2.14.3 1.9.2 @@ -91,7 +91,7 @@ 3.0.2 - 1.1.4 + 1.1.6-SNAPSHOT 1.4.20 4.13.2 From 955f9a48ead342bdf129256497eb245fa912ee22 Mon Sep 17 00:00:00 2001 From: Jan-Willem Willebrands Date: Tue, 3 Oct 2023 14:39:34 +0200 Subject: [PATCH 20/68] Copy missing Context keys from JobParameters Fix DefaultJobParametersExtractor to copy values from JobParameters when they are missing from ExecutionContext. Javadoc states this class is supposed to do just that, but seems to have broken in the 5.x API revamp. Resolves #4458 (cherry picked from commit b2a287da93982461fcfa484d9b5443f46f44fa8c) --- .../job/DefaultJobParametersExtractor.java | 3 +++ .../DefaultJobParametersExtractorTests.java | 25 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) 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 948b144712..f37de435a5 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 @@ -79,6 +79,9 @@ public JobParameters getJobParameters(Job job, StepExecution stepExecution) { if (executionContext.containsKey(key)) { properties.setProperty(key, executionContext.getString(key)); } + else if (jobParameters.containsKey(key)) { + builder.addJobParameter(key, jobParameters.get(key)); + } } builder.addJobParameters(this.jobParametersConverter.getJobParameters(properties)); return builder.toJobParameters(); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractorTests.java index 1f124694d1..c94a6d2de5 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/DefaultJobParametersExtractorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 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. @@ -18,10 +18,12 @@ import org.junit.jupiter.api.Test; import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.StepExecution; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -109,4 +111,25 @@ void testDontUseParentParameters() { assertNotNull(jobParameters.getParameter("foo").getValue()); } + @Test + public void testGetKeysFromParentParametersWhenNotInExecutionContext() { + DefaultJobParametersExtractor extractor = new DefaultJobParametersExtractor(); + extractor.setUseAllParentParameters(false); + + JobExecution jobExecution = new JobExecution(0L, + new JobParametersBuilder().addString("parentParam", "val").addDouble("foo", 22.2).toJobParameters()); + + StepExecution stepExecution = new StepExecution("step", jobExecution); + + stepExecution.getExecutionContext().put("foo", "11.1,java.lang.Double"); + extractor.setKeys(new String[] { "foo", "parentParam" }); + + JobParameters jobParameters = extractor.getJobParameters(null, stepExecution); + + assertThat(jobParameters.getParameter("parentParam")).isNotNull() + .extracting(JobParameter::getValue) + .isEqualTo("val"); + assertEquals(11.1, jobParameters.getDouble("foo")); + } + } From adc3a422d47227ef1ae769c92465122c508fc2e2 Mon Sep 17 00:00:00 2001 From: "injae.kim" Date: Wed, 25 Oct 2023 20:26:27 +0900 Subject: [PATCH 21/68] Fix infinite loop in FlowBuilder#next() Resolves #4432 (cherry picked from commit 4a67b22e9040e5e4c69da3eb1b95dcd27f6cdc0e) --- .../batch/core/job/builder/FlowBuilder.java | 26 ++++-- .../core/job/builder/FlowBuilderTests.java | 90 ++++++++++++++++--- 2 files changed, 94 insertions(+), 22 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowBuilder.java index dde3e6571c..db072f65de 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowBuilder.java @@ -48,6 +48,7 @@ * @author Dave Syer * @author Michael Minella * @author Mahmoud Ben Hassine + * @author Injae Kim * @since 2.2 * @param the type of object returned by the builder (by default a Flow) * @@ -107,7 +108,8 @@ public Q build() { /** * Transition to the next step on successful completion of the current step. All other - * outcomes are treated as failures. + * outcomes are treated as failures. If no steps are registered yet, then this method + * will behave in the same way as {@link #start(Step)}. * @param step the next step * @return this to enable chaining */ @@ -250,26 +252,32 @@ private void doNext(Object input) { if (this.currentState == null) { doStart(input); } - State next = createState(input); - addTransition("COMPLETED", next); - addTransition("*", failedState); - this.currentState = next; + else { + State next = createState(input); + addTransition("COMPLETED", next); + addTransition("*", failedState); + this.currentState = next; + } } private void doStart(Object input) { if (this.currentState != null) { doFrom(input); } - this.currentState = createState(input); + else { + this.currentState = createState(input); + } } private void doFrom(Object input) { if (currentState == null) { doStart(input); } - State state = createState(input); - tos.put(currentState.getName(), currentState); - this.currentState = state; + else { + State state = createState(input); + tos.put(currentState.getName(), currentState); + this.currentState = state; + } } private State createState(Object input) { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowBuilderTests.java index cfe457aae1..dd47b49999 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 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. @@ -19,6 +19,7 @@ import org.junit.jupiter.api.Test; +import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInterruptedException; @@ -34,26 +35,79 @@ import org.springframework.batch.core.step.StepSupport; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; /** * @author Dave Syer * @author Michael Minella * @author Mahmoud Ben Hassine + * @author Injae Kim * */ class FlowBuilderTests { @Test - void test() throws Exception { + void testNext() throws Exception { FlowBuilder builder = new FlowBuilder<>("flow"); JobRepository jobRepository = new JobRepositorySupport(); JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters()); - builder.start(new StepSupport("step") { - @Override - public void execute(StepExecution stepExecution) - throws JobInterruptedException, UnexpectedJobExecutionException { - } - }).end().start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); + + builder.next(createCompleteStep("stepA")) + .end() + .start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); + + Iterator stepExecutions = execution.getStepExecutions().iterator(); + assertEquals(stepExecutions.next().getStepName(), "stepA"); + assertFalse(stepExecutions.hasNext()); + } + + @Test + void testMultipleNext() throws Exception { + FlowBuilder builder = new FlowBuilder<>("flow"); + JobRepository jobRepository = new JobRepositorySupport(); + JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters()); + + builder.next(createCompleteStep("stepA")) + .next(createCompleteStep("stepB")) + .next(createCompleteStep("stepC")) + .end() + .start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); + + Iterator stepExecutions = execution.getStepExecutions().iterator(); + assertEquals(stepExecutions.next().getStepName(), "stepA"); + assertEquals(stepExecutions.next().getStepName(), "stepB"); + assertEquals(stepExecutions.next().getStepName(), "stepC"); + assertFalse(stepExecutions.hasNext()); + } + + @Test + void testStart() throws Exception { + FlowBuilder builder = new FlowBuilder<>("flow"); + JobRepository jobRepository = new JobRepositorySupport(); + JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters()); + + builder.start(createCompleteStep("stepA")) + .end() + .start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); + + Iterator stepExecutions = execution.getStepExecutions().iterator(); + assertEquals(stepExecutions.next().getStepName(), "stepA"); + assertFalse(stepExecutions.hasNext()); + } + + @Test + void testFrom() throws Exception { + FlowBuilder builder = new FlowBuilder<>("flow"); + JobRepository jobRepository = new JobRepositorySupport(); + JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters()); + + builder.from(createCompleteStep("stepA")) + .end() + .start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); + + Iterator stepExecutions = execution.getStepExecutions().iterator(); + assertEquals(stepExecutions.next().getStepName(), "stepA"); + assertFalse(stepExecutions.hasNext()); } @Test @@ -66,7 +120,7 @@ void testTransitionOrdering() throws Exception { @Override public void execute(StepExecution stepExecution) throws JobInterruptedException, UnexpectedJobExecutionException { - stepExecution.setExitStatus(new ExitStatus("FAILED")); + stepExecution.setExitStatus(ExitStatus.FAILED); } }; @@ -94,10 +148,20 @@ public void execute(StepExecution stepExecution) .start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution)); Iterator stepExecutions = execution.getStepExecutions().iterator(); - StepExecution stepExecutionA = stepExecutions.next(); - assertEquals(stepExecutionA.getStepName(), "stepA"); - StepExecution stepExecutionC = stepExecutions.next(); - assertEquals(stepExecutionC.getStepName(), "stepC"); + assertEquals(stepExecutions.next().getStepName(), "stepA"); + assertEquals(stepExecutions.next().getStepName(), "stepC"); + assertFalse(stepExecutions.hasNext()); + } + + private static StepSupport createCompleteStep(String name) { + return new StepSupport(name) { + @Override + public void execute(StepExecution stepExecution) + throws JobInterruptedException, UnexpectedJobExecutionException { + stepExecution.upgradeStatus(BatchStatus.COMPLETED); + stepExecution.setExitStatus(ExitStatus.COMPLETED); + } + }; } } From f40dd9fec12de67feb710561d759af13e3dee2b9 Mon Sep 17 00:00:00 2001 From: Alexey Orlyansky Date: Sat, 28 Oct 2023 15:21:53 +0300 Subject: [PATCH 22/68] Add test for adding steps to a Flow via "next" Related to #4432 (cherry picked from commit 42dd1442dd5d85760e4cc578eeac7f74364c5178) --- .../batch/core/job/builder/FlowJobBuilderTests.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java index 3b1068d225..34c8663548 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java @@ -142,6 +142,15 @@ void testBuildSingleFlow() { assertEquals(2, execution.getStepExecutions().size()); } + @Test + void testBuildSingleFlowAddingStepsViaNext() { + Flow flow = new FlowBuilder("subflow").next(step1).next(step2).build(); + FlowJobBuilder builder = new JobBuilder("flow", jobRepository).start(flow).end().preventRestart(); + builder.build().execute(execution); + assertEquals(BatchStatus.COMPLETED, execution.getStatus()); + assertEquals(2, execution.getStepExecutions().size()); + } + @Test void testBuildOverTwoLines() { FlowJobBuilder builder = new JobBuilder("flow", jobRepository).start(step1).on("COMPLETED").to(step2).end(); From 4610bdac9415068db5c92417731de3045f1a19a4 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 15 Nov 2023 11:44:01 +0100 Subject: [PATCH 23/68] Clarify documentation about throttling deprecation Resolves #4389 (cherry picked from commit 6ba7c639a42a1b1ac1d8142f459c7fcf70965636) --- .../builder/AbstractTaskletStepBuilder.java | 6 ++--- .../src/main/asciidoc/scalability.adoc | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java index 8ab4fb2a14..495f65425e 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java @@ -199,9 +199,9 @@ public B taskExecutor(TaskExecutor taskExecutor) { * in the job repository for this step. * @param throttleLimit maximum number of concurrent tasklet executions allowed * @return this for fluent chaining - * @deprecated since 5.0, scheduled for removal in 6.0. Use a pooled - * {@link TaskExecutor} implementation with a limited capacity of its task queue - * instead. + * @deprecated with no replacement since 5.0, scheduled for removal in 6.0. Use a custom + * {@link RepeatOperations} implementation (based on a {@link TaskExecutor} with a bounded + * task queue) and set it on the step with {@link #stepOperations(RepeatOperations)}. */ @Deprecated(since = "5.0", forRemoval = true) public B throttleLimit(int throttleLimit) { diff --git a/spring-batch-docs/src/main/asciidoc/scalability.adoc b/spring-batch-docs/src/main/asciidoc/scalability.adoc index 4a387f8e5b..fc7dfa5886 100644 --- a/spring-batch-docs/src/main/asciidoc/scalability.adoc +++ b/spring-batch-docs/src/main/asciidoc/scalability.adoc @@ -121,6 +121,29 @@ Note also that there may be limits placed on concurrency by any pooled resources your step, such as a `DataSource`. Be sure to make the pool in those resources at least as large as the desired number of concurrent threads in the step. +[WARNING] +.Throttle limit deprecation +==== +As of v5.0, the throttle limit is deprecated with no replacement. If you want to replace the +current throttling mechanism in the default `TaskExecutorRepeatTemplate`, you need to provide +a custom `RepeatOperations` implementation (based on a `TaskExecutor` with a bounded task queue) +and set it on the step with `StepBuilder#stepOperations`: + +.Java Configuration +[source, java] +---- +@Bean +public Step sampleStep(RepeatOperations customRepeatOperations, JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new StepBuilder("sampleStep", jobRepository) + .chunk(10, transactionManager) + .reader(itemReader()) + .writer(itemWriter()) + .stepOperations(customRepeatOperations) + .build(); +} +---- +==== + There are some practical limitations of using multi-threaded `Step` implementations for some common batch use cases. Many participants in a `Step` (such as readers and writers) are stateful. If the state is not segregated by thread, those components are not From b0f49ce390c3bfe4012c53fbcc83128dad75ae5b Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 15 Nov 2023 11:54:33 +0100 Subject: [PATCH 24/68] Fix code formatting --- .../core/step/builder/AbstractTaskletStepBuilder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java index 495f65425e..6ff424896b 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java @@ -199,9 +199,10 @@ public B taskExecutor(TaskExecutor taskExecutor) { * in the job repository for this step. * @param throttleLimit maximum number of concurrent tasklet executions allowed * @return this for fluent chaining - * @deprecated with no replacement since 5.0, scheduled for removal in 6.0. Use a custom - * {@link RepeatOperations} implementation (based on a {@link TaskExecutor} with a bounded - * task queue) and set it on the step with {@link #stepOperations(RepeatOperations)}. + * @deprecated with no replacement since 5.0, scheduled for removal in 6.0. Use a + * custom {@link RepeatOperations} implementation (based on a {@link TaskExecutor} + * with a bounded task queue) and set it on the step with + * {@link #stepOperations(RepeatOperations)}. */ @Deprecated(since = "5.0", forRemoval = true) public B throttleLimit(int throttleLimit) { From f84b1553110105edd9acd8e2529f14e6daae14f8 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 15 Nov 2023 16:13:40 +0100 Subject: [PATCH 25/68] Update ER diagram Generated with MySQL Workbench using the "Reverse Engineer" feature. Resolves #4358 (cherry picked from commit c6497b690e8ec785f143049511812b23e21f1f17) --- .../main/asciidoc/images/meta-data-erd.png | Bin 108377 -> 219900 bytes 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 spring-batch-docs/src/main/asciidoc/images/meta-data-erd.png diff --git a/spring-batch-docs/src/main/asciidoc/images/meta-data-erd.png b/spring-batch-docs/src/main/asciidoc/images/meta-data-erd.png old mode 100755 new mode 100644 index ff099a67c463e054aedfeba52eb4a075106810e8..4c2a858131513120be4a397bbed4c6feb7f812ce GIT binary patch literal 219900 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

    +c?LxE^>i5gah~>K0oU8F!rsu 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 z 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

    0P_WfZXad8F>Athoqgh$YWg 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 z zq?{DI+;m~4=gK=D4W*|K6?x&1KVv+&5&F?EQQD$HW_XDS`sR~xCT7rae-FSX|Fdwj z|0^?Uc7nkEddHna6q~E%tQx`jaPm>ZfjFQ9fAmm4b2;WnG=Y3uqitzZMJ^zfF5Nw% z`ECoJeJ)u`)1T?mMB*lIXTfH=AvM&e6;JeZ0+KQt&$&$2uw}F_W>FRg)v#Kycc_^7 ze>46taBv8Naj-)Nw&5DM_v*9C9wkg17!NX7DOmN$P>>*jLB&0r1!b$4_$kra@M^v$ zMCV8H2i7>*tJQc9-gMx6uRo`#k*&1L;=p{ zjDxAZ&i~Jkr{RGgvUX8s|IhLH|NAAs26(b!z@7&Z+_m`kdjI#!-=8qu8_fUrH&u+F zCa0LEx+ExM&khKiXe=b%snRtQX7>suj|TQ6Oq#0c6Ern>?H4SXX)N{{>xt8g=xAl_ zccVvU6INZ{il}W<%?`;+MAPeRSG2Ta_@-`G>1b_JHKtq=#D{Ed5^A**p8dxg=p2NT z|K~x%z}F(f0_?BBk_hKOfzl7P2{|FI0bgltIm@<^;&UqLt`t`T5)Maa_v{zkT{thN zbMCa_wFZpx%u}__c1owpfIoC}XnuLS8nI?Oq8NXB#*t^y%%{9`%#2EYXhWOYo5qr zJT8#LYW6cbtGZetI5?QI_stLG5xlH3fqpyKmnFsMYlQUhP-DcBgi?YLpE`MDl8RBS0m;;Ir73>#V z**8)xrL!Q9@|895eFwR-S_bG44BE=C*GDHNAqc|(R4=cMe%`y39wXetB0bipctReJ25*5Noewc3juII!fEE8a&7DGd+ zRL6XEf5>TOGYoFNKFDLTo+KrKYnW~Wq~^8lmUE@4fQFs!62O2-tMr2#3pS4jc{mRj z4lxR2V9{wJn?(}s<(lgm?*c$w%eGjmofH|^+Xx__18RNd3vgZRutDb0geK*re>pEMI|C0*E~AS{uw|Ci*B&p`{L|1{sORVBLSd- zFgX879t8_r9oF0(hwhFSrXKICSAaAb5JO@b<52_D#@}uQSEAlLuYiSPoc8l3 zCc5o=>^`>M`YuH7KfHjL^zQy+xKaXKC_;xbjJg9+E&*hf2!OCOZFs&M0xU1rSd#glj+q+(cZXv0PG4B` zF^DnZOMogE=2keyOnMK%F(WaxoH9DuhPwZAi_c4-L<*g{~)K`h9 zosN6MQ5cO*>1A3KqO0!8w^L?st?m}zPuxKagf0NMy$Fm{6cGVzK*>qacwMd|9c%D> zfwH>xVykb-JGJK#C@*LM@o*N{BwYj^aB2Ncg770xhLs+Zbnm2Yt#&su4iK^r!n7ME zXnu`^;#D5k#(i zLa*bSgDKJR8=xH{Hp=&8?hH^ohO1x~9s%$qH2|=ya&GuJ{73f$z$=SZ1+)^$MIwt) zr&WR*FM%U~KwD8z;asK03LrBs18pXHWC^h|pvcE0@c`0L&ygeOidKNs5jqZTgUsS< z@CtSl`IDzPWy0feO&?k{>|iVa_z@^#32)yYB6>VdFxYPWf?8C{Pdq3HL9RuFt1<$rUV@?mHCZ&&R^6liLmq;FyAf};XC)H%A0 zJn=<1-MKmyEXCxnR&kQk51ADdO((%f%VNiZUj znw==WlgM&|pf2bHbv*972$WRX0NQ#orqyci$=Vr!afUUoM|o#&a$Z5{b{7HNDyu|ZAh0rxp)-N`Enx`q zexhMWu(I21!I-46zRI7X!TqWw_gl~Y}x2Qu6oB4^chXif|8dHqvKKeY3iQiWT^f|GQ z#X3FS3md-$NZVKY8KJQBMAohku4bAX0rN5^Hu3p$!1QFEXN$MDDA)p+Mg?ww5h^q4 zux)n))NoTCVC13ACK5;lyKFpU3)stIerd?YwIUzGPg?|9xJ$NPbJ%W^M(7LwX{Lh{ z9&l!0#;4B$UU=_O{uE@mT6w%SR4d79RYZ5HHb$nGz0gkZnpaK#xT!~t{3-FNky=$A zLuVt^_vHkjU{nINYf>Hj89Ee1rx3>`xNO<>`^KKuK3k#=N9664dR`iJ&LK#3{tgu+ z&U=~eb{Vt`^m3G-iF~gGSeg-pA-%g^`A|s-m!7r^KBNM?g@}O(MB?A6Za|lp0vV3S zn6xfWzc1VYNfngFxM}S>&ct@hJegP50XM+gJvcP~<_Hi0KBcjncT|1jpvD*O)F(2E z%m5g@Bb|&yzvo3kX%&L^%RdL@A$%NxQae2s4D30d6!d^aBAdXl`Dooe)yK0@LbAcx z445*|RHIe~^hI8*_qYRY6~p@buFvgQ(Gk!wjC$-)$AC9$t*f~U&^#Hw3b8yV?T%^j z)`6J-8;pd0X5!Zg>qFHzfQum1;_c+QsCGD6oVgXdB!MLA@|_1^T)_K4uC4$i$GP4B zT4Ynyt)Hia>Dw1n%mjexOY+PV1}K;hwXp+H59@zwtiQJ;$lc|)W7eVIW2IR%2!yz6 z)+xUyDKdJ$ModKcdO7}(xcyj@el0XIilOVOl%Be1Aa8ZjLFC*<)|JK74Wv0&t>4Lvx-xn77Wst%SoSZ;mdPYL1aHzKEX0`~&J10~bUCsow#|>6wJpyQl%jbKZsJ*^`|IYRY zFCbxj{kGHjw?8Si?VemK_+LUMO|SrU9< z*+}%;r;7BbZ+x&2>nECYEg&VrxJdZhE$eqd)J_U8hjT^tK~^JdT3>&YgaFAA;__BWtzq&f*+1PZ#rL~JAD!65pEzNY-yF-1y* z^js9`pOjM#B-+SDwmI(H3Nk_}Bh+F(?+X#z93+=vsY`B2x5DLElK_v?9E(r-gY`oJGgMd53v5)gkHYUN zXO!;x@%{oPb7Y`1YUli-G(52lnMQ)5yi;hB&(oM|H07%0LR{yB*7MLA&b}WvJ2oPb zcsyiQ&rzk*coujR@mHb0cWw1-rpC~62Kowp<2Z33Uh~c-)SG-hjJ#UC)VqFfG5>hi}MkMmGJH`7%;mb7EDz9dXplB>6~Y;u3cLq~vOU=!5s`9uP;7o;TUrzFFJHxx89o$B)v zTas6rSc<9K8T;TU!q0woDqk8|z;Q?M!Zm7bR|UgOQGOX`xeT5m=Bc=v1*s6XR`Is| z@$X>+9rZGlME;*P?p}Gj{d42|)~q3OG~*%RXoiVDw%u<_q8&z2)5l4HxlPKUW|gHJ zD#S(AF=KdsHRQ6#c|Mp&Sphaz`$~+7ld?|f7{l6IibL&DiWoa3&MB<}GFr;ht@QCz z!2P;YjgFdezf0v$p2-~QzoM=xBDZ^8rR_3ef+JK;+d3-5q*oj1Lb<;n##Z|ft@J)q z+(yz$ew^;W54fpmgd~hye@qn3y2y4&RBxSYh5g?@jhS-cuuO%tS4G0veeOqb3k ziM3k5O1=o~7A9Q~cg_xvH|$ByeWN6q~38Ti@GAPuAIzL8ZlT@i>oNK1NC6lbw^&-`Yl zrK7)!#B<}U^p)}JCfJqN`h3DmUI?@S|GcAR+NYLincLLHF>j&hcw)773h8okV0s;62iVq8dW|@ruW&&Xm%t?-mDT z6P{U>oASBi_*&7DZT}LPrY-PVWc$3x<=!FC(Z4sP+%C7>dUOSpO$n1%;@LoD5m1V| zU-B395&fUa#r|rgq{2j;&6gbz|J?}XY;PpkO}%>@p74PtO4E~6QjU;6U_UMv$%}Q{ z(jTvtuW>Q|zHedIgdf;TvQI4_tiIo_i*>A#iVwj3M7vvBt=nqj%e?XkRr7t{{EBMw zWi8se%GT@T57WkVz~BMI#&ymkE@IlD%iTZ+FUfnOVY1%B!%CBi@^4UP-Dsi0q;t@_ z-Na!etrHp1uB@z(dudqD`p>C_d;Ead;IvfRRtToiZ3fkuA|YIZ&V)1b2Iay)YGS;_ z?knu2;exVv3Jq`HW-HO&ifFts^2}VH?z(wU~D+?b8R$Q*Fz(fuk(4zk!@DoFvcZ=DuXr_x+CAp$WhW524nkoLqg{ zA4NDf^4q)sITxUn(Iy{$?&LnubpL}t0pSi8fD|2#XUE6==1TqNx1&YE0;=A(S4VPDo7vo%A z4q^NMdtXyIu;1X=t&ormMu;*wNjZ~nVwG;nXrLDeKsHS|b3b|AVBVna{=r$x*|3Jo0>C!v?`9F_L438eU(dv1!5*p1BjVc@@lJ?&% zd>1eVxrWJuV8-_dsJ>gd=3*RQ;iUCuiR!Y4q)EK;@ADVPUzUhW(l z8z}HXL- z&JBevV?RLc1(f2^hAQA`SVaT^ZKb%?(iR#BPUr%Ocf0+qg@GJ(s{Ot94ZG@7e zmIL4@<&}~SpObQOxctoyLA^4rT21$u#8rSpjI^ENo2+@53Mvz5fl$g>jruC{FG4** z0Uz~H0y3CTX~MKjDCl(tGMod2*SNu{mcY%gA3cEIt&8E)n+Ku4n4Duv)LSbMns@*u z%yt-m1_A`}HBafB*FlsGssdQf1A#BP#h8Z&{dWN3Frd10klJvRH-;JmCDYKPUHiVcM ztzwyPzYP|20Xl@s0;nhP>?{*gI+j-PhcW^~!5L7RAoT$2xAJNLuywfOUIoI9?T{Cj z!?aK?$N~$>G@JKJ_S@7 zFq#V3)*AzH*#h`HIf^sL6p)2jxjW&K?SkR{KyYdcz!B4>kR09uNVLCy`w;&{4+_M~ z8A!~{&F@JMzqw^1ix02?Ddkn0+^0;R208br0Z0)oItsKzh409yRRcs!L;hMbo9b6& zC%48EG?Z~`BSA&_#IZ=W+0iH+-5*q+hED(@(6~G;+vUE_=e+>-=%EzYlL$tuv^AEK zN~85D{r)&R%C}X4LBFqxWc7pcz&E)zBK$U|j*dLXv=xjq)1}W@HUR?rFL&M>6c?^7 z=katZJklRUNWtOs^N-XO?O^L)0Q_Q45HN*b7k(2-Bm ztw{crH}9t;{z6^h$qza{uq)!xqT^i2P~&<;z(d%fhm2W_D9@?GjmA7jfH`^=hsX8;Z+ zxV)ddiL2W)U)c|SNknw6N?Q$eoxAh)K$*QREB`_OVi>OK9F~#r6X2O?E^%4sQi4M^ zL2)oUwG7{|p=*&=@+mxG5L)QsywJ1SEH7q7KNk!^53Ob)K|NVY)AEmeoXZCdg0>iZ zzsB%83;9?+k6I5{l9PV#ldLV;a8#Bs0|Mhp9nTG*4ffl#7rQ~m)lE&+8rXRtCzFp? z`E`z(dQw~AI=VSor`t4#w$HHTTb*AA=Dd+lVPdR^pLJm?l^cgmoDUU5df=9Um+Y-g z+**DaWkmm)@=BvqbQH~ih97`-h1KXniLZDx&xFIdRQ&)5BP?{T_v{p}yvr?@cgeml zuOjeW6aGE|WJ^%(lt9YN@M6?$*f~%>M)&D$8%_>cEsQ@7QLleya}87;F6OHEOVeUoF)80Z8!u5D? za8)ta$?A9SknKw2*t^v=tN-IG%Ca_ZZ3h&8Jp6wqL|m zj>eko0<~8u_MurzGSbB(P*+FN;I6?gLJ`=5e5T_k6q(^a{2E;2S?Hj&&Oe*UDToAo zis;gH=$O!&S|jX+tgKd}hy26pY|$GYjfz$0bkwq);iP-Vvk6>eP%U(Ei7<-O1EE5P zl>Jo5jd*+k`#e3@HqeQ0X%?!B6C{hPd$6jj#wf7`gdUlzLYQTnR8j(T?k;0!?ZcmZ z73SHY6Gg^&jNj&jO(6I!GSBWO`>EW7eS1)*!xE!-hTEkp**|e2RDV1>brX&DoJ4Ee zX+L>aka(fld9xAVo^fAFZlnbJ{+en#46!KJM2o**XkMs{IxxvnM}s_tBN%;BuPox7A3Y&BY=HOgf|gPw(- zPxTVbh2fcUDY+sa(#5lJ2olnestR`Gha1^>FcNi-UgUnS;$iomGQGa`R#4Sn{5Egk z+y^Zho%{E-sQjrnSKLjha(ifdQMA~BFdEtRXsN?vL`S&472t<4CO(cD>|od$i>dbA zUL3R1S8*w4n42eJt&K-(Qf^sR2h$sTt>)vDo8xs(A-!M5z@fK7Dew^lhM-<*kgaV9 zkLKw=-juX7@PlNezxG3GF2I(qab#GN02jIDv4u`-VV7E^%h^igm@j)u|Dk@R=UyJ! zCm5)kcwc?*G3pNDjD9=99v$}9_R~1>!uJGQ&P@NPyX&o`@f@zC2|O>t)b4T>+*7$Y zN<~SWo?DQ`)rAs)%hJ?_$fI<=aUSy={IVeE{G9%EoW(vqpsQ+ARbW7qj$$l1zt_)~ z8rVL!e+2jj^PpZ(1YNo_iH@~?(rB1Z8;iqeh$Nc|>8pt1*)=l$=mDUgE35=S<+Y7- zG?`6uT3W)FAEjbk_4y(!%K7_u2UBfTvGYEj2ZDQ{EU;#+WkIZIv*{H&#)*jvM{X#? zL3f{FNc5ol3*PJ7a9xpAq~#8kB3kWz1V-;0gVC9`AqJHikbN+pR>Y?5;g3K5ONIGy z5pqE4pHfm5J4otqI*Ivvw%vV6-ka=FJm`&U)}yqXiht8w zpKaCOYeV(<*b|p>FDjFvAyH}A(Y(MHPG^AN5T_KRm{k4_q21h~t8_fH33;6QdLPrHgxNg8>YhY} zi?p8&M2P|N9U>tvqplEQie8?Yc2TbDEMEU^#=4)7BqFUXNP|J ztq83(UCfN#n!R3SIBguvj6e~6%M!cY7R7(|aFc8uWTd1U(AG4YO_uG%!5n39-BEPVz+OFXN}VK(mI|LuaO zN95-U+VMWD#A-H&8Rz?nNBW)nK05fny+u9CPS1WVO-}0TW8zS%b>HczuQ59K4J}8|?|HFl+D3&1uRImP41_*N?AZpR%t7JjpLUiv8KwWXev3gL`+fnd~6( zfw{8s>!w#|k_O}4Z7}>h{?>4PP70H@=8Qq6n7#IDb{sd3m4Uo=Yqdd*%EpPz_^*Tr3MM@$T{VEA_TY%H@8nyujK7MUFqWyp z>$_F$Iyyy_}| zn6kBO`5GZ!-&a$swfNT9)clI+3i+O;=32hBS_9ne)cmvxg9UERKl^gPIj}DWo!iMd zAq)DEWhB|rCPf5D&$jdGnx$n>+NIW9HDC8F(cSf*DiLWJ_8Oepb_{$iW1>)2-dO`WWl&2;3PQam)z#5q@`?WIqO zeE&C8qmBU}Ds_zOGSoqC@+6m#WQy$;WmTQ%5?pP5b#0w>on_^Bi{0Ul{Dm>Uf$EYR z&p>=nCGX+XnpOIi^Vq8Y$n(G+-qfOE*)y*(J>U7i%dnA%Q?SxZ^s#{!rYk}Q@c7DU zDsaacC*?*3gVnp)U0=k6HSW_=Rf}HZ2M7_jO!KH=|)@`t=^ewbx_b!pZTP_n<-ZXGOBLa5nFONVI zFA<#`24fC_ftf2>28BB<>VLm9WN3a?`6}kf1U0d1n?<-~9QZ20Yd>w};I)V2FY6m4 z`F%mgEWP=znj(h-Wl}(KT0L$)m;(F0`Ck29Qt_QZ_aeI3-)HeIfo3}G?zGK7>#B$g zUAGkN-+Wcuhbe;xhvRe$TW#CW`q4aEQdBPdMt7m8t6+;&B5SV!c{pZTEt9(DI`9445)r z39%n4AYTC@czJ4ZZ>HQx=Saov-ActrEAvHy1aBZ)x4bK4%)v2lYd=y)80g{s40>|_5-)zl zB>{REx$%oWl=K7hh@5KD~9vm}AkzHwU| zyAxU2!}TeZLIJfB&!x{>-wLwQOguJbnihp~8=%t`h1XsRWq{0Zy^)d8UnRqUpb(Wj zm_jPWMNYCGO%!Z=l({iSr8H0rD9aKy&16s&!nIG#wFIB3e-;RMsK;Oy-w=;UJQ=vx z>WGPnMg^*#4h+9;(akrjVKV5z=v+X1R!fs|{7Wstf5k_M3#%m03af&yV>Rl39pswA!ic-FG2)V_>wT-nr8^rp7uH0Z!#Em|Ed|-HQq536VAxO=GX6b zCJ8Jm@MNSP*Kf{g3kMPXbr1WE;-cI}(ODRZ@FF^AV`Gpum!&-WuLoFY{qn&;z zWuKD-Hf>!(Epq;uPZ^Y@qdW0b_t#?$ItNt$ z+8|PyH_bjkO0<{$iZPUFM`BfJ5<-rAo9DC?7FHEnx7#^XJCWH!uA7XBniSY};M#RS z$5qINb^-srU6bs`;fz~c11CLp|AlJQ>EQUJZ5h@-sk@6{br*f5dw4QC=G7j3Musz#o9TUT|oX7{TQ zOrAud77<16lw431{ zX33Ahxs@kmIq`ep?@^4KL@M;iXA02i@@t!Cxjtc4oSy;4$eK*JvWiB3?+a=8H7))! zfMEuxKU(4xMIHu5QM2-~^|i+HA5m`+=>PPGAKB>#FX%SU4$m<_8!6g>@-i`-jB7?F zw9UA>zZYsV$S;J$C)?3zci)nie|MRd<{#9t zJqNi%MQ-J1mx6VVvQ=Kg1iBq+|5`m6*2|!4*<(KZqxhgohVZ}+1V~@e#am#VDlKpl zcJd2}1vuH`DG`t`P~>{FlzBE>jMG7>4cg_b$$^EoCa=583f{cq2uaEwK4@wq0)p9K z>uEL@ixCe8tM-RE2$g=kYvjm;P9e&W6HnNxjV{Z4oGF!rb}1M!W!_Jve`poHv0$;+ zW*#v6fSEt9LPU$CQfux{!8_ovB}y2H4H-wFVQEYMCA zX{-fx7Zx#Nb2nqF%ILJch7E-@dE_TCgGHst=M9uY{hZ-DLbDs^7uUJr+_Yp{9H0fh zzbMIwpiZU=(Px*_0eRbm=Mj3lmhj!{JTN}Jva$y9Zb9*2i3URK|?oCemnEXutM zQz{D-htoS9x_ocBwFIUuVUvo4jE&8fj&lQRuHu|TGQp|L%CX&`brZY6fblQeLm0N$ z)x)bUc^o6DR!#$o!x-VLy)~aai7Dwizh6ndQzceymu@{YPyK@FO*YE3GGGx%{eD$% zQSO$=o9%$gpA~xEQ-|A?7Ik&jgJrAogrZy$M-#U+DW~!7dqydj|}B6SAaRS$g3_AZ&o*$r$-Sr6`sq!ziDFZwq4 z$u;;@Sqqeith>Pb#0F%$7`4kIz48pE6>l=MmXc(*1M3P#5$@*NgNcc=fhK1U-3GZ$ z7Irevebf2XOR7(21g@GqyEMX-2nMb+hC92pbTjeW0M1J{FzW82Wp4V1k2Y2({efo( zLyTu1FoZm)cjO^INh!1^+9C$-HrWYWD0Z4RJdTmAMMS@|kF#alk5yiDGy7y+fR!?r z&@(@m(q5_hUQ+q!(~Bc@ehm(AfqjT*8<4Tf>PsUwy0zV3A9Em4NGBn`$(y-7hOFnS7|E!~xyruV~7n9>qVgHDm zmFbDE&^QvV93m3*wP3vjcC;)FK9hDK`>{mV+w}Eg>_T#?M*IAg*t}v#3bUIfF+!q+ z{PyRAPPpv#W|Yg#ny0&T@|qs!8I|5mscq)A^$LXlRY zag+W!VW+59`(9BZd!qOeZBUmELm4SqyBztGCU}r#uzA#Y} z>3ZGeQ1RvuASo>!(o)imAkr}D4n;u)5drBEDe0JWsz`TBqe!=O z?=gMWv)0=0yWZpYzJ2U{`-kAfIq&<5G0t(0-^FVs1u1+yGCTx9@MWaMl@a8OFoK*; z$2krELg!@s7XCVG^gv1+Il=t-P@NuzAk>JAxTvaY+|rnfF7e?0-8EC^NbHiN&pmEZpw_RrGw4bvyNnMf~TokBj-cw-?)v$Zf7oH)bzsM$Dzr6I+om7_QN zL0u2TIxefJN7l^gWA5xZ+?giURTh`nyMuRfInE*UWYPh9k+gTZx<1?xz2D7%A6LV8 zavb<`=EJ4x$Fb8vf&M3IO+>HwoCqFh7D|3^5Y^dT{bncOVk7>oCO+R7AMxB@`PAc4 z?rs+x2hNM+@w<7}a?`g9k~}L* z5swYbNN*%R4exYC@^Um_{#!=7#^2qeJheju5Vuh!5r)YuX zq6=;?JKvdhyuHHiYJTjO%zM9u<)(eUVU;*JAN=xo-7Q+rsvTZo*#Ehpm-g@$F7h64 zkAPgmluG#9l9R1nVxd)zkF=|`-)7zGGuhTw!b2`%#;j+bI&Cxzs!9)1+(S7=NgkLy zvEDG2FIs3dw4ha_+8^)R3GKe2DcxS!AT@^>_k^}5C@WG?LaS;q-!$@HF`;A^>7nyM34m7tg?xdNN`M3?MVA@8PE9^22KWMBauCq$P_P3<*L z9Jef~aWi`FIjejV8WH-0lZphEJq?5*erV@G;hO+Izg5+nVl!{j}?oVWeXEM0v~@Z;`=CnJYqH;jjUNhpPSX z{o47cnDF2L^jiuT73p!0H}ysY@tmfMQVy~!)6L`yI$Yl7-Ci+izPHZ8TE{}Nv#lvd zYZy@Pu32m3D4%}%eeA&qzJHkGnpO5|B6`?F;79Z$PO1w27OxALj~5{L&XpH#>YdjnmI)=6%1L@p7W0vdAv8<1SGHI(BPpCgHbwwAA7pPOqmLi_AFKmO9rC|Z3E%TK~z z5}!l(%#(WT4Dw@vI#X*)ev=OSx>GU1j~HI*94I_*kdHjvMwVMvLQ_Y8mBTVb2EL$I}&Tf&jeHlVmqopb>XK&*^7|7>s@X*w`fsGIl zF-DLrWNxsWlv4)YY-ZfY%Bbw1V!KJKR1eQp6{V+@$}l@STi>6CqX91yA5=H zE{uiLn+&R{-Ho+++yBWWV(Hj;y_%fYlh*z2J&6p*5P43Td3&N;?DiQYGKa-+ckvo7ez#l5`|(yi9@OE^ z9mc_9TQbC6fdU&TmUY^n^l=rd{QXj*JhIbep2D2-Rs8d-2<3QZZv;JweRyH?M|uPY zFR-uL^2^~Xv2zy*DDEBFbyttZZI}k9=(ou&Qtdc5iX7>%6dm6GdQxD+vk~1@ZejAI zzSzaS_@_NT_RhtXD>-@ugPGLkm9>wAu8$t?^|WUUGp74*$+shc^{0{LdBvDC`hcId z*=>ra>&A!hktm0cZ$dpv?}R$q+Vw_kz9Ng*n;H~G8JN<(&8S(Ia8}I1%^B!O@x$?5 zTVlI=BF?ZOP2o!|P$5;qa2lgT-UxgNhp>gkg=-O-V%}vYBH`6Q!?xZLE_VT15Z=K zO3CNC{60UoQ_*?{7m9vr8}K?T?X(rG-AI=2=ixe&csL=$f6gwv=zW^GFLh=sNICE9sn5w%2D5QEzE}BO_97po74lwx7GK?c&t!kQC}uay zp3$_&-cyQ)pJ1Y*#}hG|8hX7tH}LZYMu9nWEiB0=)Ake7tCEE)XBb`%m@$FB2R@PD zmB{AM^pkPPgqh^U2{Dy9%w=tH%7>4)=H%tz;Vicrp{WGRbkub(5fAvZjS@sz7%;_n z9v$KaY1bG0Bs*)jZAEqcvcqzmar>JeUgKmQ(`^Nf5hmPuYT1|JQMS_J6O1)c*(2X5O2+q%i z^0xc@Ck8vOu5vfFm>uPMosEe(g{o!YDOB*{cCiX>N=hd`q^UAL?j1Z%b!7 zt9)-b#x3NjqlSp97AY7&#!)|n7DP6^EJw?eg^zzPr#(bZ@MzasCO(riMG#unqrtbq zv%+Ow#WW|Rf$b}TuBvS>v`C$qoEuI{JU;TK5BHW!PDGVPt zb3ZPYICI9N*#DzUOlq1)@(nId(H<xzTT~M#TC~vR@9#FXuK{DB~HYU^DvWutg>9!Tg|`y>TqL^y2SH` zN@rGE>26U}%qg9ku9737w@vfy zgkkmE#lLDU_0RvUbV~7aLahY3Bq|DHimMmzZi52V$kmlmP~cWMbps2@(#UI|^T%jY zo3)lZ|E1h&4l_o{OSHyNw%z8k=U6p&-Cet3zOA>#8l0J#Sy)(@P9jemHa$CAOY=Cg z+1Ss|Pw}>@mshp2dH4CQ%&e?-&&QbinnPJQZ4bPsYQBxm{>~H53lzdr1)FTsQZFPBEbfjb^-a$8dp3Gyl=%Tz4A784*K6!`1QXy1KfT7p}2C`uucr z(-Haf=~I`7IbUKYD+2>NA6|i`=WGW>T8t_~(5qKC7cR(2OWQg-E6B=zq-S7d4W@oY z!S8IA%*)Fwld7Ej+~{L?M1%$1m-_nKH*O^5<|>p97h4YAyZ$ydHa06O>-qEho}Qj6 zDq%KQCd6=S1Q#y62@G_wx7RMUiMPR4sb=SsO#9jv%@O^c^VY3fEG#x{QEV>>sM6^1 zkU}(?PCkayX0&X=`v4zd=iqQz9)9BZ6lUs@JDypudX9Fg#>aOneSK{Y1<5|SAF{Y5 zt2D3H!QkEr=uxMZDO5>UsIRZ*lz))g<9)PmJyhs76doJ9I5+nxM@vJa@rUi^PY!cD znNUvotp0`WWT}&l#1qb8p5&LkoPs{bhhLtb>*e%1K6HbU`uA^pm2fVypxWA#D+Zol ztn@1!o7>xSGBPr%s&rA>t^)dohDqHI@A2`?Oi!~VRyr+~*iXxvaHlAnD=Bp~1d%&9 zIQWSrmC$j@2iE^=45lKdASTL5NqNyY#ddpZYs+D_1BSaR$9Zc(jf#qD#^L_`=aG?v z<4~6D6A=-i9p{xzXafTRhKtN^g-92XwC%{E-f+rO@j05c$8d4VUm+#sDYpYO`30d3TR(SAWYGbd$NxMJm{rmT&6W-*Q1=INET3A%n_ez&l zTq4@*{LW0w%sG~Wx!v8}Ui+J`0|HuFT7KHzgKrPEmpy#fF)8VjM2<&iMsY8()(Usc zQ(7`|vRHB(b;ZT*A3iMXe0+Qz(HwNt)YJ?NnLa1SQ;oqpYioB&f@qrEHfGFuCfsJ@ z-%{|O7IAmy6TPIIvDwO6t6OH9H2w1Bix+FIRe~Pd;^N|RQFjeT%j`@TW~ZmI&z)P; zrwIxQ!hRYMfOp>X{$Ro5M)$3SRC4RSPY)kNFom>EBk$tkt`ieG&a_20H8l-Lk_Og4 zd-lv_WfT_|x0^H~GO{y_GwXb^E(m`hik5>mz0zYuw3b_ zpSEXa>QmF#&sCy#d_aunC!1>Yn^#9?1fGbNmR7&kd(88Ca@3Y}#ci=9+ny8|L`h98 z{QdjQehmX=&3uu{((-aG{vr<3j?oIItg^Bw>Q`ZOiVJ58@-<-VZ*Ol~aqH;V!+PDB z@bMYQ)_VBxq43dW7`KNdY!!#Gq0Y{{4<9CRB?B-;4QVl-$CQ1!$SK_G*LVuDN=udK z`viYDu8fw4hK9a)@nQ&V+L<8e0c+>ZojYlTJigSla#0_2ZiY1@lZ$z^1FbmB0@o4Q z2M?~W>U%EqW$cW5u-?A?WT@~-8pFZf9_+x3ev6swB*>fVy!Jo7`kgsXV}ZW@TKwnK)MHD_R;!B?e2(z(i-UP6J6(5Ty!!gU zEBEi;cRKGTF#bXGc~qw^3k1mGilNxVL<4p82(hI6;$p9pqn%Tax<5+rpvE~b*vRBD zFfiPUtF2KKI#@!twYA-ndW(gHg@{N?OM80@p|c=yJ&0sM9$8ykyJix=G7wXg$Xexn zV$VgIV>Tj5O^oN{lgFW+t@#jc)YHby>~8kjQWvM-nm8a6h$ z87(0pA>-rYBc&))ZVnEPjg1WmN(eO#&98&iTGN)Dm9Z?BXZ@cb2%N|Am5=3Si-om2 zQeu5D`JBLU(dv7?VQU04Y?X*$=_IA9gOy5%XZ`#;X=++pZjjJy#wzAXCB?;ecX!QR zI>WnB`5bnu5;1SLG&a7}>OY4-m{ol6fZy#mO<2V#5g5DMgt#)H?9rI0AQeoBC@Cp@ zPOeVaQ+Vu?$cv!yv{%0*M7g4oG1FDyTBySPEE{cT=dhX)& z{3-(fmyHb#>Z+=qhwF{VrK?xVjGIFJQ&xz0G=ucP#l_|A?Ok!c{(@ldWpj`Vg__v| z7r%5xFzfuXhp^r%uSUS1?y3X%^;_+}z!T!tXiEv|SVO z-2EsKDCbpQY&wNZZqE0zv9X~PFs=@cps8YL_0XS7a4R>8&3d?Kc4*XL%_69&rDY)& zRr8P`oO#^iJOW!(@$j86YzUmg0l$%+6kNE7|=RMK(X7VPKG_%8;mDw6I{o z!D@=>4k!gC(0F8JHu+5^k{^XJbmUSOG;&O!(e_=tQcFOR0i0nrJUl$4Z@&q-eGF&Xl;u1@0S z<-|_Y0?nHt(lmt3dKG6o<17X>o*-_A+acfIry;yUjAw$* z%nWFq&ebgN9pdD=ktS(j(xF3g9Wm*MYfdS@cI}#-ogD-lUeDdT8&9+gjho9(DqL16 z5o1$R#TZU=NVBy^+vE;q`Z6XaGr4+|Z@imf%5E569xhVLQoly3-rw)#v%Tb2?0%G2 zJI=_U%n)ATArrdPm!V>3$0pyaoKa*@>#b8_b%&n*(rfXGeyr1?hK4ufd&erAbjs~- zOFWc2`tadH5IIi|XFCm>eR*7l&(e1`Uup{ri>UU|QC%214#7b)&g0`_1J8AAwA*~o zZ62P|v@}{3=9!rpJU_9&_&blhMHQ82 zP&=L`Pri)hz5C;3Z<>7X%2<)P%0!LVNU>$3V}IX^D6))b-co^k^1UxFQfQ-1@a21< z&`?lNfFRo1(XqX=)7jMY!Mp$Qu_E~7Dd6sibSb@dqY z?!VMuTE{P~pBtURK5LU-Kuwyo#}qp)s?*WYZERIKFE7l`yZ!uzYqIhA*%_5Ix$YIv z6)0I*yukVj+aJC^3WjmnxRf{Kb*^4Vl$Djoy$`IBrj8Cu4ih;eBO@qy=;WeoVFk9d z$hx@f+_>+5fl|P=>D>)yXJ>PBbG=IEpto;VdeaqERpFK*3~^u9y?*<4ycCtVM~P90 zP4CsKW{b3GTg&X~@(hG|MQ(`*#xj$!|7vY(lR%coMx%Bj`TwI(gb@8qmxYSgK82gu zp>Xzl!Q*Q8EhEA^4WAw+M=)vKjBM3nB1NtXxV~$hW(aSA`d?B?s?>6@<7+OI5g4f` z`4*!TLDxrHTt-5}!k+v3cEs@#!LSMm$%KMP=(VZY=-|I`At)^^?b9dvw8QP?5vVsHjSd^*)NSufyfFoqXCI z5)-qbj-77K2MZR~3~~ud5h^MIggts`^2>8_9vdcldU__N&GmJ|v!QWuafyi&A1K4v;JF?bb)4@st!!@;oe5?pDQdhl!owiRu*Gqt6u)2XWZ|_Z=QMz1(>z$7bSXP zhH%-~K+xFF>VAAu%>*?hB`&Txt_FD;wpgA02J`UnFen2qHn#Qst;Lxsv?kNo1x5aC zSf9^Cl(e;F9}jo~rxNr9ir=wAR4CKtmgZ$MZ3W#Y)_=miAS zDadQYcD5s)MX$nYv@B%EDg;EKvT~?)j!Ev1)1R9{Ze3x~HA|B)ahU5$^4MO|s`akk z+r<)vQbjZ`zo^I&<|bVs-hH)t2X+*s>H#BRK>-1HR_CAJUc;EBq@}U@(a5Zfl(N#& znn1!qKF@A&u(O{fptN#?K`Vl7B{^HA_J#2;!Fm6`2+l~jGspSU$lJGXVR5!LHR0gm zHg|TKGH9r)vwPq_$j-^x^Yji3gLXB}jb!bDm39T{SNJ$(?uV{^lD#6K^3&75UK2g9 zH-c=Hr1UAL#Hc<1lH#Ajc_q(B5cU!&4i<nZOYr$fU;c7K|;^A=sV1V{_HI~TO zn3xK98B=(GZmr%KA3>WEY(xc<>NwijX_ecjj$^9}k_Abo+=3+lpF~1J0ur1J!8&`E zMXS&lDj>P>$Kw$7^7JaX-F_QeH^WB~5fT=~LLDvazG()2*!Z(HOd89W(Iy#%TA{Nu z*sY@pbhOPx&GOO`6O_J2>%Q3M)8u2-_4Fu6Ncy4nqzvYXFr# zxvVBsR`LfoqEm?eDOdgNm<(MbS_cOs%R`$4p0>BPF3y+i60&pk)S5$4VqfkF$~BDv zGR7sWB)z?J$n^BIy1F_PoN2Nj|43LT0=NEaM>3+Axe8Iw_IPYtKDupVv-*3ly}kYP zGZ7lXYw}M$y}X!%=YL|Zp5X+uza=flP;7?P3<^HbeZh_VF+_au&I}-RIw%(0s5_T@ zkDovG4zJg~qnupZ;`<6rnbxV5h2}vf?aNvFQ4{99Y1MNqRVCTk*)@AJ?y}5HrMY5yh@(`zmSuO`|X7{a7htb+gGA! z^OgXM0ea(5B09ae_`0v|aPu%~Nv2NIn?LGa(#QxUPqKgafW3WvlJ5qwmw#ZEcXYU%$S#V z;^OYEr5CTA!#xVs&M~Z_%eN$5{B^$1u86%~9c zQ_M_EOQ2j_U3cHzxPSJ-)prRA9q+-M{BK%3ijoiuY@v(RSfGG1RLLkQSqNY6dJ4g2 zaKGoVZI#U706~MFpMR!570G|}#TQCwa>^Pg7B{{A??}$GW#Upg< zg+514>v#(LP}1U{>Gmq>eEwZNcWaXw)u(UyaCPP7<<-k0``^5E z3(S-!?9uw$B`Μ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

    eS}hBXDkft6?2F%C=ca-gfuW+qVTS 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 YiC_F!L``@aOZh1Z$5oD{lZ}1;5Be*D4gdfE From 356c47c45d1ee07e227f872c968dcb9b1f98eb0d Mon Sep 17 00:00:00 2001 From: hwan33 Date: Tue, 7 Nov 2023 12:08:55 +0100 Subject: [PATCH 26/68] Update documentation about serializable keys in the execution context Resolves #4457 (cherry picked from commit dcd1ac8b521e5028088c092c2344cf968961eaec) --- spring-batch-docs/src/main/asciidoc/domain.adoc | 6 ++++++ .../org/springframework/batch/item/ExecutionContext.java | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/spring-batch-docs/src/main/asciidoc/domain.adoc b/spring-batch-docs/src/main/asciidoc/domain.adoc index c544b10539..10f78d4284 100644 --- a/spring-batch-docs/src/main/asciidoc/domain.adoc +++ b/spring-batch-docs/src/main/asciidoc/domain.adoc @@ -557,6 +557,12 @@ As noted in the comment, `ecStep` does not equal `ecJob`. They are two different `ExecutionContexts`. The one scoped to the `Step` is saved at every commit point in the `Step`, whereas the one scoped to the Job is saved in between every `Step` execution. +NOTE: In the `ExecutionContext`, all non-transient entries must be `Serializable`. +Proper serialization of the execution context underpins the restart capability of steps and jobs. +Should you use keys or values that are not natively serializable, you are required to +employ a tailored serialization approach. Failing to serialize the execution context +may jeopardize the state persistence process, making failed jobs impossible to recover properly. + === JobRepository `JobRepository` is the persistence mechanism for all of the stereotypes mentioned earlier. diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ExecutionContext.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ExecutionContext.java index 49f0d348fb..393e31da42 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ExecutionContext.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ExecutionContext.java @@ -29,8 +29,9 @@ * that allows optionally for type safety on reads. It also allows for dirty checking by * setting a 'dirty' flag whenever any put is called. *

    - * Note that putting null value is equivalent to removing the entry for the - * given key. + * Non-transient entries should be serializable, otherwise a custom serializer should be + * used. Note that putting null value is equivalent to removing the entry for + * the given key. * * @author Lucas Ward * @author Douglas Kaminsky From 8ad6d806a54565b8afa5a403ea4e9b13d5fa3db0 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Mon, 20 Nov 2023 11:53:49 +0100 Subject: [PATCH 27/68] Fix JavaDoc in JobBuilder Issue #4415 --- .../springframework/batch/core/job/builder/JobBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java index 67fb991f53..d00372346a 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java @@ -62,7 +62,7 @@ public SimpleJobBuilder start(Step step) { /** * Create a new job builder that will execute a flow. * @param flow a flow to execute - * @return a {@link SimpleJobBuilder} + * @return a {@link JobFlowBuilder} */ public JobFlowBuilder start(Flow flow) { return new FlowJobBuilder(this).start(flow); @@ -71,7 +71,7 @@ public JobFlowBuilder start(Flow flow) { /** * Create a new job builder that will execute a step or sequence of steps. * @param step a step to execute - * @return a {@link SimpleJobBuilder} + * @return a {@link JobFlowBuilder} */ public JobFlowBuilder flow(Step step) { return new FlowJobBuilder(this).start(step); From 6e0db8a34dab36f1316cd0430acfe5ca6119c2c8 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Mon, 20 Nov 2023 15:10:30 +0100 Subject: [PATCH 28/68] Fix NPE in RepeatTemplate Resolves #1123 (cherry picked from commit 03d28330c2746753ca0500f9e46cc1222fef3e4b) --- .../batch/repeat/support/RepeatTemplate.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) 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 4e81315d14..7b7af3fc68 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 @@ -286,8 +286,15 @@ private void doHandle(Throwable throwable, RepeatContext context, Collection Date: Tue, 21 Nov 2023 09:14:18 +0100 Subject: [PATCH 29/68] Fix disposable bean lifecycle in JobScope test utilities Before this commit, the destroy method of a job-scoped bean was not called after a test method. This commit changes the listener to respect the DisposableBean contract for job-scoped beans (and make it consistent with the calls to the JobSynchronizationManager in AbstractJob, ie calling register/release). FTR, I did not find a clean way to test this with an assertion (which should be made after the test method), but a log message in the destroy method shows that the method is now called as expected. Resolves #1288 (cherry picked from commit ad50599d280b903f152ea1460eab0f1a25eac0b7) --- .../batch/test/JobScopeTestExecutionListener.java | 2 +- .../org/springframework/batch/test/JobScopeTestUtils.java | 5 +++-- .../test/JobScopeTestExecutionListenerIntegrationTests.java | 5 ++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestExecutionListener.java b/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestExecutionListener.java index 6fca833885..89bf1730f9 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestExecutionListener.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestExecutionListener.java @@ -103,7 +103,7 @@ public void beforeTestMethod(org.springframework.test.context.TestContext testCo @Override public void afterTestMethod(TestContext testContext) throws Exception { if (testContext.hasAttribute(JOB_EXECUTION)) { - JobSynchronizationManager.close(); + JobSynchronizationManager.release(); } } diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestUtils.java b/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestUtils.java index 00e9871fe5..989512bb46 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestUtils.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/JobScopeTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010 the original author or authors. + * Copyright 2006-2023 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. @@ -28,6 +28,7 @@ * * @author Dave Syer * @author Jimmy Praet + * @author Mahmoud Ben Hassine */ public class JobScopeTestUtils { @@ -37,7 +38,7 @@ public static T doInJobScope(JobExecution jobExecution, Callable callable return callable.call(); } finally { - JobSynchronizationManager.close(); + JobSynchronizationManager.release(); } } diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/JobScopeTestExecutionListenerIntegrationTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/JobScopeTestExecutionListenerIntegrationTests.java index 707732bba7..d295007f00 100644 --- a/spring-batch-test/src/test/java/org/springframework/batch/test/JobScopeTestExecutionListenerIntegrationTests.java +++ b/spring-batch-test/src/test/java/org/springframework/batch/test/JobScopeTestExecutionListenerIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2022 the original author or authors. + * Copyright 2013-2023 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,6 +17,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import org.junit.jupiter.api.Test; import org.springframework.batch.core.JobExecution; @@ -56,6 +57,8 @@ JobExecution getJobExecution() { void testJob() throws Exception { stream.open(new ExecutionContext()); assertEquals("foo", reader.read()); + assertEquals("bar", reader.read()); + assertNull(reader.read()); } } From b8603b28c5bcb201beec3b7a8d8b0eae7b97cacf Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Tue, 21 Nov 2023 10:20:00 +0100 Subject: [PATCH 30/68] Fix Javadoc in DefaultFieldSet and DefaultFieldSetFactory Resolves #4494 (cherry picked from commit a1b1ede35b08fea776bc620355f36d91aa7ab40f) --- .../batch/item/file/transform/DefaultFieldSet.java | 14 +++++++------- .../file/transform/DefaultFieldSetFactory.java | 11 ++++++----- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSet.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSet.java index c0e833831c..4ec95e4d53 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSet.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSet.java @@ -33,9 +33,9 @@ import org.springframework.util.StringUtils; /** - * Default implementation of {@link FieldSet} using Java using Java primitive and standard - * types and utilities. Strings are trimmed before parsing by default, and so are plain - * String values. + * Default implementation of {@link FieldSet} using Java primitive and standard types and + * utilities. Strings are trimmed before parsing by default, and so are plain String + * values. * * @author Rob Harrop * @author Dave Syer @@ -65,8 +65,8 @@ public class DefaultFieldSet implements FieldSet { private List names; /** - * The {@link NumberFormat} to use for parsing numbers. If unset the US locale will be - * used ('.' as decimal place). + * The {@link NumberFormat} to use for parsing numbers. If unset the {@link Locale#US} + * will be used ('.' as decimal place). * @param numberFormat the {@link NumberFormat} to use for number parsing */ public final void setNumberFormat(NumberFormat numberFormat) { @@ -78,8 +78,8 @@ public final void setNumberFormat(NumberFormat numberFormat) { } /** - * The {@link DateFormat} to use for parsing numbers. If unset the default pattern is - * ISO standard yyyy/MM/dd. + * The {@link DateFormat} to use for parsing dates. If unset the default pattern is + * ISO standard yyyy-MM-dd. * @param dateFormat the {@link DateFormat} to use for date parsing */ public void setDateFormat(DateFormat dateFormat) { diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSetFactory.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSetFactory.java index 7ef0fca1bb..a958f50a1f 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSetFactory.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSetFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2009-2012 the original author or authors. + * Copyright 2009-2023 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. @@ -23,6 +23,7 @@ * {@link FieldSet} required. Returns a {@link DefaultFieldSet} from both factory methods. * * @author Dave Syer + * @author Mahmoud Ben Hassine * */ public class DefaultFieldSetFactory implements FieldSetFactory { @@ -32,8 +33,8 @@ public class DefaultFieldSetFactory implements FieldSetFactory { private NumberFormat numberFormat; /** - * The {@link NumberFormat} to use for parsing numbers. If unset the default locale - * will be used. + * The {@link NumberFormat} to use for parsing numbers. If unset then + * {@link java.util.Locale#US} will be used. * @param numberFormat the {@link NumberFormat} to use for number parsing */ public void setNumberFormat(NumberFormat numberFormat) { @@ -41,8 +42,8 @@ public void setNumberFormat(NumberFormat numberFormat) { } /** - * The {@link DateFormat} to use for parsing numbers. If unset the default pattern is - * ISO standard yyyy/MM/dd. + * The {@link DateFormat} to use for parsing dates. If unset the default pattern is + * ISO standard yyyy-MM-dd. * @param dateFormat the {@link DateFormat} to use for date parsing */ public void setDateFormat(DateFormat dateFormat) { From 776d150827142ba2c9dce3dd566845ba7b5d094c Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 22 Nov 2023 00:21:29 +0100 Subject: [PATCH 31/68] Fix continuous integration workflow --- .github/workflows/continuous-integration.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 08e9d43564..42a87f6e82 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -1,16 +1,18 @@ -name: CI/CD build +name: CI/CD build for 5.0.x on: push: - branches: [ "main" ] + branches: [ "5.0.x" ] jobs: build: - name: Build Main branch + name: Build 5.0.x branch runs-on: ubuntu-latest steps: - name: Checkout source code uses: actions/checkout@v3 + with: + ref: '5.0.x' - name: Set up JDK 17 uses: actions/setup-java@v3 From 18da47359ca3d4eb6325068d9ab8f6ff5c752842 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 22 Nov 2023 00:35:38 +0100 Subject: [PATCH 32/68] Update Spring dependencies to latest snapshots --- pom.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 32f5ea138f..90a8f9a6f8 100644 --- a/pom.xml +++ b/pom.xml @@ -61,16 +61,16 @@ 17 - 6.0.13-SNAPSHOT + 6.0.14-SNAPSHOT 2.0.4-SNAPSHOT - 6.0.8-SNAPSHOT - 1.10.12-SNAPSHOT + 6.0.9-SNAPSHOT + 1.10.13-SNAPSHOT - 3.0.11-SNAPSHOT - 3.0.11-SNAPSHOT - 4.0.11-SNAPSHOT - 3.0.12-SNAPSHOT + 3.0.12-SNAPSHOT + 3.0.12-SNAPSHOT + 4.0.12-SNAPSHOT + 3.0.13-SNAPSHOT 3.0.10-SNAPSHOT 3.0.6-SNAPSHOT @@ -91,7 +91,7 @@ 3.0.2 - 1.1.6-SNAPSHOT + 1.1.7-SNAPSHOT 1.4.20 4.13.2 From e24f40c04421a63e64160df6379978b35d2ea6b7 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 22 Nov 2023 18:15:36 +0100 Subject: [PATCH 33/68] Prepare release 5.0.4 --- pom.xml | 60 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/pom.xml b/pom.xml index 90a8f9a6f8..6f937c22e7 100644 --- a/pom.xml +++ b/pom.xml @@ -61,18 +61,18 @@ 17 - 6.0.14-SNAPSHOT - 2.0.4-SNAPSHOT - 6.0.9-SNAPSHOT - 1.10.13-SNAPSHOT + 6.0.14 + 2.0.4 + 6.0.9 + 1.10.13 - 3.0.12-SNAPSHOT - 3.0.12-SNAPSHOT - 4.0.12-SNAPSHOT - 3.0.13-SNAPSHOT - 3.0.10-SNAPSHOT - 3.0.6-SNAPSHOT + 3.0.12 + 3.0.12 + 4.0.12 + 3.0.13 + 3.0.10 + 3.0.6 2.14.3 1.9.2 @@ -83,7 +83,7 @@ 3.1.0 3.0.2 3.1.0 - 4.0.5 + 4.0.8 4.9.1 5.9.3 @@ -91,42 +91,42 @@ 3.0.2 - 1.1.7-SNAPSHOT + 1.1.7 1.4.20 4.13.2 ${junit-jupiter.version} 2.2 3.24.2 - 5.5.0 + 5.7.0 2.9.1 - 2.13.0 - 2.9.0 - 2.0.7 + 2.15.0 + 2.11.0 + 2.0.9 2.7.2 - 2.2.220 - 3.42.0.0 + 2.2.224 + 3.44.0.0 10.16.1.1 - 2.16.14 - 2.30.0 - 4.0.3 - 2.20.0 + 2.18.13 + 2.31.2 + 4.0.4 + 2.22.0 8.0.1.Final 5.0.1 4.0.2 2.0.1 - 4.0.0 + 4.0.1 2.0.2 6.5.1 - 1.9.20 - 8.1.0 - 3.1.4 - 42.6.0 + 1.9.20.1 + 8.2.0 + 3.3.0 + 42.7.0 11.5.8.0 - 19.20.0.0 + 19.21.0.0 11.2.3.jre17 1.3.1 - 1.19.0 + 1.19.3 1.5.1 @@ -144,7 +144,7 @@ 3.11.0 3.1.2 3.1.2 - 3.5.0 + 3.6.0 3.3.0 0.8.10 1.5.0 From 3d382c12c1192918b2e5195a2d50f78eb3eed275 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 22 Nov 2023 19:30:38 +0100 Subject: [PATCH 34/68] Release version 5.0.4 --- pom.xml | 2 +- spring-batch-bom/pom.xml | 2 +- spring-batch-core/pom.xml | 2 +- spring-batch-docs/pom.xml | 2 +- spring-batch-infrastructure/pom.xml | 2 +- spring-batch-integration/pom.xml | 2 +- spring-batch-samples/pom.xml | 2 +- spring-batch-test/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 6f937c22e7..bba3ce2241 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. Spring Batch is part of the Spring Portfolio. - 5.0.4-SNAPSHOT + 5.0.4 pom https://projects.spring.io/spring-batch diff --git a/spring-batch-bom/pom.xml b/spring-batch-bom/pom.xml index 3909a20064..c0a9997162 100644 --- a/spring-batch-bom/pom.xml +++ b/spring-batch-bom/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4-SNAPSHOT + 5.0.4 spring-batch-bom pom diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index cf7a2e33b5..a4215e4e87 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4-SNAPSHOT + 5.0.4 spring-batch-core jar diff --git a/spring-batch-docs/pom.xml b/spring-batch-docs/pom.xml index 5f3298b703..d5a4ff8b8f 100644 --- a/spring-batch-docs/pom.xml +++ b/spring-batch-docs/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4-SNAPSHOT + 5.0.4 spring-batch-docs Spring Batch Docs diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index cfaa79160e..609723ac73 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4-SNAPSHOT + 5.0.4 spring-batch-infrastructure jar diff --git a/spring-batch-integration/pom.xml b/spring-batch-integration/pom.xml index a92c734b4f..8e217b8e62 100644 --- a/spring-batch-integration/pom.xml +++ b/spring-batch-integration/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4-SNAPSHOT + 5.0.4 spring-batch-integration Spring Batch Integration diff --git a/spring-batch-samples/pom.xml b/spring-batch-samples/pom.xml index 73b894a807..d80cadf3a4 100644 --- a/spring-batch-samples/pom.xml +++ b/spring-batch-samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4-SNAPSHOT + 5.0.4 spring-batch-samples jar diff --git a/spring-batch-test/pom.xml b/spring-batch-test/pom.xml index 780884c908..0dbb29550a 100644 --- a/spring-batch-test/pom.xml +++ b/spring-batch-test/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4-SNAPSHOT + 5.0.4 spring-batch-test Spring Batch Test From f38bf3268f3dcc3743f7e7053b439ca3b8490de1 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 22 Nov 2023 19:31:17 +0100 Subject: [PATCH 35/68] Next development version --- pom.xml | 2 +- spring-batch-bom/pom.xml | 2 +- spring-batch-core/pom.xml | 2 +- spring-batch-docs/pom.xml | 2 +- spring-batch-infrastructure/pom.xml | 2 +- spring-batch-integration/pom.xml | 2 +- spring-batch-samples/pom.xml | 2 +- spring-batch-test/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index bba3ce2241..0e047b0b3a 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. Spring Batch is part of the Spring Portfolio. - 5.0.4 + 5.0.5-SNAPSHOT pom https://projects.spring.io/spring-batch diff --git a/spring-batch-bom/pom.xml b/spring-batch-bom/pom.xml index c0a9997162..8f08adf638 100644 --- a/spring-batch-bom/pom.xml +++ b/spring-batch-bom/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4 + 5.0.5-SNAPSHOT spring-batch-bom pom diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index a4215e4e87..c3117d12d3 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4 + 5.0.5-SNAPSHOT spring-batch-core jar diff --git a/spring-batch-docs/pom.xml b/spring-batch-docs/pom.xml index d5a4ff8b8f..c166f6e8ce 100644 --- a/spring-batch-docs/pom.xml +++ b/spring-batch-docs/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4 + 5.0.5-SNAPSHOT spring-batch-docs Spring Batch Docs diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index 609723ac73..193e269fbe 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4 + 5.0.5-SNAPSHOT spring-batch-infrastructure jar diff --git a/spring-batch-integration/pom.xml b/spring-batch-integration/pom.xml index 8e217b8e62..3dee14a7a6 100644 --- a/spring-batch-integration/pom.xml +++ b/spring-batch-integration/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4 + 5.0.5-SNAPSHOT spring-batch-integration Spring Batch Integration diff --git a/spring-batch-samples/pom.xml b/spring-batch-samples/pom.xml index d80cadf3a4..0c6ab6446e 100644 --- a/spring-batch-samples/pom.xml +++ b/spring-batch-samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4 + 5.0.5-SNAPSHOT spring-batch-samples jar diff --git a/spring-batch-test/pom.xml b/spring-batch-test/pom.xml index 0dbb29550a..e4e48f8cfa 100644 --- a/spring-batch-test/pom.xml +++ b/spring-batch-test/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.4 + 5.0.5-SNAPSHOT spring-batch-test Spring Batch Test From 83c2c351ab8585cd3f4543ca0ce5da68137f60c7 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Fri, 24 Nov 2023 15:48:53 +0100 Subject: [PATCH 36/68] Update Github Actions --- .../artifactory-milestone-release.yml | 38 --------- ...taging.yml => artifactory-staging-50x.yml} | 4 +- .github/workflows/continuous-inspection.yml | 32 -------- ...ion.yml => continuous-integration-50x.yml} | 10 ++- ...pload.yml => documentation-upload-50x.yml} | 16 ++-- .github/workflows/maven-central-release.yml | 81 ------------------- .github/workflows/maven-central-stage.yml | 58 ------------- .../workflows/release-notes-generation.yml | 54 ------------- 8 files changed, 19 insertions(+), 274 deletions(-) delete mode 100644 .github/workflows/artifactory-milestone-release.yml rename .github/workflows/{artifactory-staging.yml => artifactory-staging-50x.yml} (93%) delete mode 100644 .github/workflows/continuous-inspection.yml rename .github/workflows/{continuous-integration.yml => continuous-integration-50x.yml} (78%) rename .github/workflows/{documentation-upload.yml => documentation-upload-50x.yml} (73%) delete mode 100644 .github/workflows/maven-central-release.yml delete mode 100644 .github/workflows/maven-central-stage.yml delete mode 100644 .github/workflows/release-notes-generation.yml diff --git a/.github/workflows/artifactory-milestone-release.yml b/.github/workflows/artifactory-milestone-release.yml deleted file mode 100644 index 4c368a39a4..0000000000 --- a/.github/workflows/artifactory-milestone-release.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Artifactory Milestone Release - -on: - workflow_dispatch: - inputs: - releaseVersion: - description: "Milestone release version" - required: true - -jobs: - build: - name: Release milestone to Artifactory - runs-on: ubuntu-latest - steps: - - name: Checkout source code - uses: actions/checkout@v3 - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - - - name: Capture release version - run: echo RELEASE_VERSION=${{ github.event.inputs.releaseVersion }} >> $GITHUB_ENV - - - name: Update release version - run: mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$RELEASE_VERSION - - - name: Enforce release rules - run: mvn org.apache.maven.plugins:maven-enforcer-plugin:enforce -Drules=requireReleaseDeps - - - name: Build with Maven and deploy to Artifactory's milestone repository - env: - ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }} - ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} - run: mvn -P artifactory-milestone -s settings.xml --batch-mode -Dmaven.test.skip=true deploy diff --git a/.github/workflows/artifactory-staging.yml b/.github/workflows/artifactory-staging-50x.yml similarity index 93% rename from .github/workflows/artifactory-staging.yml rename to .github/workflows/artifactory-staging-50x.yml index 13dbf9298e..6f8f0d1f81 100644 --- a/.github/workflows/artifactory-staging.yml +++ b/.github/workflows/artifactory-staging-50x.yml @@ -1,10 +1,10 @@ -name: Artifactory Staging +name: Artifactory Staging for 5.0.x on: workflow_dispatch: inputs: releaseVersion: - description: "Release version" + description: "Release version (5.0.x)" required: true jobs: diff --git a/.github/workflows/continuous-inspection.yml b/.github/workflows/continuous-inspection.yml deleted file mode 100644 index f496eba5c9..0000000000 --- a/.github/workflows/continuous-inspection.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Continuous inspection build - -on: - schedule: - - cron: '0 10 * * *' # Once per day at 10am UTC - workflow_dispatch: - -jobs: - code-quality-analysis: - name: code quality analysis report - runs-on: ubuntu-latest - steps: - - name: Checkout source code - uses: actions/checkout@v3 - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - - - name: Analyse test coverage with Jacoco - run: mvn -P test-coverage verify - - - name: Analyse code quality with Sonar - if: github.repository == 'spring-projects/spring-batch' - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ secrets.SONAR_URL }} - run: mvn sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_TOKEN - diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration-50x.yml similarity index 78% rename from .github/workflows/continuous-integration.yml rename to .github/workflows/continuous-integration-50x.yml index 42a87f6e82..84b97aab38 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration-50x.yml @@ -52,8 +52,10 @@ jobs: DOCS_HOST: ${{ secrets.DOCS_HOST }} DOCS_PATH: ${{ secrets.DOCS_PATH }} DOCS_USERNAME: ${{ secrets.DOCS_USERNAME }} - working-directory: spring-batch-docs + working-directory: spring-batch-docs/target run: | - cd target && unzip spring-batch-$PROJECT_VERSION-docs.zip - scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION - scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION + unzip spring-batch-$PROJECT_VERSION-docs.zip + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir -p $PROJECT_VERSION/api && mkdir -p $PROJECT_VERSION/reference + scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION/api + scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION/reference + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && rm 5.0.x-SNAPSHOT && ln -s $PROJECT_VERSION 5.0.x-SNAPSHOT diff --git a/.github/workflows/documentation-upload.yml b/.github/workflows/documentation-upload-50x.yml similarity index 73% rename from .github/workflows/documentation-upload.yml rename to .github/workflows/documentation-upload-50x.yml index ecbbb01246..8aa79f921f 100644 --- a/.github/workflows/documentation-upload.yml +++ b/.github/workflows/documentation-upload-50x.yml @@ -1,10 +1,10 @@ -name: Documentation Upload +name: Documentation Upload for 5.0.x on: workflow_dispatch: inputs: releaseVersion: - description: "Release version" + description: "Release version (5.0.x)" required: true jobs: @@ -17,6 +17,8 @@ jobs: - name: Checkout source code uses: actions/checkout@v3 + with: + ref: '5.0.x' - name: Set up JDK 17 uses: actions/setup-java@v3 @@ -25,6 +27,9 @@ jobs: distribution: 'temurin' cache: 'maven' + - name: Update release version + run: mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$RELEASE_VERSION + - name: Generate Java docs run: mvn javadoc:aggregate @@ -52,9 +57,10 @@ jobs: working-directory: spring-batch-docs/target run: | unzip spring-batch-$RELEASE_VERSION-docs.zip - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir $RELEASE_VERSION - scp -i $HOME/.ssh/key -r api reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST rm current && ln -s $RELEASE_VERSION current + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir -p $RELEASE_VERSION/api && mkdir -p $RELEASE_VERSION/reference + scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION/api + scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION/reference + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && rm 5.0.x && ln -s $RELEASE_VERSION 5.0.x unzip spring-batch-$RELEASE_VERSION-schemas.zip scp -i $HOME/.ssh/key batch/*.xsd $DOCS_USERNAME@$DOCS_HOST:$BATCH_SCHEMA_PATH diff --git a/.github/workflows/maven-central-release.yml b/.github/workflows/maven-central-release.yml deleted file mode 100644 index 6d3905dea2..0000000000 --- a/.github/workflows/maven-central-release.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: Maven Central Release - -on: - workflow_dispatch: - inputs: - releaseVersion: - description: "Release version" - required: true - -jobs: - build: - runs-on: ubuntu-latest - steps: - - - name: Capture release version - run: echo RELEASE_VERSION=${{ github.event.inputs.releaseVersion }} >> $GITHUB_ENV - - - name: Prepare directory structure - run: | - mkdir -p nexus/org/springframework/batch/spring-batch-bom/$RELEASE_VERSION - mkdir -p nexus/org/springframework/batch/spring-batch-infrastructure/$RELEASE_VERSION - mkdir -p nexus/org/springframework/batch/spring-batch-core/$RELEASE_VERSION - mkdir -p nexus/org/springframework/batch/spring-batch-test/$RELEASE_VERSION - mkdir -p nexus/org/springframework/batch/spring-batch-integration/$RELEASE_VERSION - - - name: Download release files from Artifactory - env: - ARTIFACTORY_URL: "https://repo.spring.io/libs-staging-local/org/springframework/batch" - run: | - echo "Downloading BOM artifacts" - cd nexus/org/springframework/batch/spring-batch-bom/$RELEASE_VERSION - wget $ARTIFACTORY_URL/spring-batch-bom/$RELEASE_VERSION/spring-batch-bom-$RELEASE_VERSION.pom - - echo "Downloading infrastructure artifacts" - cd ../../../../../.. - cd nexus/org/springframework/batch/spring-batch-infrastructure/$RELEASE_VERSION - wget $ARTIFACTORY_URL/spring-batch-infrastructure/$RELEASE_VERSION/spring-batch-infrastructure-$RELEASE_VERSION.pom - wget $ARTIFACTORY_URL/spring-batch-infrastructure/$RELEASE_VERSION/spring-batch-infrastructure-$RELEASE_VERSION.jar - wget $ARTIFACTORY_URL/spring-batch-infrastructure/$RELEASE_VERSION/spring-batch-infrastructure-$RELEASE_VERSION-javadoc.jar - wget $ARTIFACTORY_URL/spring-batch-infrastructure/$RELEASE_VERSION/spring-batch-infrastructure-$RELEASE_VERSION-sources.jar - - echo "Downloading core artifacts" - cd ../../../../../.. - cd nexus/org/springframework/batch/spring-batch-core/$RELEASE_VERSION - wget $ARTIFACTORY_URL/spring-batch-core/$RELEASE_VERSION/spring-batch-core-$RELEASE_VERSION.pom - wget $ARTIFACTORY_URL/spring-batch-core/$RELEASE_VERSION/spring-batch-core-$RELEASE_VERSION.jar - wget $ARTIFACTORY_URL/spring-batch-core/$RELEASE_VERSION/spring-batch-core-$RELEASE_VERSION-javadoc.jar - wget $ARTIFACTORY_URL/spring-batch-core/$RELEASE_VERSION/spring-batch-core-$RELEASE_VERSION-sources.jar - - echo "Downloading test artifacts" - cd ../../../../../.. - cd nexus/org/springframework/batch/spring-batch-test/$RELEASE_VERSION - wget $ARTIFACTORY_URL/spring-batch-test/$RELEASE_VERSION/spring-batch-test-$RELEASE_VERSION.pom - wget $ARTIFACTORY_URL/spring-batch-test/$RELEASE_VERSION/spring-batch-test-$RELEASE_VERSION.jar - wget $ARTIFACTORY_URL/spring-batch-test/$RELEASE_VERSION/spring-batch-test-$RELEASE_VERSION-javadoc.jar - wget $ARTIFACTORY_URL/spring-batch-test/$RELEASE_VERSION/spring-batch-test-$RELEASE_VERSION-sources.jar - - echo "Downloading integration artifacts" - cd ../../../../../.. - cd nexus/org/springframework/batch/spring-batch-integration/$RELEASE_VERSION - wget $ARTIFACTORY_URL/spring-batch-integration/$RELEASE_VERSION/spring-batch-integration-$RELEASE_VERSION.pom - wget $ARTIFACTORY_URL/spring-batch-integration/$RELEASE_VERSION/spring-batch-integration-$RELEASE_VERSION.jar - wget $ARTIFACTORY_URL/spring-batch-integration/$RELEASE_VERSION/spring-batch-integration-$RELEASE_VERSION-javadoc.jar - wget $ARTIFACTORY_URL/spring-batch-integration/$RELEASE_VERSION/spring-batch-integration-$RELEASE_VERSION-sources.jar - - - name: Sign artifacts and release them to Maven Central - uses: jvalkeal/nexus-sync@v0 - id: nexus - with: - url: ${{ secrets.OSSRH_URL }} - username: ${{ secrets.OSSRH_S01_TOKEN_USERNAME }} - password: ${{ secrets.OSSRH_S01_TOKEN_PASSWORD }} - staging-profile-name: ${{ secrets.OSSRH_STAGING_PROFILE_NAME }} - create: true - upload: true - close: true - release: true - generate-checksums: true - pgp-sign: true - pgp-sign-passphrase: ${{ secrets.GPG_PASSPHRASE }} - pgp-sign-private-key: ${{ secrets.GPG_PRIVATE_KEY }} diff --git a/.github/workflows/maven-central-stage.yml b/.github/workflows/maven-central-stage.yml deleted file mode 100644 index e01f26c54d..0000000000 --- a/.github/workflows/maven-central-stage.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Maven Central Staging - -on: - workflow_dispatch: - inputs: - buildName: - description: "Artifactory build name" - required: true - buildNumber: - description: "Artifactory build number" - required: true - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # to get spec file in .github - - uses: actions/checkout@v2 - - # Setup jfrog cli - - uses: jfrog/setup-jfrog-cli@v1 - with: - version: 1.43.2 - env: - JF_ARTIFACTORY_SPRING: ${{ secrets.JF_ARTIFACTORY_SPRING }} - - # Extract build id from input - - name: Extract Build Id - run: | - echo JFROG_CLI_BUILD_NAME=${{ github.event.inputs.buildName }} >> $GITHUB_ENV - echo JFROG_CLI_BUILD_NUMBER=${{ github.event.inputs.buildNumber }} >> $GITHUB_ENV - - # Download released files - - name: Download Release Files - run: | - jfrog rt download \ - --spec .github/release-files-spec.json \ - --spec-vars "buildname=$JFROG_CLI_BUILD_NAME;buildnumber=$JFROG_CLI_BUILD_NUMBER" - - # Create checksums, signatures and create staging repo on central and upload - - uses: jvalkeal/nexus-sync@v0 - id: nexus - with: - url: ${{ secrets.OSSRH_URL }} - username: ${{ secrets.OSSRH_S01_TOKEN_USERNAME }} - password: ${{ secrets.OSSRH_S01_TOKEN_PASSWORD }} - staging-profile-name: ${{ secrets.OSSRH_STAGING_PROFILE_NAME }} - create: true - upload: true - generate-checksums: true - pgp-sign: true - pgp-sign-passphrase: ${{ secrets.GPG_PASSPHRASE }} - pgp-sign-private-key: ${{ secrets.GPG_PRIVATE_KEY }} - - # Print staging repo id - - name: Print Staging Repo Id - run: echo ${{ steps.nexus.outputs.staged-repository-id }} diff --git a/.github/workflows/release-notes-generation.yml b/.github/workflows/release-notes-generation.yml deleted file mode 100644 index fa601a05fa..0000000000 --- a/.github/workflows/release-notes-generation.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Generate Release notes - -on: - workflow_dispatch: - inputs: - milestoneNumber: - description: "Milestone title" - required: true - generatorVersion: - description: "Changelog Generator version" - required: true - -jobs: - build: - name: Generate release notes - runs-on: ubuntu-latest - steps: - - name: Capture milestone number and generator version - run: | - echo MILESTONE_NUMBER=${{ github.event.inputs.milestoneNumber }} >> $GITHUB_ENV - echo GENERATOR_VERSION=${{ github.event.inputs.generatorVersion }} >> $GITHUB_ENV - - - name: Download changelog generator - run: wget https://github.com/spring-io/github-changelog-generator/releases/download/v$GENERATOR_VERSION/github-changelog-generator.jar - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - - - name: Prepare configuration file - run: | - cat << EOF > application.yml - changelog: - repository: spring-projects/spring-batch - sections: - - title: ":star: New features" - labels: [ "type: feature" ] - - title: ":rocket: Enhancements" - labels: [ "type: enhancement" ] - - title: ":lady_beetle: Bug fixes" - labels: [ "type: bug" ] - - title: ":notebook_with_decorative_cover: Documentation" - labels: [ "in: documentation" ] - - title: ":hammer: Tasks" - labels: [ "type: task" ] - EOF - - - name: Generate release notes - run: java -jar github-changelog-generator.jar $MILESTONE_NUMBER release-notes.md - - - name: Print release notes - run: cat release-notes.md From 255e972fa10e0bb38482b7dcae3a1bad079cec2b Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Mon, 27 Nov 2023 11:24:07 +0100 Subject: [PATCH 37/68] Fix documentation upload workflow --- .github/workflows/continuous-integration-50x.yml | 6 +++--- .github/workflows/documentation-upload-50x.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/continuous-integration-50x.yml b/.github/workflows/continuous-integration-50x.yml index 84b97aab38..4f4f8d0421 100644 --- a/.github/workflows/continuous-integration-50x.yml +++ b/.github/workflows/continuous-integration-50x.yml @@ -55,7 +55,7 @@ jobs: working-directory: spring-batch-docs/target run: | unzip spring-batch-$PROJECT_VERSION-docs.zip - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir -p $PROJECT_VERSION/api && mkdir -p $PROJECT_VERSION/reference + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir -p $PROJECT_VERSION/api scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION/api - scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION/reference - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && rm 5.0.x-SNAPSHOT && ln -s $PROJECT_VERSION 5.0.x-SNAPSHOT + scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && ln -s $PROJECT_VERSION 5.0.x-SNAPSHOT diff --git a/.github/workflows/documentation-upload-50x.yml b/.github/workflows/documentation-upload-50x.yml index 8aa79f921f..82844bc8f5 100644 --- a/.github/workflows/documentation-upload-50x.yml +++ b/.github/workflows/documentation-upload-50x.yml @@ -57,10 +57,10 @@ jobs: working-directory: spring-batch-docs/target run: | unzip spring-batch-$RELEASE_VERSION-docs.zip - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir -p $RELEASE_VERSION/api && mkdir -p $RELEASE_VERSION/reference + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir -p $RELEASE_VERSION/api scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION/api - scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION/reference - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && rm 5.0.x && ln -s $RELEASE_VERSION 5.0.x + scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && ln -s $RELEASE_VERSION 5.0.x unzip spring-batch-$RELEASE_VERSION-schemas.zip scp -i $HOME/.ssh/key batch/*.xsd $DOCS_USERNAME@$DOCS_HOST:$BATCH_SCHEMA_PATH From 8594b8ca55922e348bff242845d88d50056c58ea Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 13 Dec 2023 11:25:27 +0100 Subject: [PATCH 38/68] Rename workflow files --- .../{artifactory-staging-50x.yml => artifactory-staging.yml} | 2 +- .../{documentation-upload-50x.yml => documentation-upload.yml} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{artifactory-staging-50x.yml => artifactory-staging.yml} (97%) rename .github/workflows/{documentation-upload-50x.yml => documentation-upload.yml} (98%) diff --git a/.github/workflows/artifactory-staging-50x.yml b/.github/workflows/artifactory-staging.yml similarity index 97% rename from .github/workflows/artifactory-staging-50x.yml rename to .github/workflows/artifactory-staging.yml index 6f8f0d1f81..00d80b927d 100644 --- a/.github/workflows/artifactory-staging-50x.yml +++ b/.github/workflows/artifactory-staging.yml @@ -1,4 +1,4 @@ -name: Artifactory Staging for 5.0.x +name: Artifactory Staging on: workflow_dispatch: diff --git a/.github/workflows/documentation-upload-50x.yml b/.github/workflows/documentation-upload.yml similarity index 98% rename from .github/workflows/documentation-upload-50x.yml rename to .github/workflows/documentation-upload.yml index 82844bc8f5..fb2dba83c0 100644 --- a/.github/workflows/documentation-upload-50x.yml +++ b/.github/workflows/documentation-upload.yml @@ -1,4 +1,4 @@ -name: Documentation Upload for 5.0.x +name: Documentation Upload on: workflow_dispatch: From 24eb3ba2d459bcfd485a26eab733dc2c5b0d87fd Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Mon, 22 Jan 2024 12:43:57 +0100 Subject: [PATCH 39/68] Upgrade Spring dependencies to latest snapshots --- pom.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 0e047b0b3a..249135e51c 100644 --- a/pom.xml +++ b/pom.xml @@ -61,18 +61,18 @@ 17 - 6.0.14 - 2.0.4 - 6.0.9 - 1.10.13 + 6.0.17-SNAPSHOT + 2.0.5-SNAPSHOT + 6.0.10-SNAPSHOT + 1.10.14-SNAPSHOT - 3.0.12 - 3.0.12 - 4.0.12 - 3.0.13 - 3.0.10 - 3.0.6 + 3.0.13-SNAPSHOT + 3.0.13-SNAPSHOT + 4.0.13-SNAPSHOT + 3.0.14-SNAPSHOT + 3.0.11-SNAPSHOT + 3.0.7-SNAPSHOT 2.14.3 1.9.2 @@ -91,7 +91,7 @@ 3.0.2 - 1.1.7 + 1.1.10-SNAPSHOT 1.4.20 4.13.2 From 1258db903f02a5611d85272a94c21c008897ee9f Mon Sep 17 00:00:00 2001 From: Alexander Afanasiev Date: Fri, 5 Jan 2024 10:51:15 +0100 Subject: [PATCH 40/68] Fix error message Issue #4528 --- .../batch/core/launch/support/JobOperatorFactoryBean.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBean.java index ce2ef8e4f2..a3c07375ec 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobOperatorFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 the original author or authors. + * Copyright 2022-2024 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. @@ -71,7 +71,7 @@ public class JobOperatorFactoryBean implements FactoryBean, Initial public void afterPropertiesSet() throws Exception { Assert.notNull(this.transactionManager, "TransactionManager must not be null"); Assert.notNull(this.jobLauncher, "JobLauncher must not be null"); - Assert.notNull(this.jobRegistry, "JobLocator must not be null"); + Assert.notNull(this.jobRegistry, "JobRegistry must not be null"); Assert.notNull(this.jobExplorer, "JobExplorer must not be null"); Assert.notNull(this.jobRepository, "JobRepository must not be null"); if (this.transactionAttributeSource == null) { From 893e83e0b5211caa95b035c33517f754d2d0353a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bj=C3=B8rge=20Andersen?= Date: Fri, 5 Jan 2024 16:45:10 +0100 Subject: [PATCH 41/68] Fix javadoc referencing Long when it should be Double Resolves #4526 --- .../main/java/org/springframework/batch/core/JobParameters.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java index 586f7ab62f..01ee5034cc 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java @@ -142,7 +142,7 @@ public String getString(String key, @Nullable String defaultValue) { } /** - * Typesafe getter for the {@link Long} represented by the provided key. + * Typesafe getter for the {@link Double} represented by the provided key. * @param key The key for which to get a value. * @return The {@link Double} value or {@code null} if the key is absent. */ From 2fbdcd42a01e8a85956a41bbfb380208d8a05509 Mon Sep 17 00:00:00 2001 From: Henning Poettker Date: Thu, 30 Nov 2023 10:43:00 +0100 Subject: [PATCH 42/68] Check dirty flag of step execution context before update in inner loop --- .../springframework/batch/core/step/tasklet/TaskletStep.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 b5941c1ecc..58a22395c4 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 @@ -431,7 +431,9 @@ public RepeatStatus doInTransaction(TransactionStatus status) { try { // Going to attempt a commit. If it fails this flag will // stay false and we can use that later. - getJobRepository().updateExecutionContext(stepExecution); + if (stepExecution.getExecutionContext().isDirty()) { + getJobRepository().updateExecutionContext(stepExecution); + } stepExecution.incrementCommitCount(); if (logger.isDebugEnabled()) { logger.debug("Saving step execution before commit: " + stepExecution); From 0093e441c9a5709c8a09920e8c891a891b1c8a44 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 14 Feb 2024 15:01:59 +0100 Subject: [PATCH 43/68] Fix exception when parsing empty values in DefaultJobParametersConverter Resolves #4505 --- .../DefaultJobParametersConverter.java | 8 ++++++-- .../DefaultJobParametersConverterTests.java | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 3 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 ab0cfdb6ba..79bd590d7b 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 @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 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. @@ -168,7 +168,11 @@ protected JobParameter decode(String encodedJobParameter) { } private String parseValue(String encodedJobParameter) { - return StringUtils.commaDelimitedListToStringArray(encodedJobParameter)[0]; + String[] tokens = StringUtils.commaDelimitedListToStringArray(encodedJobParameter); + if (tokens.length == 0) { + return ""; + } + return tokens[0]; } private Class parseType(String encodedJobParameter) { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java index e413162a41..d39b9ad5eb 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/converter/DefaultJobParametersConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 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,6 +20,7 @@ import org.junit.jupiter.api.Test; +import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.util.StringUtils; @@ -129,6 +130,22 @@ void testGetParametersWithBogusLong() { } } + @Test + void testGetParametersWithEmptyValue() { + // given + String[] args = new String[] { "parameter=" }; + + // when + JobParameters jobParameters = factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "=")); + + // then + assertEquals(1, jobParameters.getParameters().size()); + JobParameter parameter = jobParameters.getParameters().get("parameter"); + assertEquals("", parameter.getValue()); + assertEquals(String.class, parameter.getType()); + assertTrue(parameter.isIdentifying()); + } + @Test void testGetParametersWithDoubleValueDeclaredAsLong() { From 36cd26fa1b3b1f093632b64d6ce5653fc4460058 Mon Sep 17 00:00:00 2001 From: Henning Poettker Date: Tue, 21 Nov 2023 23:31:13 +0100 Subject: [PATCH 44/68] Let SimpleJobRepository#deleteJobInstance delete corresponding step executions Resolves #4382 --- .../support/SimpleJobRepository.java | 4 +- .../SimpleJobRepositoryIntegrationTests.java | 63 ++++++++----------- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java index a427dbfa35..48610fbf77 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/SimpleJobRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 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. @@ -328,7 +328,7 @@ public void deleteJobExecution(JobExecution jobExecution) { @Override public void deleteJobInstance(JobInstance jobInstance) { - List jobExecutions = this.jobExecutionDao.findJobExecutions(jobInstance); + List jobExecutions = findJobExecutions(jobInstance); for (JobExecution jobExecution : jobExecutions) { deleteJobExecution(jobExecution); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryIntegrationTests.java index 53c33b178e..eb81dbd246 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2022 the original author or authors. + * Copyright 2008-2024 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. @@ -32,12 +32,13 @@ import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; -import java.util.Arrays; +import java.util.List; +import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; /** * Repository tests using JDBC DAOs (rather than mocks). @@ -152,11 +153,7 @@ void testGetStepExecutionCountAndLastStepExecution() throws Exception { @Transactional @Test void testSaveExecutionContext() throws Exception { - ExecutionContext ctx = new ExecutionContext() { - { - putLong("crashedPosition", 7); - } - }; + ExecutionContext ctx = new ExecutionContext(Map.of("crashedPosition", 7)); JobExecution jobExec = jobRepository.createJobExecution(job.getName(), jobParameters); jobExec.setStartTime(LocalDateTime.now()); jobExec.setExecutionContext(ctx); @@ -169,11 +166,6 @@ void testSaveExecutionContext() throws Exception { StepExecution retrievedStepExec = jobRepository.getLastStepExecution(jobExec.getJobInstance(), step.getName()); assertEquals(stepExec, retrievedStepExec); assertEquals(ctx, retrievedStepExec.getExecutionContext()); - - // JobExecution retrievedJobExec = - // jobRepository.getLastJobExecution(jobExec.getJobInstance()); - // assertEquals(jobExec, retrievedJobExec); - // assertEquals(ctx, retrievedJobExec.getExecutionContext()); } /* @@ -205,7 +197,7 @@ void testGetLastJobExecution() throws Exception { jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters); StepExecution stepExecution = new StepExecution("step1", jobExecution); jobRepository.add(stepExecution); - jobExecution.addStepExecutions(Arrays.asList(stepExecution)); + jobExecution.addStepExecutions(List.of(stepExecution)); assertEquals(jobExecution, jobRepository.getLastJobExecution(job.getName(), jobParameters)); assertEquals(stepExecution, jobExecution.getStepExecutions().iterator().next()); } @@ -233,42 +225,41 @@ void testReExecuteWithSameJobParameters() throws Exception { */ @Transactional @Test - public void testReExecuteWithSameJobParametersWhenRunning() throws Exception { + void testReExecuteWithSameJobParametersWhenRunning() throws Exception { JobParameters jobParameters = new JobParametersBuilder().addString("stringKey", "stringValue") .toJobParameters(); // jobExecution with status STARTING JobExecution jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters); - try { - jobRepository.createJobExecution(job.getName(), jobParameters); - fail(); - } - catch (JobExecutionAlreadyRunningException e) { - // expected - } + assertThrows(JobExecutionAlreadyRunningException.class, + () -> jobRepository.createJobExecution(job.getName(), jobParameters)); // jobExecution with status STARTED jobExecution.setStatus(BatchStatus.STARTED); jobExecution.setStartTime(LocalDateTime.now()); jobRepository.update(jobExecution); - try { - jobRepository.createJobExecution(job.getName(), jobParameters); - fail(); - } - catch (JobExecutionAlreadyRunningException e) { - // expected - } + assertThrows(JobExecutionAlreadyRunningException.class, + () -> jobRepository.createJobExecution(job.getName(), jobParameters)); // jobExecution with status STOPPING jobExecution.setStatus(BatchStatus.STOPPING); jobRepository.update(jobExecution); - try { - jobRepository.createJobExecution(job.getName(), jobParameters); - fail(); - } - catch (JobExecutionAlreadyRunningException e) { - // expected - } + assertThrows(JobExecutionAlreadyRunningException.class, + () -> jobRepository.createJobExecution(job.getName(), jobParameters)); + } + + @Transactional + @Test + void testDeleteJobInstance() throws Exception { + var jobParameters = new JobParametersBuilder().addString("foo", "bar").toJobParameters(); + var jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters); + var stepExecution = new StepExecution("step", jobExecution); + jobRepository.add(stepExecution); + + jobRepository.deleteJobInstance(jobExecution.getJobInstance()); + + assertEquals(0, jobRepository.findJobInstancesByName(job.getName(), 0, 1).size()); + assertNull(jobRepository.getLastJobExecution(job.getName(), jobParameters)); } } From 7c5a25f8a9eecc2aa151cdf819b553538a880aa4 Mon Sep 17 00:00:00 2001 From: Ilpyo-Yang Date: Mon, 23 Oct 2023 23:32:12 +0900 Subject: [PATCH 45/68] Add AbstractTaskletStepBuilder copy constructor This commit includes tests for the copy constructor of AbstractTaskletStepBuilder and for the faultTolerant method, specifically after taskExecutor has been set. (cherry picked from commit b9ba8ffb861119924cbb4e17069ddd9e911aaa91) --- .../builder/AbstractTaskletStepBuilder.java | 18 +++ .../core/step/builder/SimpleStepBuilder.java | 1 - .../test/AbstractTaskletStepBuilderTests.java | 114 ++++++++++++++++++ 3 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 spring-batch-test/src/test/java/org/springframework/batch/test/AbstractTaskletStepBuilderTests.java diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java index 6ff424896b..eb61b652d1 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java @@ -49,6 +49,7 @@ * @author Dave Syer * @author Michael Minella * @author Mahmoud Ben Hassine + * @author Ilpyo Yang * @since 2.2 * @param the type of builder represented */ @@ -74,6 +75,23 @@ public AbstractTaskletStepBuilder(StepBuilderHelper parent) { super(parent); } + /** + * Create a new builder initialized with any properties in the parent. The parent is + * copied, so it can be re-used. + * @param parent a parent helper containing common step properties + */ + public AbstractTaskletStepBuilder(AbstractTaskletStepBuilder parent) { + super(parent); + this.chunkListeners = parent.chunkListeners; + this.stepOperations = parent.stepOperations; + this.transactionManager = parent.transactionManager; + this.transactionAttribute = parent.transactionAttribute; + this.streams.addAll(parent.streams); + this.exceptionHandler = parent.exceptionHandler; + this.throttleLimit = parent.throttleLimit; + this.taskExecutor = parent.taskExecutor; + } + protected abstract Tasklet createTasklet(); /** diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java index aa51c34e54..088b17ca5f 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java @@ -114,7 +114,6 @@ protected SimpleStepBuilder(SimpleStepBuilder parent) { this.itemListeners = parent.itemListeners; this.readerTransactionalQueue = parent.readerTransactionalQueue; this.meterRegistry = parent.meterRegistry; - this.transactionManager(parent.getTransactionManager()); } public FaultTolerantStepBuilder faultTolerant() { diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/AbstractTaskletStepBuilderTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/AbstractTaskletStepBuilderTests.java new file mode 100644 index 0000000000..465d6f5f5b --- /dev/null +++ b/spring-batch-test/src/test/java/org/springframework/batch/test/AbstractTaskletStepBuilderTests.java @@ -0,0 +1,114 @@ +package org.springframework.batch.test; +/* + * Copyright 2020-2022 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. + */ + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.AbstractTaskletStepBuilder; +import org.springframework.batch.core.step.builder.SimpleStepBuilder; +import org.springframework.batch.core.step.builder.StepBuilderHelper; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.test.context.SpringBatchTest; +import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.core.task.TaskExecutor; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +/** + * Test cases for verifying the {@link AbstractTaskletStepBuilder} and faultTolerant() functionality. + * + * @author Ilpyo Yang + */ +@SpringBatchTest +@SpringJUnitConfig +public class AbstractTaskletStepBuilderTests { + private final JobRepository jobRepository = mock(JobRepository.class); + private final int chunkSize = 10; + private final ItemReader itemReader = mock(ItemReader.class); + private final ItemProcessor itemProcessor = mock(ItemProcessor.class); + private final ItemWriter itemWriter = mock(ItemWriter.class); + private final SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); + SimpleStepBuilder simpleStepBuilder; + + private T accessPrivateField(Object o, String fieldName) throws ReflectiveOperationException { + Field field = o.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + return (T) field.get(o); + } + + private T accessSuperClassPrivateField(Object o, String fieldName) throws ReflectiveOperationException { + Field field = o.getClass().getSuperclass().getDeclaredField(fieldName); + field.setAccessible(true); + return (T) field.get(o); + } + + @BeforeEach + void set(){ + StepBuilderHelper stepBuilderHelper = new StepBuilderHelper("test", jobRepository) { + @Override + protected StepBuilderHelper self() { + return null; + } + }; + simpleStepBuilder = new SimpleStepBuilder(stepBuilderHelper); + simpleStepBuilder.chunk(chunkSize); + simpleStepBuilder.reader(itemReader); + simpleStepBuilder.processor(itemProcessor); + simpleStepBuilder.writer(itemWriter); + } + + @Test + void copyConstractorTest() throws ReflectiveOperationException { + Constructor constructor = SimpleStepBuilder.class.getDeclaredConstructor(SimpleStepBuilder.class); + constructor.setAccessible(true); + SimpleStepBuilder copySimpleStepBuilder = constructor.newInstance(simpleStepBuilder); + + int copyChunkSize = accessPrivateField(copySimpleStepBuilder, "chunkSize"); + ItemReader copyItemReader = accessPrivateField(copySimpleStepBuilder, "reader"); + ItemProcessor copyItemProcessor = accessPrivateField(copySimpleStepBuilder, "processor"); + ItemWriter copyItemWriter = accessPrivateField(copySimpleStepBuilder, "writer"); + + assertEquals(chunkSize, copyChunkSize); + assertEquals(itemReader, copyItemReader); + assertEquals(itemProcessor, copyItemProcessor); + assertEquals(itemWriter, copyItemWriter); + } + + @Test + void faultTolerantMethodTest() throws ReflectiveOperationException { + simpleStepBuilder.taskExecutor(taskExecutor); // The task executor is set before faultTolerant() + simpleStepBuilder.faultTolerant(); + + int afterChunkSize = accessPrivateField(simpleStepBuilder, "chunkSize"); + ItemReader afterItemReader = accessPrivateField(simpleStepBuilder, "reader"); + ItemProcessor afterItemProcessor = accessPrivateField(simpleStepBuilder, "processor"); + ItemWriter afterItemWriter = accessPrivateField(simpleStepBuilder, "writer"); + TaskExecutor afterTaskExecutor = accessSuperClassPrivateField(simpleStepBuilder, "taskExecutor"); + + assertEquals(chunkSize, afterChunkSize); + assertEquals(itemReader, afterItemReader); + assertEquals(itemProcessor, afterItemProcessor); + assertEquals(itemWriter, afterItemWriter); + assertEquals(taskExecutor, afterTaskExecutor); + } +} From 6549ecc5309606a1f0dcce171d06622fdd62bc61 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Mon, 19 Feb 2024 15:23:50 +0100 Subject: [PATCH 46/68] Refine contribution #4471 - Update tests - Move test class to the core module (cherry picked from commit 4b8e504972a59a99e33e634a12c6ceebbad5fca8) --- .../AbstractTaskletStepBuilderTests.java | 88 ++++++++++++++ .../test/AbstractTaskletStepBuilderTests.java | 114 ------------------ 2 files changed, 88 insertions(+), 114 deletions(-) create mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilderTests.java delete mode 100644 spring-batch-test/src/test/java/org/springframework/batch/test/AbstractTaskletStepBuilderTests.java diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilderTests.java new file mode 100644 index 0000000000..6cd6f2374e --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilderTests.java @@ -0,0 +1,88 @@ +/* + * Copyright 2024 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. + */ +package org.springframework.batch.core.step.builder; + +import org.junit.jupiter.api.Test; + +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.tasklet.TaskletStep; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate; +import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.transaction.PlatformTransactionManager; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.mockito.Mockito.mock; + +/** + * Test cases for verifying the {@link AbstractTaskletStepBuilder} and faultTolerant() + * functionality. + * + * Issue: https://github.com/spring-projects/spring-batch/issues/4438 + * + * @author Ilpyo Yang + * @author Mahmoud Ben Hassine + */ +public class AbstractTaskletStepBuilderTests { + + private final JobRepository jobRepository = mock(JobRepository.class); + + private final PlatformTransactionManager transactionManager = mock(PlatformTransactionManager.class); + + private final int chunkSize = 10; + + private final ItemReader itemReader = mock(ItemReader.class); + + private final ItemProcessor itemProcessor = mock(ItemProcessor.class); + + private final ItemWriter itemWriter = mock(ItemWriter.class); + + private final SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); + + @Test + void testSetTaskExecutorBeforeFaultTolerant() { + TaskletStep step = new StepBuilder("step-name", jobRepository) + .chunk(chunkSize, transactionManager) + .taskExecutor(taskExecutor) + .reader(itemReader) + .processor(itemProcessor) + .writer(itemWriter) + .faultTolerant() + .build(); + + Object stepOperations = ReflectionTestUtils.getField(step, "stepOperations"); + assertInstanceOf(TaskExecutorRepeatTemplate.class, stepOperations); + } + + @Test + void testSetTaskExecutorAfterFaultTolerant() { + TaskletStep step = new StepBuilder("step-name", jobRepository) + .chunk(chunkSize, transactionManager) + .reader(itemReader) + .processor(itemProcessor) + .writer(itemWriter) + .faultTolerant() + .taskExecutor(taskExecutor) + .build(); + + Object stepOperations = ReflectionTestUtils.getField(step, "stepOperations"); + assertInstanceOf(TaskExecutorRepeatTemplate.class, stepOperations); + } + +} diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/AbstractTaskletStepBuilderTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/AbstractTaskletStepBuilderTests.java deleted file mode 100644 index 465d6f5f5b..0000000000 --- a/spring-batch-test/src/test/java/org/springframework/batch/test/AbstractTaskletStepBuilderTests.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.springframework.batch.test; -/* - * Copyright 2020-2022 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. - */ - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.step.builder.AbstractTaskletStepBuilder; -import org.springframework.batch.core.step.builder.SimpleStepBuilder; -import org.springframework.batch.core.step.builder.StepBuilderHelper; -import org.springframework.batch.item.ItemProcessor; -import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.test.context.SpringBatchTest; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.core.task.TaskExecutor; -import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; - -/** - * Test cases for verifying the {@link AbstractTaskletStepBuilder} and faultTolerant() functionality. - * - * @author Ilpyo Yang - */ -@SpringBatchTest -@SpringJUnitConfig -public class AbstractTaskletStepBuilderTests { - private final JobRepository jobRepository = mock(JobRepository.class); - private final int chunkSize = 10; - private final ItemReader itemReader = mock(ItemReader.class); - private final ItemProcessor itemProcessor = mock(ItemProcessor.class); - private final ItemWriter itemWriter = mock(ItemWriter.class); - private final SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); - SimpleStepBuilder simpleStepBuilder; - - private T accessPrivateField(Object o, String fieldName) throws ReflectiveOperationException { - Field field = o.getClass().getDeclaredField(fieldName); - field.setAccessible(true); - return (T) field.get(o); - } - - private T accessSuperClassPrivateField(Object o, String fieldName) throws ReflectiveOperationException { - Field field = o.getClass().getSuperclass().getDeclaredField(fieldName); - field.setAccessible(true); - return (T) field.get(o); - } - - @BeforeEach - void set(){ - StepBuilderHelper stepBuilderHelper = new StepBuilderHelper("test", jobRepository) { - @Override - protected StepBuilderHelper self() { - return null; - } - }; - simpleStepBuilder = new SimpleStepBuilder(stepBuilderHelper); - simpleStepBuilder.chunk(chunkSize); - simpleStepBuilder.reader(itemReader); - simpleStepBuilder.processor(itemProcessor); - simpleStepBuilder.writer(itemWriter); - } - - @Test - void copyConstractorTest() throws ReflectiveOperationException { - Constructor constructor = SimpleStepBuilder.class.getDeclaredConstructor(SimpleStepBuilder.class); - constructor.setAccessible(true); - SimpleStepBuilder copySimpleStepBuilder = constructor.newInstance(simpleStepBuilder); - - int copyChunkSize = accessPrivateField(copySimpleStepBuilder, "chunkSize"); - ItemReader copyItemReader = accessPrivateField(copySimpleStepBuilder, "reader"); - ItemProcessor copyItemProcessor = accessPrivateField(copySimpleStepBuilder, "processor"); - ItemWriter copyItemWriter = accessPrivateField(copySimpleStepBuilder, "writer"); - - assertEquals(chunkSize, copyChunkSize); - assertEquals(itemReader, copyItemReader); - assertEquals(itemProcessor, copyItemProcessor); - assertEquals(itemWriter, copyItemWriter); - } - - @Test - void faultTolerantMethodTest() throws ReflectiveOperationException { - simpleStepBuilder.taskExecutor(taskExecutor); // The task executor is set before faultTolerant() - simpleStepBuilder.faultTolerant(); - - int afterChunkSize = accessPrivateField(simpleStepBuilder, "chunkSize"); - ItemReader afterItemReader = accessPrivateField(simpleStepBuilder, "reader"); - ItemProcessor afterItemProcessor = accessPrivateField(simpleStepBuilder, "processor"); - ItemWriter afterItemWriter = accessPrivateField(simpleStepBuilder, "writer"); - TaskExecutor afterTaskExecutor = accessSuperClassPrivateField(simpleStepBuilder, "taskExecutor"); - - assertEquals(chunkSize, afterChunkSize); - assertEquals(itemReader, afterItemReader); - assertEquals(itemProcessor, afterItemProcessor); - assertEquals(itemWriter, afterItemWriter); - assertEquals(taskExecutor, afterTaskExecutor); - } -} From cf1607147fcc5e6dcb267f233a274575ca4d2d22 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 21 Feb 2024 11:35:39 +0100 Subject: [PATCH 47/68] Prepare release 5.0.5 --- pom.xml | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/pom.xml b/pom.xml index 249135e51c..a493ec2983 100644 --- a/pom.xml +++ b/pom.xml @@ -61,18 +61,18 @@ 17 - 6.0.17-SNAPSHOT - 2.0.5-SNAPSHOT - 6.0.10-SNAPSHOT - 1.10.14-SNAPSHOT + 6.0.17 + 2.0.5 + 6.0.9 + 1.10.13 - 3.0.13-SNAPSHOT - 3.0.13-SNAPSHOT - 4.0.13-SNAPSHOT - 3.0.14-SNAPSHOT - 3.0.11-SNAPSHOT - 3.0.7-SNAPSHOT + 3.0.12 + 3.0.12 + 4.0.12 + 3.0.14 + 3.0.11 + 3.0.6 2.14.3 1.9.2 @@ -83,7 +83,7 @@ 3.1.0 3.0.2 3.1.0 - 4.0.8 + 4.0.9 4.9.1 5.9.3 @@ -91,7 +91,7 @@ 3.0.2 - 1.1.10-SNAPSHOT + 1.1.10 1.4.20 4.13.2 @@ -100,17 +100,17 @@ 3.24.2 5.7.0 2.9.1 - 2.15.0 + 2.15.1 2.11.0 - 2.0.9 + 2.0.12 2.7.2 2.2.224 - 3.44.0.0 + 3.44.1.0 10.16.1.1 - 2.18.13 + 2.18.16 2.31.2 4.0.4 - 2.22.0 + 2.22.1 8.0.1.Final 5.0.1 4.0.2 @@ -118,15 +118,15 @@ 4.0.1 2.0.2 6.5.1 - 1.9.20.1 - 8.2.0 - 3.3.0 - 42.7.0 - 11.5.8.0 - 19.21.0.0 + 1.9.21.1 + 8.3.0 + 3.3.2 + 42.7.2 + 11.5.9.0 + 19.22.0.0 11.2.3.jre17 1.3.1 - 1.19.3 + 1.19.5 1.5.1 From 03daeeb0f845bbb93bd2dba35bf3f2bbff9f75d5 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 21 Feb 2024 15:22:02 +0100 Subject: [PATCH 48/68] Release version 5.0.5 --- pom.xml | 2 +- spring-batch-bom/pom.xml | 2 +- spring-batch-core/pom.xml | 2 +- spring-batch-docs/pom.xml | 2 +- spring-batch-infrastructure/pom.xml | 2 +- spring-batch-integration/pom.xml | 2 +- spring-batch-samples/pom.xml | 2 +- spring-batch-test/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index a493ec2983..0ce5485b23 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. Spring Batch is part of the Spring Portfolio. - 5.0.5-SNAPSHOT + 5.0.5 pom https://projects.spring.io/spring-batch diff --git a/spring-batch-bom/pom.xml b/spring-batch-bom/pom.xml index 8f08adf638..7fdc7f0772 100644 --- a/spring-batch-bom/pom.xml +++ b/spring-batch-bom/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5-SNAPSHOT + 5.0.5 spring-batch-bom pom diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index c3117d12d3..6409b211f7 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5-SNAPSHOT + 5.0.5 spring-batch-core jar diff --git a/spring-batch-docs/pom.xml b/spring-batch-docs/pom.xml index c166f6e8ce..25e213d744 100644 --- a/spring-batch-docs/pom.xml +++ b/spring-batch-docs/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5-SNAPSHOT + 5.0.5 spring-batch-docs Spring Batch Docs diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index 193e269fbe..f78df550d8 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5-SNAPSHOT + 5.0.5 spring-batch-infrastructure jar diff --git a/spring-batch-integration/pom.xml b/spring-batch-integration/pom.xml index 3dee14a7a6..376a16fbcc 100644 --- a/spring-batch-integration/pom.xml +++ b/spring-batch-integration/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5-SNAPSHOT + 5.0.5 spring-batch-integration Spring Batch Integration diff --git a/spring-batch-samples/pom.xml b/spring-batch-samples/pom.xml index 0c6ab6446e..f428144d36 100644 --- a/spring-batch-samples/pom.xml +++ b/spring-batch-samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5-SNAPSHOT + 5.0.5 spring-batch-samples jar diff --git a/spring-batch-test/pom.xml b/spring-batch-test/pom.xml index e4e48f8cfa..3ef0d3c956 100644 --- a/spring-batch-test/pom.xml +++ b/spring-batch-test/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5-SNAPSHOT + 5.0.5 spring-batch-test Spring Batch Test From 5e18dd873ca56d61078fd73254fe8ed77277a539 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 21 Feb 2024 15:22:18 +0100 Subject: [PATCH 49/68] Next development version --- pom.xml | 2 +- spring-batch-bom/pom.xml | 2 +- spring-batch-core/pom.xml | 2 +- spring-batch-docs/pom.xml | 2 +- spring-batch-infrastructure/pom.xml | 2 +- spring-batch-integration/pom.xml | 2 +- spring-batch-samples/pom.xml | 2 +- spring-batch-test/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 0ce5485b23..bbf785b14d 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. Spring Batch is part of the Spring Portfolio. - 5.0.5 + 5.0.6-SNAPSHOT pom https://projects.spring.io/spring-batch diff --git a/spring-batch-bom/pom.xml b/spring-batch-bom/pom.xml index 7fdc7f0772..6621731259 100644 --- a/spring-batch-bom/pom.xml +++ b/spring-batch-bom/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5 + 5.0.6-SNAPSHOT spring-batch-bom pom diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index 6409b211f7..ca2de1b20f 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5 + 5.0.6-SNAPSHOT spring-batch-core jar diff --git a/spring-batch-docs/pom.xml b/spring-batch-docs/pom.xml index 25e213d744..91c4431ef9 100644 --- a/spring-batch-docs/pom.xml +++ b/spring-batch-docs/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5 + 5.0.6-SNAPSHOT spring-batch-docs Spring Batch Docs diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index f78df550d8..06417664b0 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5 + 5.0.6-SNAPSHOT spring-batch-infrastructure jar diff --git a/spring-batch-integration/pom.xml b/spring-batch-integration/pom.xml index 376a16fbcc..4ffec5faaf 100644 --- a/spring-batch-integration/pom.xml +++ b/spring-batch-integration/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5 + 5.0.6-SNAPSHOT spring-batch-integration Spring Batch Integration diff --git a/spring-batch-samples/pom.xml b/spring-batch-samples/pom.xml index f428144d36..4af54a5686 100644 --- a/spring-batch-samples/pom.xml +++ b/spring-batch-samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5 + 5.0.6-SNAPSHOT spring-batch-samples jar diff --git a/spring-batch-test/pom.xml b/spring-batch-test/pom.xml index 3ef0d3c956..2d5e318aae 100644 --- a/spring-batch-test/pom.xml +++ b/spring-batch-test/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.5 + 5.0.6-SNAPSHOT spring-batch-test Spring Batch Test From c70d40dc2616b8a9dba9abad28db8e767745b71a Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Thu, 7 Mar 2024 10:51:36 +0100 Subject: [PATCH 50/68] Update deprecated code that uses StepExecutionListenerSupport Backported from 376d84888fea9d021676d627a55d51c1d89fc3c1 Issue #4538 --- spring-batch-docs/src/main/asciidoc/step.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-batch-docs/src/main/asciidoc/step.adoc b/spring-batch-docs/src/main/asciidoc/step.adoc index 9825377c7f..d6bed21d52 100644 --- a/spring-batch-docs/src/main/asciidoc/step.adoc +++ b/spring-batch-docs/src/main/asciidoc/step.adoc @@ -1689,14 +1689,14 @@ the condition of the execution having skipped records, as the following example [source, java] ---- -public class SkipCheckingListener extends StepExecutionListenerSupport { +public class SkipCheckingListener implements StepExecutionListener { + @Override public ExitStatus afterStep(StepExecution stepExecution) { String exitCode = stepExecution.getExitStatus().getExitCode(); if (!exitCode.equals(ExitStatus.FAILED.getExitCode()) && - stepExecution.getSkipCount() > 0) { + stepExecution.getSkipCount() > 0) { return new ExitStatus("COMPLETED WITH SKIPS"); - } - else { + } else { return null; } } From 8ca9c6e35b8dbd9f8c66f073c0c84d6b5cd1302e Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Fri, 8 Mar 2024 20:25:49 +0100 Subject: [PATCH 51/68] Fix incorrect code example in documentation Backported from 6334fbf870a4a3b9b18bf792268861bbe87f471c Issue #4550 --- spring-batch-docs/src/main/asciidoc/step.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-batch-docs/src/main/asciidoc/step.adoc b/spring-batch-docs/src/main/asciidoc/step.adoc index d6bed21d52..50abb6de78 100644 --- a/spring-batch-docs/src/main/asciidoc/step.adoc +++ b/spring-batch-docs/src/main/asciidoc/step.adoc @@ -1373,7 +1373,7 @@ public class FileDeletingTasklet implements Tasklet, InitializingBean { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { File dir = directory.getFile(); - Assert.state(dir.isDirectory()); + Assert.state(dir.isDirectory(), "The resource must be a directory"); File[] files = dir.listFiles(); for (int i = 0; i < files.length; i++) { @@ -1391,7 +1391,7 @@ public class FileDeletingTasklet implements Tasklet, InitializingBean { } public void afterPropertiesSet() throws Exception { - Assert.state(directory != null, "directory must be set"); + Assert.state(directory != null, "Directory must be set"); } } ---- From f56a21c0c634211b618d5415a40218b2853e9b36 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Mon, 11 Mar 2024 17:00:40 +0100 Subject: [PATCH 52/68] Fix misleading documentation regarding the ItemWriteListener Backported from e78539191506c0d4e4fe5d5cc867beeabfa75c9c Issue #4400 --- spring-batch-docs/src/main/asciidoc/step.adoc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spring-batch-docs/src/main/asciidoc/step.adoc b/spring-batch-docs/src/main/asciidoc/step.adoc index 50abb6de78..4c746bffe7 100644 --- a/spring-batch-docs/src/main/asciidoc/step.adoc +++ b/spring-batch-docs/src/main/asciidoc/step.adoc @@ -1184,9 +1184,10 @@ public interface ItemWriteListener extends StepListener { ---- The `beforeWrite` method is called before `write` on the `ItemWriter` and is handed the -list of items that is written. The `afterWrite` method is called after the item has been -successfully written. If there was an error while writing, the `onWriteError` method is -called. The exception encountered and the item that was attempted to be written are +list of items that is written. The `afterWrite` method is called after the items have been +successfully written, but before committing the transaction associated with the chunk's processing. +If there was an error while writing, the `onWriteError` method is called. +The exception encountered and the item that was attempted to be written are provided, so that they can be logged. The annotations corresponding to this interface are: From b3cc665ad3080b1fa5134d5937f7b2054fabb02f Mon Sep 17 00:00:00 2001 From: Mustafa Yanar Date: Mon, 4 Mar 2024 22:07:58 +0300 Subject: [PATCH 53/68] Fix output chunk end property in ChunkProcessor implementations Resolves #4560 --- .../step/item/FaultTolerantChunkProcessor.java | 6 ++++-- .../batch/core/step/item/SimpleChunkProcessor.java | 5 ++++- .../item/FaultTolerantChunkProcessorTests.java | 13 ++++++++++++- .../core/step/item/SimpleChunkProcessorTests.java | 14 +++++++++++++- .../java/org/springframework/batch/item/Chunk.java | 9 ++++++++- 5 files changed, 41 insertions(+), 6 deletions(-) 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 f1eb7321f5..ecb797111c 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 @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 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. @@ -306,7 +306,9 @@ else if (shouldSkip(itemProcessSkipPolicy, e, contribution.getStepSkipCount())) break; } } - + if (inputs.isEnd()) { + outputs.setEnd(); + } return outputs; } 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 813b6eb403..101945bb22 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 @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2024 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. @@ -340,6 +340,9 @@ protected Chunk transform(StepContribution contribution, Chunk inputs) thr iterator.remove(); } } + if (inputs.isEnd()) { + outputs.setEnd(); + } return outputs; } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessorTests.java index 5070b277a4..d30e06917e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 the original author or authors. + * Copyright 2008-2024 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. @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import java.util.ArrayList; @@ -97,6 +98,16 @@ public String process(String item) throws Exception { assertEquals(1, contribution.getFilterCount()); } + @Test + void testTransformChunkEnd() throws Exception { + Chunk inputs = new Chunk<>(Arrays.asList("1", "2")); + inputs.setEnd(); + processor.initializeUserData(inputs); + Chunk outputs = processor.transform(contribution, inputs); + assertEquals(Arrays.asList("1", "2"), outputs.getItems()); + assertTrue(outputs.isEnd()); + } + @Test void testFilterCountOnSkip() throws Exception { processor.setProcessSkipPolicy(new AlwaysSkipItemSkipPolicy()); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleChunkProcessorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleChunkProcessorTests.java index e9a7e0e678..5ebcb49ced 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleChunkProcessorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleChunkProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 the original author or authors. + * Copyright 2008-2024 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. @@ -16,6 +16,7 @@ package org.springframework.batch.core.step.item; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.Arrays; @@ -76,4 +77,15 @@ void testProcess() throws Exception { assertEquals(2, contribution.getWriteCount()); } + @Test + void testTransform() throws Exception { + Chunk inputs = new Chunk<>(); + inputs.add("foo"); + inputs.add("bar"); + inputs.setEnd(); + Chunk outputs = processor.transform(contribution, inputs); + assertEquals(Arrays.asList("foo", "bar"), outputs.getItems()); + assertTrue(outputs.isEnd()); + } + } 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 4cdfa1c7e6..aababa36c2 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 @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 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. @@ -154,6 +154,13 @@ public int size() { /** * Flag to indicate if the source data is exhausted. + * + *

    + * Note: This may return false if the last chunk has the same number of items as the + * configured commit interval. Consequently, in such cases,there will be a last empty + * chunk that won't be processed. It is recommended to consider this behavior when + * utilizing this method. + *

    * @return true if there is no more data to process */ public boolean isEnd() { From d5c92c6bb78303feaddf159d940caf0badd9a90c Mon Sep 17 00:00:00 2001 From: injae-kim Date: Wed, 13 Mar 2024 01:10:12 +0900 Subject: [PATCH 54/68] Fix SystemCommandTasklet to propagate error when exit status is failed Fixes #4483 --- .../core/step/tasklet/SystemCommandTasklet.java | 14 +++++++++++--- .../SystemCommandTaskletIntegrationTests.java | 7 +++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/SystemCommandTasklet.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/SystemCommandTasklet.java index b35a228a4d..4499279e8e 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/SystemCommandTasklet.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/SystemCommandTasklet.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 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. @@ -60,6 +60,7 @@ * @author Robert Kasanicky * @author Will Schipp * @author Mahmoud Ben Hassine + * @author Injae Kim */ public class SystemCommandTasklet implements StepExecutionListener, StoppableTasklet, InitializingBean { @@ -121,8 +122,15 @@ public RepeatStatus execute(StepContribution contribution, ChunkContext chunkCon } if (systemCommandTask.isDone()) { - contribution.setExitStatus(systemProcessExitCodeMapper.getExitStatus(systemCommandTask.get())); - return RepeatStatus.FINISHED; + Integer exitCode = systemCommandTask.get(); + ExitStatus exitStatus = systemProcessExitCodeMapper.getExitStatus(exitCode); + contribution.setExitStatus(exitStatus); + if (ExitStatus.FAILED.equals(exitStatus)) { + throw new SystemCommandException("Execution of system command failed with exit code " + exitCode); + } + else { + return RepeatStatus.FINISHED; + } } else if (System.currentTimeMillis() - t0 > timeout) { systemCommandTask.cancel(interruptOnCancel); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java index 006d9ed877..b703d91ee3 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/SystemCommandTaskletIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 the original author or authors. + * Copyright 2008-2024 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. @@ -323,9 +323,8 @@ public void testExecuteWithFailedCommandRunnerMockExecution() throws Exception { tasklet.setCommand(command); tasklet.afterPropertiesSet(); - RepeatStatus exitStatus = tasklet.execute(stepContribution, null); - - assertEquals(RepeatStatus.FINISHED, exitStatus); + Exception exception = assertThrows(SystemCommandException.class, () -> tasklet.execute(stepContribution, null)); + assertTrue(exception.getMessage().contains("failed with exit code")); assertEquals(ExitStatus.FAILED, stepContribution.getExitStatus()); } From a8472cba18eba96aacf55e6c91a4bad1991d1ed6 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Mon, 25 Mar 2024 11:26:51 +0100 Subject: [PATCH 55/68] Add native runtime hints for remote partitioning types Resolves #4564 --- .../integration/aot/IntegrationRuntimeHints.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/aot/IntegrationRuntimeHints.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/aot/IntegrationRuntimeHints.java index 72674495fb..5f42caf800 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/aot/IntegrationRuntimeHints.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/aot/IntegrationRuntimeHints.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 the original author or authors. + * Copyright 2023-2024 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,6 +20,9 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.batch.integration.chunk.ChunkRequest; import org.springframework.batch.integration.chunk.ChunkResponse; +import org.springframework.batch.integration.partition.MessageChannelPartitionHandler; +import org.springframework.batch.integration.partition.StepExecutionRequest; +import org.springframework.batch.integration.partition.StepExecutionRequestHandler; /** * AOT hints for Spring Batch integration module. @@ -32,12 +35,16 @@ public class IntegrationRuntimeHints implements RuntimeHintsRegistrar { @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { // reflection hints - hints.reflection().registerType(ChunkRequest.class, MemberCategory.values()); - hints.reflection().registerType(ChunkResponse.class, MemberCategory.values()); + MemberCategory[] memberCategories = MemberCategory.values(); + hints.reflection().registerType(ChunkRequest.class, memberCategories); + hints.reflection().registerType(ChunkResponse.class, memberCategories); + hints.reflection().registerType(StepExecutionRequestHandler.class, memberCategories); + hints.reflection().registerType(MessageChannelPartitionHandler.class, memberCategories); // serialization hints hints.serialization().registerType(ChunkRequest.class); hints.serialization().registerType(ChunkResponse.class); + hints.serialization().registerType(StepExecutionRequest.class); } } From 5aa4deba200f5dc1b4443eabf321150859dc85ba Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 17 Apr 2024 14:59:45 +0200 Subject: [PATCH 56/68] Upgrade Spring dependencies to latest snapshots --- pom.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index bbf785b14d..6777b78eca 100644 --- a/pom.xml +++ b/pom.xml @@ -61,18 +61,18 @@ 17 - 6.0.17 - 2.0.5 - 6.0.9 - 1.10.13 + 6.0.20-SNAPSHOT + 2.0.6-SNAPSHOT + 6.0.10-SNAPSHOT + 1.10.14-SNAPSHOT - 3.0.12 - 3.0.12 - 4.0.12 - 3.0.14 - 3.0.11 - 3.0.6 + 3.0.13-SNAPSHOT + 3.0.13-SNAPSHOT + 4.0.13-SNAPSHOT + 3.0.16-SNAPSHOT + 3.0.14-SNAPSHOT + 3.0.7-SNAPSHOT 2.14.3 1.9.2 @@ -91,7 +91,7 @@ 3.0.2 - 1.1.10 + 1.1.12-SNAPSHOT 1.4.20 4.13.2 From 929a5514421eef7c4a388dfde3dd13284e8c82c7 Mon Sep 17 00:00:00 2001 From: Henning Poettker Date: Thu, 28 Dec 2023 02:12:11 +0100 Subject: [PATCH 57/68] Fix SimpleBinaryBufferedReaderFactory for longer endings Resolves #811 --- .../SimpleBinaryBufferedReaderFactory.java | 19 ++++++++------- ...impleBinaryBufferedReaderFactoryTests.java | 23 +++++++++++++++---- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactory.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactory.java index 098ff06eb5..2ec50d2dc8 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactory.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 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. @@ -114,25 +114,24 @@ private boolean isEndOfLine(StringBuilder buffer, StringBuilder candidate, int n } char c = (char) next; - if (ending.charAt(0) == c || candidate.length() > 0) { + if (ending.charAt(0) == c || !candidate.isEmpty()) { candidate.append(c); } - - if (candidate.length() == 0) { + else { buffer.append(c); return false; } - boolean end = ending.equals(candidate.toString()); - if (end) { + if (ending.contentEquals(candidate)) { candidate.delete(0, candidate.length()); + return true; } - else if (candidate.length() >= ending.length()) { - buffer.append(candidate); - candidate.delete(0, candidate.length()); + while (!ending.startsWith(candidate.toString())) { + buffer.append(candidate.charAt(0)); + candidate.delete(0, 1); } - return end; + return false; } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactoryTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactoryTests.java index 0a814af5aa..202fcc6476 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactoryTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/SimpleBinaryBufferedReaderFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2024 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. @@ -21,6 +21,8 @@ import java.io.BufferedReader; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.core.io.ByteArrayResource; /** @@ -75,16 +77,27 @@ void testCreateWithLineEndingAtEnd() throws Exception { assertNull(reader.readLine()); } - @Test - void testCreateWithFalseLineEnding() throws Exception { + @ParameterizedTest + @ValueSource(strings = { "||", "|||" }) + void testCreateWithFalseLineEnding(String lineEnding) throws Exception { SimpleBinaryBufferedReaderFactory factory = new SimpleBinaryBufferedReaderFactory(); - factory.setLineEnding("||"); + factory.setLineEnding(lineEnding); @SuppressWarnings("resource") - BufferedReader reader = factory.create(new ByteArrayResource("a|b||".getBytes()), "UTF-8"); + BufferedReader reader = factory.create(new ByteArrayResource(("a|b" + lineEnding).getBytes()), "UTF-8"); assertEquals("a|b", reader.readLine()); assertNull(reader.readLine()); } + @Test + void testCreateWithFalseMixedCharacterLineEnding() throws Exception { + SimpleBinaryBufferedReaderFactory factory = new SimpleBinaryBufferedReaderFactory(); + factory.setLineEnding("#@"); + @SuppressWarnings("resource") + BufferedReader reader = factory.create(new ByteArrayResource(("a##@").getBytes()), "UTF-8"); + assertEquals("a#", reader.readLine()); + assertNull(reader.readLine()); + } + @Test void testCreateWithIncompleteLineEnding() throws Exception { SimpleBinaryBufferedReaderFactory factory = new SimpleBinaryBufferedReaderFactory(); From a1ce07e106b43343df38a1f0a6b56a311199a023 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Thu, 25 Apr 2024 10:59:17 +0200 Subject: [PATCH 58/68] Fix code sample that uses deprecated StepBuilderFactory Backported from b020da4766d306950cc6141a5eeb8fffcd60dd6b Issue #4582 --- spring-batch-docs/src/main/asciidoc/scalability.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-batch-docs/src/main/asciidoc/scalability.adoc b/spring-batch-docs/src/main/asciidoc/scalability.adoc index fc7dfa5886..6d8928fa24 100644 --- a/spring-batch-docs/src/main/asciidoc/scalability.adoc +++ b/spring-batch-docs/src/main/asciidoc/scalability.adoc @@ -338,8 +338,8 @@ configuration: [source, java, role="javaContent"] ---- @Bean -public Step step1Manager() { - return stepBuilderFactory.get("step1.manager") +public Step step1Manager(JobRepository jobRepository) { + return new StepBuilder("step1.manager", jobRepository) .partitioner("step1", partitioner()) .step(step1()) .gridSize(10) From 21ea4d403405ec1c6599aad7f8cf8a7f6ce54818 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Mon, 29 Apr 2024 16:03:03 +0200 Subject: [PATCH 59/68] Improve error messages in JobParametersBuilder Resolves #4581 --- .../batch/core/JobParametersBuilder.java | 16 ++++++++++++---- .../batch/core/JobParametersBuilderTests.java | 10 +++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParametersBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParametersBuilder.java index 3450f4894a..9727fa52a5 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/JobParametersBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/JobParametersBuilder.java @@ -105,6 +105,7 @@ public JobParametersBuilder addString(String key, @NonNull String parameter) { * @return a reference to this object. */ public JobParametersBuilder addString(String key, @NonNull 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; } @@ -128,6 +129,7 @@ public JobParametersBuilder addDate(String key, @NonNull Date parameter) { * @return a reference to this object. */ public JobParametersBuilder addDate(String key, @NonNull 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; } @@ -151,6 +153,7 @@ public JobParametersBuilder addLocalDate(String key, @NonNull LocalDate paramete * @return a reference to this object. */ public JobParametersBuilder addLocalDate(String key, @NonNull 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; } @@ -174,6 +177,7 @@ public JobParametersBuilder addLocalTime(String key, @NonNull LocalTime paramete * @return a reference to this object. */ public JobParametersBuilder addLocalTime(String key, @NonNull 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; } @@ -197,6 +201,7 @@ public JobParametersBuilder addLocalDateTime(String key, @NonNull LocalDateTime * @return a reference to this object. */ public JobParametersBuilder addLocalDateTime(String key, @NonNull 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; } @@ -220,6 +225,7 @@ public JobParametersBuilder addLong(String key, @NonNull Long parameter) { * @return a reference to this object. */ public JobParametersBuilder addLong(String key, @NonNull 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; } @@ -243,6 +249,7 @@ public JobParametersBuilder addDouble(String key, @NonNull Double parameter) { * @return a reference to this object. */ public JobParametersBuilder addDouble(String key, @NonNull 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; } @@ -285,27 +292,28 @@ public JobParametersBuilder addJobParameter(String key, JobParameter jobParam /** * Add a job parameter. * @param name the name of the parameter - * @param value the value of the parameter + * @param value the value of the parameter. Must not be {@code null}. * @param type the type of the parameter * @param identifying true if the parameter is identifying. false otherwise * @return a reference to this object. * @param the type of the parameter * @since 5.0 */ - public JobParametersBuilder addJobParameter(String name, T value, Class type, boolean identifying) { + public JobParametersBuilder addJobParameter(String name, @NonNull 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)); } /** * Add an identifying job parameter. * @param name the name of the parameter - * @param value the value of the parameter + * @param value the value of the parameter. Must not be {@code null}. * @param type the type of the parameter * @return a reference to this object. * @param the type of the parameter * @since 5.0 */ - public JobParametersBuilder addJobParameter(String name, T value, Class type) { + public JobParametersBuilder addJobParameter(String name, @NonNull T value, Class type) { return addJobParameter(name, value, type, true); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java index 2f5cdb5d6e..220dfc4724 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/JobParametersBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 the original author or authors. + * Copyright 2008-2024 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. @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Set; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -85,6 +86,13 @@ void testAddingExistingJobParameters() { assertEquals(finalParams.getString("baz"), "quix"); } + @Test + void testAddingNullJobParameters() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> new JobParametersBuilder().addString("foo", null).toJobParameters()); + Assertions.assertEquals("Value for parameter 'foo' must not be null", exception.getMessage()); + } + @Test void testNonIdentifyingParameters() { this.parametersBuilder.addDate("SCHEDULE_DATE", date, false); From a5ed687908069d853cdc1e98799e0af9029538db Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Mon, 13 May 2024 10:55:16 +0200 Subject: [PATCH 60/68] Fix typo in job.adoc Cherry-picked from b06f90a8995a26907bf81ad7748deaed305604c0 Issue #4591 --- spring-batch-docs/src/main/asciidoc/job.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-batch-docs/src/main/asciidoc/job.adoc b/spring-batch-docs/src/main/asciidoc/job.adoc index 94f3aab23c..91049567d7 100644 --- a/spring-batch-docs/src/main/asciidoc/job.adoc +++ b/spring-batch-docs/src/main/asciidoc/job.adoc @@ -449,6 +449,7 @@ public class MyJobConfiguration { return new JdbcTransactionManager(dataSource); } + @Bean public Job job(JobRepository jobRepository) { return new JobBuilder("myJob", jobRepository) //define job flow as needed From 1710c1332ded8c0e3535f55af057e0a99fa0e04e Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Tue, 14 May 2024 10:31:56 +0200 Subject: [PATCH 61/68] Fix command syntax in documentation deployment scripts --- .github/workflows/continuous-integration-50x.yml | 4 ++-- .github/workflows/documentation-upload.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/continuous-integration-50x.yml b/.github/workflows/continuous-integration-50x.yml index 4f4f8d0421..7026fb034a 100644 --- a/.github/workflows/continuous-integration-50x.yml +++ b/.github/workflows/continuous-integration-50x.yml @@ -55,7 +55,7 @@ jobs: working-directory: spring-batch-docs/target run: | unzip spring-batch-$PROJECT_VERSION-docs.zip - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir -p $PROJECT_VERSION/api + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $PROJECT_VERSION/api" scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION/api scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && ln -s $PROJECT_VERSION 5.0.x-SNAPSHOT + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && ln -s $PROJECT_VERSION 5.0.x-SNAPSHOT" diff --git a/.github/workflows/documentation-upload.yml b/.github/workflows/documentation-upload.yml index fb2dba83c0..9500f4926e 100644 --- a/.github/workflows/documentation-upload.yml +++ b/.github/workflows/documentation-upload.yml @@ -57,10 +57,10 @@ jobs: working-directory: spring-batch-docs/target run: | unzip spring-batch-$RELEASE_VERSION-docs.zip - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && mkdir -p $RELEASE_VERSION/api + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $RELEASE_VERSION/api" scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION/api scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST cd $DOCS_PATH && ln -s $RELEASE_VERSION 5.0.x + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && ln -s $RELEASE_VERSION 5.0.x" unzip spring-batch-$RELEASE_VERSION-schemas.zip scp -i $HOME/.ssh/key batch/*.xsd $DOCS_USERNAME@$DOCS_HOST:$BATCH_SCHEMA_PATH From 46b09da192f8bc241751c879f8c0f8d219ec0b73 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Tue, 14 May 2024 13:27:45 +0200 Subject: [PATCH 62/68] Update dependencies --- pom.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 6777b78eca..13575fb3f6 100644 --- a/pom.xml +++ b/pom.xml @@ -79,11 +79,11 @@ 2.9.1 6.1.7.Final 2.1.1 - 2.1.2 + 2.1.3 3.1.0 3.0.2 3.1.0 - 4.0.9 + 4.0.10 4.9.1 5.9.3 @@ -91,7 +91,7 @@ 3.0.2 - 1.1.12-SNAPSHOT + 1.1.13-SNAPSHOT 1.4.20 4.13.2 @@ -102,31 +102,31 @@ 2.9.1 2.15.1 2.11.0 - 2.0.12 + 2.0.13 2.7.2 2.2.224 3.44.1.0 10.16.1.1 2.18.16 2.31.2 - 4.0.4 + 4.0.5 2.22.1 8.0.1.Final 5.0.1 4.0.2 2.0.1 4.0.1 - 2.0.2 + 2.0.3 6.5.1 - 1.9.21.1 + 1.9.21.2 8.3.0 - 3.3.2 - 42.7.2 + 3.3.3 + 42.7.3 11.5.9.0 19.22.0.0 11.2.3.jre17 1.3.1 - 1.19.5 + 1.19.8 1.5.1 From 0525fc6c01d0d8299684eb7d98a80d1142bc9314 Mon Sep 17 00:00:00 2001 From: Henning Poettker Date: Sun, 19 May 2024 19:29:31 +0200 Subject: [PATCH 63/68] Keep heap lean during remote partition polling Resolves #4598 --- .../MessageChannelPartitionHandler.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) 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 9b16964100..be541b880f 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 @@ -1,5 +1,5 @@ /* - * Copyright 2009-2023 the original author or authors. + * Copyright 2009-2024 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. @@ -251,24 +251,22 @@ protected Set doHandle(StepExecution managerStepExecution, private Set pollReplies(final StepExecution managerStepExecution, final Set split) throws Exception { - final Set result = new HashSet<>(split.size()); + Set partitionStepExecutionIds = split.stream().map(StepExecution::getId).collect(Collectors.toSet()); Callable> callback = () -> { - Set currentStepExecutionIds = split.stream().map(StepExecution::getId).collect(Collectors.toSet()); JobExecution jobExecution = jobExplorer.getJobExecution(managerStepExecution.getJobExecutionId()); - jobExecution.getStepExecutions() + Set finishedStepExecutions = jobExecution.getStepExecutions() .stream() - .filter(stepExecution -> currentStepExecutionIds.contains(stepExecution.getId())) - .filter(stepExecution -> !result.contains(stepExecution)) + .filter(stepExecution -> partitionStepExecutionIds.contains(stepExecution.getId())) .filter(stepExecution -> !stepExecution.getStatus().isRunning()) - .forEach(result::add); + .collect(Collectors.toSet()); if (logger.isDebugEnabled()) { logger.debug(String.format("Currently waiting on %s partitions to finish", split.size())); } - if (result.size() == split.size()) { - return result; + if (finishedStepExecutions.size() == split.size()) { + return finishedStepExecutions; } else { return null; From 1ceafd8d27539c6c4b466e459bd900de08fe3a35 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 22 May 2024 08:29:48 +0200 Subject: [PATCH 64/68] Update documentation deployment scripts --- .github/workflows/continuous-integration-50x.yml | 2 +- .github/workflows/documentation-upload.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous-integration-50x.yml b/.github/workflows/continuous-integration-50x.yml index 7026fb034a..37c47ac672 100644 --- a/.github/workflows/continuous-integration-50x.yml +++ b/.github/workflows/continuous-integration-50x.yml @@ -58,4 +58,4 @@ jobs: ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $PROJECT_VERSION/api" scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION/api scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && ln -s $PROJECT_VERSION 5.0.x-SNAPSHOT" + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && rm 5.0.x-SNAPSHOT && ln -s $PROJECT_VERSION 5.0.x-SNAPSHOT" diff --git a/.github/workflows/documentation-upload.yml b/.github/workflows/documentation-upload.yml index 9500f4926e..bb2942f7b3 100644 --- a/.github/workflows/documentation-upload.yml +++ b/.github/workflows/documentation-upload.yml @@ -60,7 +60,7 @@ jobs: ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $RELEASE_VERSION/api" scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION/api scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && ln -s $RELEASE_VERSION 5.0.x" + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && rm 5.0.x && ln -s $RELEASE_VERSION 5.0.x" unzip spring-batch-$RELEASE_VERSION-schemas.zip scp -i $HOME/.ssh/key batch/*.xsd $DOCS_USERNAME@$DOCS_HOST:$BATCH_SCHEMA_PATH From 9813115a56ea5bf442c02333a8c22bd3b49fd01b Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 22 May 2024 08:57:45 +0200 Subject: [PATCH 65/68] Prepare release 5.0.6 --- pom.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 13575fb3f6..d60363e113 100644 --- a/pom.xml +++ b/pom.xml @@ -61,18 +61,18 @@ 17 - 6.0.20-SNAPSHOT - 2.0.6-SNAPSHOT - 6.0.10-SNAPSHOT - 1.10.14-SNAPSHOT + 6.0.20 + 2.0.6 + 6.0.9 + 1.10.13 - 3.0.13-SNAPSHOT - 3.0.13-SNAPSHOT - 4.0.13-SNAPSHOT - 3.0.16-SNAPSHOT - 3.0.14-SNAPSHOT - 3.0.7-SNAPSHOT + 3.0.12 + 3.0.12 + 4.0.12 + 3.0.17 + 3.0.14 + 3.0.6 2.14.3 1.9.2 @@ -91,7 +91,7 @@ 3.0.2 - 1.1.13-SNAPSHOT + 1.1.13 1.4.20 4.13.2 From a79e42f6d8ae127df3b33d0e3a142908407097ba Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 22 May 2024 09:46:09 +0200 Subject: [PATCH 66/68] Release version 5.0.6 --- pom.xml | 2 +- spring-batch-bom/pom.xml | 2 +- spring-batch-core/pom.xml | 2 +- spring-batch-docs/pom.xml | 2 +- spring-batch-infrastructure/pom.xml | 2 +- spring-batch-integration/pom.xml | 2 +- spring-batch-samples/pom.xml | 2 +- spring-batch-test/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index d60363e113..ebb7841050 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. Spring Batch is part of the Spring Portfolio. - 5.0.6-SNAPSHOT + 5.0.6 pom https://projects.spring.io/spring-batch diff --git a/spring-batch-bom/pom.xml b/spring-batch-bom/pom.xml index 6621731259..ece8c963e4 100644 --- a/spring-batch-bom/pom.xml +++ b/spring-batch-bom/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6-SNAPSHOT + 5.0.6 spring-batch-bom pom diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index ca2de1b20f..745ad4d714 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6-SNAPSHOT + 5.0.6 spring-batch-core jar diff --git a/spring-batch-docs/pom.xml b/spring-batch-docs/pom.xml index 91c4431ef9..c5d8ffb50a 100644 --- a/spring-batch-docs/pom.xml +++ b/spring-batch-docs/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6-SNAPSHOT + 5.0.6 spring-batch-docs Spring Batch Docs diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index 06417664b0..ffc7ff368d 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6-SNAPSHOT + 5.0.6 spring-batch-infrastructure jar diff --git a/spring-batch-integration/pom.xml b/spring-batch-integration/pom.xml index 4ffec5faaf..2694f80a0e 100644 --- a/spring-batch-integration/pom.xml +++ b/spring-batch-integration/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6-SNAPSHOT + 5.0.6 spring-batch-integration Spring Batch Integration diff --git a/spring-batch-samples/pom.xml b/spring-batch-samples/pom.xml index 4af54a5686..15bc3b9141 100644 --- a/spring-batch-samples/pom.xml +++ b/spring-batch-samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6-SNAPSHOT + 5.0.6 spring-batch-samples jar diff --git a/spring-batch-test/pom.xml b/spring-batch-test/pom.xml index 2d5e318aae..f704975375 100644 --- a/spring-batch-test/pom.xml +++ b/spring-batch-test/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6-SNAPSHOT + 5.0.6 spring-batch-test Spring Batch Test From 0e40e6e4b3a319639e1ad4bdb0343ebed46ccee8 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 22 May 2024 09:46:42 +0200 Subject: [PATCH 67/68] Next development version --- pom.xml | 2 +- spring-batch-bom/pom.xml | 2 +- spring-batch-core/pom.xml | 2 +- spring-batch-docs/pom.xml | 2 +- spring-batch-infrastructure/pom.xml | 2 +- spring-batch-integration/pom.xml | 2 +- spring-batch-samples/pom.xml | 2 +- spring-batch-test/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index ebb7841050..66915893eb 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. Spring Batch is part of the Spring Portfolio. - 5.0.6 + 5.0.7-SNAPSHOT pom https://projects.spring.io/spring-batch diff --git a/spring-batch-bom/pom.xml b/spring-batch-bom/pom.xml index ece8c963e4..91accf3644 100644 --- a/spring-batch-bom/pom.xml +++ b/spring-batch-bom/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6 + 5.0.7-SNAPSHOT spring-batch-bom pom diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml index 745ad4d714..124f3008eb 100644 --- a/spring-batch-core/pom.xml +++ b/spring-batch-core/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6 + 5.0.7-SNAPSHOT spring-batch-core jar diff --git a/spring-batch-docs/pom.xml b/spring-batch-docs/pom.xml index c5d8ffb50a..a437241444 100644 --- a/spring-batch-docs/pom.xml +++ b/spring-batch-docs/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6 + 5.0.7-SNAPSHOT spring-batch-docs Spring Batch Docs diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index ffc7ff368d..3dc7b43bb2 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6 + 5.0.7-SNAPSHOT spring-batch-infrastructure jar diff --git a/spring-batch-integration/pom.xml b/spring-batch-integration/pom.xml index 2694f80a0e..370bd162b2 100644 --- a/spring-batch-integration/pom.xml +++ b/spring-batch-integration/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6 + 5.0.7-SNAPSHOT spring-batch-integration Spring Batch Integration diff --git a/spring-batch-samples/pom.xml b/spring-batch-samples/pom.xml index 15bc3b9141..05f2686e86 100644 --- a/spring-batch-samples/pom.xml +++ b/spring-batch-samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6 + 5.0.7-SNAPSHOT spring-batch-samples jar diff --git a/spring-batch-test/pom.xml b/spring-batch-test/pom.xml index f704975375..da125fcf43 100644 --- a/spring-batch-test/pom.xml +++ b/spring-batch-test/pom.xml @@ -4,7 +4,7 @@ org.springframework.batch spring-batch - 5.0.6 + 5.0.7-SNAPSHOT spring-batch-test Spring Batch Test From 0f32ff42326a059fe576c9655899e5344c248030 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 29 May 2024 10:33:24 +0200 Subject: [PATCH 68/68] Fix javadocs deployment path --- .github/workflows/continuous-integration-50x.yml | 4 ++-- .github/workflows/documentation-upload.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/continuous-integration-50x.yml b/.github/workflows/continuous-integration-50x.yml index 37c47ac672..9744e02581 100644 --- a/.github/workflows/continuous-integration-50x.yml +++ b/.github/workflows/continuous-integration-50x.yml @@ -55,7 +55,7 @@ jobs: working-directory: spring-batch-docs/target run: | unzip spring-batch-$PROJECT_VERSION-docs.zip - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $PROJECT_VERSION/api" - scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION/api + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $PROJECT_VERSION" + scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$PROJECT_VERSION ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && rm 5.0.x-SNAPSHOT && ln -s $PROJECT_VERSION 5.0.x-SNAPSHOT" diff --git a/.github/workflows/documentation-upload.yml b/.github/workflows/documentation-upload.yml index bb2942f7b3..9ec72c93ed 100644 --- a/.github/workflows/documentation-upload.yml +++ b/.github/workflows/documentation-upload.yml @@ -57,8 +57,8 @@ jobs: working-directory: spring-batch-docs/target run: | unzip spring-batch-$RELEASE_VERSION-docs.zip - ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $RELEASE_VERSION/api" - scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION/api + ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && mkdir -p $RELEASE_VERSION" + scp -i $HOME/.ssh/key -r api $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION scp -i $HOME/.ssh/key -r reference $DOCS_USERNAME@$DOCS_HOST:$DOCS_PATH/$RELEASE_VERSION ssh -i $HOME/.ssh/key $DOCS_USERNAME@$DOCS_HOST "cd $DOCS_PATH && rm 5.0.x && ln -s $RELEASE_VERSION 5.0.x"