diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/DefaultExecutionContextSerializer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/DefaultExecutionContextSerializer.java index 5569bce038..8493127de4 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/DefaultExecutionContextSerializer.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/DefaultExecutionContextSerializer.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. @@ -15,16 +15,18 @@ */ package org.springframework.batch.core.repository.dao; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; +import java.util.Base64; import java.util.Map; import org.springframework.batch.core.repository.ExecutionContextSerializer; import org.springframework.util.Assert; -import org.springframework.util.Base64Utils; -import org.springframework.util.SerializationUtils; /** * An implementation of the {@link ExecutionContextSerializer} that produces/consumes @@ -34,7 +36,6 @@ * @author Mahmoud Ben Hassine * @since 2.2 */ -@SuppressWarnings("rawtypes") public class DefaultExecutionContextSerializer implements ExecutionContextSerializer { /** @@ -45,7 +46,6 @@ public class DefaultExecutionContextSerializer implements ExecutionContextSerial * written. */ @Override - @SuppressWarnings("unchecked") public void serialize(Map context, OutputStream out) throws IOException { Assert.notNull(context, "context is required"); Assert.notNull(out, "OutputStream is required"); @@ -58,9 +58,12 @@ public void serialize(Map context, OutputStream out) throws IOEx + value.getClass().getName() + "] must be an instance of " + Serializable.class); } } - byte[] serializedContext = SerializationUtils.serialize(context); - String base64EncodedContext = Base64Utils.encodeToString(serializedContext); - out.write(base64EncodedContext.getBytes()); + var byteArrayOutputStream = new ByteArrayOutputStream(1024); + var encodingStream = Base64.getEncoder().wrap(byteArrayOutputStream); + try (var objectOutputStream = new ObjectOutputStream(encodingStream)) { + objectOutputStream.writeObject(context); + } + out.write(byteArrayOutputStream.toByteArray()); } /** @@ -72,10 +75,17 @@ public void serialize(Map context, OutputStream out) throws IOEx @SuppressWarnings("unchecked") @Override public Map deserialize(InputStream inputStream) throws IOException { - String base64EncodedContext = new String(inputStream.readAllBytes()); - byte[] decodedContext = Base64Utils.decodeFromString(base64EncodedContext); - // FIXME use replacement of the following SerializationUtils.deserialize - return (Map) SerializationUtils.deserialize(decodedContext); + var decodingStream = Base64.getDecoder().wrap(inputStream); + try { + var objectInputStream = new ObjectInputStream(decodingStream); + return (Map) objectInputStream.readObject(); + } + catch (IOException ex) { + throw new IllegalArgumentException("Failed to deserialize object", ex); + } + catch (ClassNotFoundException ex) { + throw new IllegalStateException("Failed to deserialize object type", ex); + } } } 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 116b122cb0..948b144712 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 @@ -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. @@ -16,7 +16,6 @@ package org.springframework.batch.core.step.job; import java.util.Arrays; -import java.util.Date; import java.util.HashSet; import java.util.Map; import java.util.Properties; @@ -72,7 +71,7 @@ public JobParameters getJobParameters(Job job, StepExecution stepExecution) { ExecutionContext executionContext = stepExecution.getExecutionContext(); if (useAllParentParameters) { for (String key : jobParameters.keySet()) { - builder.addParameter(key, jobParameters.get(key)); + builder.addJobParameter(key, jobParameters.get(key)); } } Properties properties = new Properties(); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/PartitionStepParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/PartitionStepParserTests.java index 3790b31339..254d7ad922 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/PartitionStepParserTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/PartitionStepParserTests.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. @@ -45,7 +45,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; -import org.springframework.util.ReflectionUtils; /** * @author Dave Syer @@ -97,13 +96,10 @@ void setUp() { } @SuppressWarnings("unchecked") - private T accessPrivateField(Object o, String fieldName) { - Field field = ReflectionUtils.findField(o.getClass(), fieldName); - boolean previouslyAccessibleValue = field.isAccessible(); + private T accessPrivateField(Object o, String fieldName) throws ReflectiveOperationException { + Field field = o.getClass().getDeclaredField(fieldName); field.setAccessible(true); - T val = (T) ReflectionUtils.getField(field, o); - field.setAccessible(previouslyAccessibleValue); - return val; + return (T) field.get(o); } @Test diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/concurrent/ConcurrentTransactionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/concurrent/ConcurrentTransactionTests.java index bd15e60589..e6e2fce644 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/concurrent/ConcurrentTransactionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/concurrent/ConcurrentTransactionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2022 the original author or authors. + * Copyright 2015-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. @@ -48,7 +48,6 @@ import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.core.task.SyncTaskExecutor; import org.springframework.core.task.TaskExecutor; import org.springframework.jdbc.datasource.embedded.ConnectionProperties; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseConfigurer; @@ -109,7 +108,7 @@ public RepeatStatus execute(StepContribution contribution, ChunkContext chunkCon return RepeatStatus.FINISHED; } }, transactionManager).build()) - .next(new StepBuilder("flow.step2").repository(jobRepository).tasklet(new Tasklet() { + .next(new StepBuilder("flow.step2", jobRepository).tasklet(new Tasklet() { @Nullable @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxTestUtils.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxTestUtils.java index e4b62a9658..fdfef6f30d 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxTestUtils.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2018 the original author or authors. + * Copyright 2015-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. @@ -29,19 +29,15 @@ public final class StaxTestUtils { public static XMLEventWriter getXmlEventWriter(Result r) throws Exception { Method m = r.getClass().getDeclaredMethod("getXMLEventWriter"); - boolean accessible = m.isAccessible(); m.setAccessible(true); Object result = m.invoke(r); - m.setAccessible(accessible); return (XMLEventWriter) result; } public static XMLEventReader getXmlEventReader(Source s) throws Exception { Method m = s.getClass().getDeclaredMethod("getXMLEventReader"); - boolean accessible = m.isAccessible(); m.setAccessible(true); Object result = m.invoke(s); - m.setAccessible(accessible); return (XMLEventReader) result; } 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 79c27195ad..d1e98846f7 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 @@ -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. @@ -265,8 +265,8 @@ else if (count < items.size()) { } }; - TaskletStep taskletStep = new RemoteChunkingManagerStepBuilder("step").reader(itemReader) - .readerIsTransactionalQueue().processor(itemProcessor).repository(this.jobRepository) + TaskletStep taskletStep = new RemoteChunkingManagerStepBuilder("step", this.jobRepository) + .reader(itemReader).readerIsTransactionalQueue().processor(itemProcessor) .transactionManager(this.transactionManager).transactionAttribute(transactionAttribute) .inputChannel(this.inputChannel).outputChannel(this.outputChannel).listener(annotatedListener) .listener(skipListener).listener(chunkListener).listener(stepExecutionListener) diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/common/StagingItemReader.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/common/StagingItemReader.java index 3642ad14cd..0569db7112 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/common/StagingItemReader.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/common/StagingItemReader.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. @@ -16,6 +16,8 @@ package org.springframework.batch.sample.common; +import java.io.InputStream; +import java.io.ObjectInputStream; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Iterator; @@ -38,7 +40,6 @@ import org.springframework.jdbc.core.RowMapper; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.SerializationUtils; /** * Thread-safe database {@link ItemReader} implementing the process indicator pattern. @@ -117,17 +118,23 @@ public ProcessIndicatorItemWrapper read() { } @SuppressWarnings("unchecked") T result = (T) jdbcTemplate.queryForObject("SELECT VALUE FROM BATCH_STAGING WHERE ID=?", - new RowMapper() { - @Override - public Object mapRow(ResultSet rs, int rowNum) throws SQLException { - byte[] blob = rs.getBytes(1); - return SerializationUtils.deserialize(blob); - } - }, id); + (rs, rowNum) -> deserialize(rs.getBinaryStream(1)), id); return new ProcessIndicatorItemWrapper<>(id, result); } + private static Object deserialize(InputStream inputStream) { + if (inputStream == null) { + return null; + } + try (var objectInputStream = new ObjectInputStream(inputStream)) { + return objectInputStream.readObject(); + } + catch (Exception e) { + throw new IllegalArgumentException("Failed to deserialize object", e); + } + } + @Nullable @Override public ExitStatus afterStep(StepExecution stepExecution) {