Я переношу Spring Boot с 1.4.2 на 2.0.0, что также включает перенос пакета Spring с 3.0.7 на 4.0.0, и похоже, что пакетный процесс больше не работает, когда я пытаюсь запустить его с новой версией Spring Batch.
Когда я попытался отладить, я обнаружил проблему, когда пакет пытается получить данные из batch_job_execution_context.
Я вижу, что получение данных из базы данных работает нормально, но новая версия пакета не может анализировать данные базы данных.
{"map":[{"entry":[{"string":["name",""]},{"string":["sender",""]},{"string":["id",""]},{"string":["nav",""]},{"string":["created",140418]}]}]}
с этой ошибкой:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected VALUE_STRING: need JSON String that contains type id (for subtype of java.lang.Object) at [Source: (ByteArrayInputStream); line: 1, column: 9] (through reference chain: java.util.HashMap["map"])
Я обнаружил, что когда я удаляю все таблицы метаданных пакета и воссоздаю их с нуля, пакет снова работает. Похоже, формат метаданных JSON изменился на этот
{"name":"","sender":"145844","id":"","nav":"","created":"160909"}
Я не хочу удалять старые данные, чтобы снова заставить эту работу работать, есть ли способ исправить это?
Кто-нибудь еще пробовал сделать это обновление? Было бы неплохо узнать, есть ли какие-нибудь критические изменения, которые я, возможно, не заметил.
Спасибо
@MahmoudBenHassine Я уже пробовал это, но все равно получаю то же исключение Jackson MismatchedInputException.




До Spring Batch 4 механизм сериализации по умолчанию для ExecutionContext был через XStream. Теперь он по умолчанию использует Jackson, который нет совместим со старым форматом сериализации. У нас все еще доступна старая версия (XStreamExecutionContextStringSerializer), но вам нужно будет настроить ее самостоятельно, реализовав BatchConfigurer и переопределив конфигурацию в JobRepositoryFactoryBean.
Для записи, это связано с этой проблемой: https://jira.spring.io/browse/BATCH-2575.
Не могли бы вы и здесь ответить stackoverflow.com/questions/51688838/…?
Я не совсем понимаю ответ. Не могли бы вы вставить код, подтверждающий ваш ответ? Будучи новичком в Spring Batch, трудно понять, что вы говорите
Основываясь на ответе Майкла выше, этот блок кода помог мне расширить конфигурацию по умолчанию - мне пришлось подключить сериализатор как к JobRepository.class, так и к JobExplorer.class:
@Configuration
@EnableBatchProcessing
MyBatchConfigurer extends DefaultBatchConfigurer {
private final DataSource dataSource;
@Autowired
public BatchConfiguration(final DataSource dataSource) throws Exception {
this.dataSource = dataSource;
}
@Bean
ExecutionContextSerializer getSerializer() {
return new XStreamExecutionContextStringSerializer();
}
@Override
protected JobRepository createJobRepository() throws Exception {
final JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource);
factory.setSerializer(getSerializer());
factory.setTransactionManager(getTransactionManager());
factory.afterPropertiesSet();
return factory.getObject();
}
@Override
protected JobExplorer createJobExplorer() throws Exception {
final JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
jobExplorerFactoryBean.setDataSource(dataSource);
jobExplorerFactoryBean.setSerializer(getSerializer());
jobExplorerFactoryBean.afterPropertiesSet();
return jobExplorerFactoryBean.getObject();
}
}
очень полезно tnx. Но моя текущая конфигурация также включает публичный метод \ @Bean JobExecutionDao jobExecutionDao (). Я не могу изменить это с помощью DefaultBatchConfigurer. Любые идеи? не уверен, что могу оставить его как "фасоль" и не отменять
В решении @anotherdave и @ michael-minella вы также можете заменить простой XStreamExecutionContextStringSerializer экземпляром следующего класса. Он принимает оба формата при десериализации и сериализуется в новый формат.
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.batch.core.repository.ExecutionContextSerializer;
import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
import org.springframework.batch.core.repository.dao.XStreamExecutionContextStringSerializer;
/**
* Enables Spring Batch 4 to read both ExecutionContext entries written by ealier versions and the Spring 5 format. Entries are
* written in Spring 5 format.
*/
@SuppressWarnings("deprecation")
class XStreamOrJackson2ExecutionContextSerializer implements ExecutionContextSerializer {
private final XStreamExecutionContextStringSerializer xStream = new XStreamExecutionContextStringSerializer();
private final Jackson2ExecutionContextStringSerializer jackson = new Jackson2ExecutionContextStringSerializer();
public XStreamOrJackson2ExecutionContextSerializer() throws Exception {
xStream.afterPropertiesSet();
}
// The caller closes the stream; and the decoration by ensureMarkSupported does not need any cleanup.
@SuppressWarnings("resource")
@Override
public Map<String, Object> deserialize(InputStream inputStream) throws IOException {
InputStream repeatableInputStream = ensureMarkSupported(inputStream);
repeatableInputStream.mark(Integer.MAX_VALUE);
try {
return jackson.deserialize(repeatableInputStream);
} catch (JsonProcessingException e) {
repeatableInputStream.reset();
return xStream.deserialize(repeatableInputStream);
}
}
private static InputStream ensureMarkSupported(InputStream in) {
return in.markSupported() ? in : new BufferedInputStream(in);
}
@Override
public void serialize(Map<String, Object> object, OutputStream outputStream) throws IOException {
jackson.serialize(object, outputStream);
}
}
Вероятно, это связано с jira.spring.io/browse/BATCH-2680. Вы пробовали использовать Spring Batch версии 4.0.1?