简体   繁体   English

运行 spring 批处理作业时无法反序列化执行上下文异常

[英]Unable to deserialize the execution context exception when running spring batch job

I am executing some spring batch job and getting the following exception:我正在执行一些 spring 批处理作业并收到以下异常:

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDate` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (ByteArrayInputStream); line: 1, column: 447] (through reference chain: java.util.HashMap["TEST_FF_EXCEPTION"]-com.example.model.TestFFContext["cobDate"])

Assuming that it is some kind of date serialization issue, I have tried the following:假设这是某种日期序列化问题,我尝试了以下方法:

public class LocalDateDeserializer extends StdDeserializer<LocalDate> {

    public LocalDateDeserializer() {
        super(LocalDate.class);
    }

    @Override
    public LocalDate deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext)
            throws IOException {
        return LocalDate.parse(jsonParser.getText());
    }
}
    

public class LocalDateSerializer extends StdSerializer<LocalDate> {

    static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    public LocalDateSerializer() {
        super(LocalDate.class);
    }

    @Override
    public void serialize(final LocalDate localDate, final JsonGenerator jsonGenerator,
                          final SerializerProvider serializerProvider) throws IOException {
        final String formattedDateTime = localDate.format(FORMATTER);
        jsonGenerator.writeString(formattedDateTime);
    }
}


public final class TestFFContext {

    private String name;

    @JsonDeserialize(using = LocalDateDeserializer.class)
    @JsonSerialize(using = LocalDateSerializer.class)
    private LocalDate cobDate;
    
    //no args constructor
    //all args constructor
    
}

But getting the following:但是得到以下信息:

   Caused by: com.fasterxml.jackson.databind.JsonMappingException: Text '{' could not be parsed at index 0 (through reference chain: java.util.HashMap["TEST_FF_CONTEXT"]->com.example.model.TestFFContext["cobDate"])
        at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394)
        at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:353)
        at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1711)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:371)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
        at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:116)
        at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromAny(AsArrayTypeDeserializer.java:71)
        at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserializeWithType(UntypedObjectDeserializer.java:712)
        at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:529)
        at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364)
        at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
        at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4014)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3078)
        at org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer.deserialize(Jackson2ExecutionContextStringSerializer.java:71)
        at org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer.deserialize(Jackson2ExecutionContextStringSerializer.java:50)
        at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:325)
        at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:312)
        at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:94)
        at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:61)
        at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:679)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:768)
        at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.getExecutionContext(JdbcExecutionContextDao.java:114)
        at org.springframework.batch.core.repository.support.SimpleJobRepository.getLastJobExecution(SimpleJobRepository.java:278)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
        at com.sun.proxy.$Proxy155.getLastJobExecution(Unknown Source)
        at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:104)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
        at com.sun.proxy.$Proxy151.run(Unknown Source)

Anyone can give me any pointers what I am missing here?任何人都可以给我任何指示我在这里缺少什么?

it is tripping up in ExecutionContextRowMapper() when deserialising inputstream.反序列化输入流时,它在ExecutionContextRowMapper()中跳闸。 This is only happening in the case of my bdd test.这只发生在我的 bdd 测试中。 When running the spring boot app normally, I didnt need any custom serialization classes.正常运行 spring 启动应用程序时,我不需要任何自定义序列化类。

Sample json:样品 json:

{
  "name": "TEST",
  "cobDate": "2020-07-28",
}

I create spring batch job parameter with cobDate from string and run job:我使用字符串中的cobDate创建 spring 批处理作业参数并运行作业:

`execution = jobLauncher.run(job, parameters);`

After updating deserializer to use getValueAsString()更新反序列化器以使用getValueAsString()

Caused by: com.fasterxml.jackson.databind.JsonMappingException: text (through reference chain: java.util.HashMap["TEST_FF_CONTEXT"]->com.example.model.TestFFContext["cobDate"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:353)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1711)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:371)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:116)
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromAny(AsArrayTypeDeserializer.java:71)
    at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserializeWithType(UntypedObjectDeserializer.java:712)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:529)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4014)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3078)
    at org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer.deserialize(Jackson2ExecutionContextStringSerializer.java:71)
    at org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer.deserialize(Jackson2ExecutionContextStringSerializer.java:50)
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:325)
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:312)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:94)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:61)
    at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:679)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:768)
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.getExecutionContext(JdbcExecutionContextDao.java:114)
    at org.springframework.batch.core.repository.support.SimpleJobRepository.getLastJobExecution(SimpleJobRepository.java:278)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy155.getLastJobExecution(Unknown Source)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy151.run(Unknown Source)
    at com.example.batch.MyJobRunner.runJob(MyJobRunner.java:61)
    at com.example.feed.AbstractProcessor.validateAndRun(AbstractProcessor.java:62)
    at com.example.feed.MySyncProcessor.execute(MySyncProcessor.java:25)
    at com.example.feed.AbstractProcessor.process(AbstractProcessor.java:44)
    at com.example.cukes.stepdefs.MyStepDef.theRequestIsProcessedSynchronously(MyStepDef.java:53)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at io.cucumber.java.Invoker.invoke(Invoker.java:27)
    at io.cucumber.java.JavaStepDefinition.execute(JavaStepDefinition.java:27)
    at io.cucumber.core.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:63)
    at io.cucumber.core.runner.TestStep.executeStep(TestStep.java:64)
    at io.cucumber.core.runner.TestStep.run(TestStep.java:49)
    at io.cucumber.core.runner.PickleStepTestStep.run(PickleStepTestStep.java:46)
    at io.cucumber.core.runner.TestCase.run(TestCase.java:51)
    at io.cucumber.core.runner.Runner.runPickle(Runner.java:67)
    at io.cucumber.junit.PickleRunners$NoStepDescriptions.run(PickleRunners.java:149)
    at io.cucumber.junit.FeatureRunner.runChild(FeatureRunner.java:83)
    at io.cucumber.junit.FeatureRunner.runChild(FeatureRunner.java:24)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at io.cucumber.junit.Cucumber.runChild(Cucumber.java:185)
    at io.cucumber.junit.Cucumber.runChild(Cucumber.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at io.cucumber.junit.Cucumber$RunCucumber.evaluate(Cucumber.java:219)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.NullPointerException: text
    at java.util.Objects.requireNonNull(Objects.java:228)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1848)
    at java.time.LocalDate.parse(LocalDate.java:400)
    at com.example.util.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:28)
    at com.example.util.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:11)
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369)
    ... 87 more

Use parser.getValueAsString() to get the json value for date and use formatter when parse the date string.使用parser.getValueAsString()获取日期的 json 值,并在解析日期字符串时使用格式化程序。 And make sure you are importing right Deserializer on the field.并确保您在现场导入正确的反序列化器。 I added a sample, you can use it我添加了一个示例,您可以使用它

public class LocalDateDeserializer extends StdDeserializer<LocalDate> {

    private static final long serialVersionUID = 1608358311371702012L;

    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    public LocalDateDeserializer() {
        this(null);
    }

    protected LocalDateDeserializer(Class<LocalDate> type) {
        super(type);
    }

    @Override
    public LocalDate deserialize(JsonParser parser, DeserializationContext context)
            throws IOException, JsonProcessingException {
        return LocalDate.parse(parser.getValueAsString(), formatter);
    }

}

I solved this problem by configuring a custom JobRepository that could handle JSR-310: First add com.fasterxml.jackson.datatype:jackson-datatype-jsr310 in your classpath if you don't have it already Then, my main config class for Spring batch extends DefaultBatchConfigurer from which I can override createJobRepository . I solved this problem by configuring a custom JobRepository that could handle JSR-310: First add com.fasterxml.jackson.datatype:jackson-datatype-jsr310 in your classpath if you don't have it already Then, my main config class for Spring批处理扩展DefaultBatchConfigurer ,我可以从中覆盖createJobRepository I pass it an ObjectMapper configured to handle JSR-310:我向它传递了一个配置为处理 JSR-310 的ObjectMapper

@Override
protected JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(getTransactionManager());
    Jackson2ExecutionContextStringSerializer serializer = new Jackson2ExecutionContextStringSerializer();
    serializer.setObjectMapper(objectMapper());
    factory.setSerializer(serializer);
    factory.afterPropertiesSet();
    return factory.getObject();
}

@Bean
public ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JavaTimeModule());
    return objectMapper;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring 批次 4.2.4:无法反序列化执行上下文 - Spring Batch 4.2.4: Unable to deserialize the execution context Spring 批处理如何在 Skip Listener 中获取作业执行上下文 - Spring batch how to get job execution context in Skip Listener Spring批处理:传播在分区步骤中遇到的异常(停止作业执行) - Spring batch : Propagate exception encountered in partitioned step (Stop job execution) 使用StepBuilder创建tasklet时“无法反序列化执行上下文” - “Unable to deserialize the execution context” when creating tasklet with StepBuilder Spring Batch多个作业执行 - Spring Batch Multiple Job execution 如何从 Spring Batch Step 访问执行上下文? 错误:没有可用于作业范围的上下文持有者 - How to access execution context from a Spring Batch Step? Error: No context holder available for job scope 升级到Spring Cloud Dataflow任务的Spring Boot 2.0后无法反序列化执行上下文 - Unable to deserialize the execution context after upgrading to spring boot 2.0 for a spring cloud dataflow task 在 unix 中运行 spring 批处理作业 - Running spring batch job in unix Spring Batch 3.0:StepExecutionListener 用于分区 Step 并将执行上下文值级联到分区作业 - Spring Batch 3.0 : StepExecutionListener for a partitioned Step and cascading of execution context values to the partitioned job 通过JUnit运行时执行Spring Batch作业增量器 - Executing a Spring Batch job incrementer when running through JUnit
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM