升级到Spring Cloud Dataflow任务的Spring Boot 2.0后无法反序列化执行上下文

时间:2018-10-29 09:42:21

标签: java spring spring-boot spring-batch

我将Spring Boot(任务)应用程序从1.5更新为Spring Boot 2.0。现在,当我运行它时,出现一个可反序列化的错误。

2018-10-29 15:03:00.346 ERROR 713 --- [           main] o.s.boot.SpringApplication               : Application run failed

java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) [spring-boot-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776) [spring-boot-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242) [spring-boot-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230) [spring-boot-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
    at com.mediaiq.miq.batch.MiqBatchApplication.main(MiqBatchApplication.java:42) [classes!/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [aiq-miq-batch-2.18-SNAPSHOT.jar:na]
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [aiq-miq-batch-2.18-SNAPSHOT.jar:na]
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [aiq-miq-batch-2.18-SNAPSHOT.jar:na]
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [aiq-miq-batch-2.18-SNAPSHOT.jar:na]
Caused by: java.lang.IllegalArgumentException: Unable to deserialize the execution context
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:325) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:309) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:93) ~[spring-jdbc-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:60) ~[spring-jdbc-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:667) ~[spring-jdbc-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:605) ~[spring-jdbc-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:657) ~[spring-jdbc-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:688) ~[spring-jdbc-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700) ~[spring-jdbc-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:756) ~[spring-jdbc-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.getExecutionContext(JdbcExecutionContextDao.java:112) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
    at org.springframework.batch.core.explore.support.SimpleJobExplorer.getJobExecutionDependencies(SimpleJobExplorer.java:202) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
    at org.springframework.batch.core.explore.support.SimpleJobExplorer.getJobExecutions(SimpleJobExplorer.java:83) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197) ~[spring-aop-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
    at com.sun.proxy.$Proxy185.getJobExecutions(Unknown Source) ~[na:na]
    at org.springframework.batch.core.JobParametersBuilder.getNextJobParameters(JobParametersBuilder.java:264) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:162) ~[spring-boot-autoconfigure-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:179) ~[spring-boot-autoconfigure-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:134) ~[spring-boot-autoconfigure-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
    at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:128) ~[spring-boot-autoconfigure-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:792) [spring-boot-2.0.6.RELEASE.jar!/:2.0.6.RELEASE]
    ... 13 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id '' as a subtype of [simple type, class java.lang.Object]: no such class found
 at [Source: (ByteArrayInputStream); line: 1, column: 11] (through reference chain: java.util.HashMap["map"])
    at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.DeserializationContext.invalidTypeIdException(DeserializationContext.java:1635) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownTypeId(DeserializationContext.java:1187) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver._typeFromId(ClassNameIdResolver.java:53) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver.typeFromId(ClassNameIdResolver.java:44) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._findDeserializer(TypeDeserializerBase.java:156) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:97) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromAny(AsArrayTypeDeserializer.java:71) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserializeWithType(UntypedObjectDeserializer.java:712) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:529) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3077) ~[jackson-databind-2.9.7.jar!/:2.9.7]
    at org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer.deserialize(Jackson2ExecutionContextStringSerializer.java:70) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
    at org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer.deserialize(Jackson2ExecutionContextStringSerializer.java:50) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:322) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]

一个人建议: 当您的作业的执行上下文使用版本3序列化(默认情况下使用XStream),然后使用版本4进行反序列化(默认情况下使用Jackson)时,会发生此错误。因此,要么将Spring Batch降级到版本3,要么将您的作业存储库配置为使用XStreamExecutionContextStringSerializer。

在您的情况下,您已经定义了BatchConfigurer类型的bean,因此您可以覆盖createJobRepository方法并配置XStream序列化程序。例如:

@Bean
BatchConfigurer configurer(@Qualifier("dataSource") DataSource dataSource, PlatformTransactionManager transactionManager) {
    return new DefaultBatchConfigurer(dataSource) {
        @Override
        protected JobRepository createJobRepository() throws Exception {
            JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
            factory.setDataSource(dataSource);
            factory.setTransactionManager(transactionManager);
            factory.setSerializer(new XStreamExecutionContextStringSerializer());
            factory.afterPropertiesSet();
            return factory.getObject();
        }
    };
}

我将上述bean添加到我的主类中,但仍然收到错误。

1 个答案:

答案 0 :(得分:0)

batch_job_execution_context表中,您可能有一些由Spring批处理版本3创建的记录。当您尝试使用Spring Batch的版本4执行新的执行时,它试图比较以前的记录。因此,它试图反序列化那些较早的记录。这就是为什么您遇到此问题。

春季批处理版本3记录就像batch_job_execution_context表中的波纹管一样

  

{“ map”:[{“ entry”:{“ string”:[“ key”,“ value”]}}]}}

春季批处理版本4记录就像batch_job_execution_context表中的波纹管一样

{"key":"value"}

删除所有由版本3创建的记录。这将解决此问题。