PostGreSQL JOB_EXECUTION_CONTEXT的Spring Batch ExecutionContext反序列化失败

时间:2017-09-20 21:14:43

标签: deserialization spring-batch executioncontext

我正在尝试使用Java Configuration和PostGreSQL创建Spring Batch POC。

我已经成功创建了bean,这些bean本来是通过内存DB使用@EnableBatchProcessing和@EnableAutoConfiguration提供的。

在给定从同一JobExplorer bean创建的JobInstance bean的情况下,我无法让bean(JobExplorer)返回JobExecution列表。

我得到的错误是“无法反序列化执行上下文”,这似乎来自试图反序列化JOB_EXECUTION_CONTEXT表的“SHORT_CONTEXT”字段的方法。

我已经传递了创建的JobExplorer bean DefaultExecutionContextSerializer。后来传递了一个DefaultLobHandler,当我仍然收到错误时,“wrapAsLob”设置为True。

@Bean
public JobRegistry jobRegistry() {
    JobRegistry jr = new MapJobRegistry();
    return jr;
}

@Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor() {
    JobRegistryBeanPostProcessor jrbpp = new JobRegistryBeanPostProcessor();
    jrbpp.setJobRegistry(jobRegistry());
    return jrbpp;
}

@Bean
public JobOperator jobOperator() {
    SimpleJobOperator sjo = new SimpleJobOperator();
    sjo.setJobExplorer(jobExplorer());
    sjo.setJobLauncher(jobLauncher());
    sjo.setJobRegistry(jobRegistry());
    sjo.setJobRepository(jobRepository());

    return sjo;
}

@Bean
public JobExplorer jobExplorer() {
    JobExplorerFactoryBean jefb = new JobExplorerFactoryBean();
    jefb.setDataSource(dataSource());
    jefb.setJdbcOperations(jdbcTemplate);
    jefb.setTablePrefix("batch_");  
    jefb.setSerializer(new DefaultExecutionContextSerializer());
    DefaultLobHandler lh = new DefaultLobHandler();
    lh.setWrapAsLob(true);
    jefb.setLobHandler(lh);
    JobExplorer je = null;
    try {
        je = jefb.getObject();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return je;
}

@ConfigurationProperties(prefix = "spring.datasource")
@Bean
@Primary
public DataSource dataSource() {
    return DataSourceBuilder.create().build();
}

@Bean
public JobRepository jobRepository() {
    JobRepositoryFactoryBean jrfb = new JobRepositoryFactoryBean();
    jrfb.setDataSource(dataSource());
    jrfb.setDatabaseType("POSTGRES");
    jrfb.setTransactionManager(new ResourcelessTransactionManager());
    jrfb.setSerializer(new DefaultExecutionContextSerializer());
    jrfb.setTablePrefix("batch_");
    JobRepository jr = null;
    try {

        jr = (JobRepository)jrfb.getObject();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return jr;
}

下面是我的休息控制器中的get方法,我正在尝试处理生成失败的作业执行列表

@Autowired
JobLauncher jobLauncher;

@Autowired
JobRegistry jobRegistry;

@Autowired
JobOperator jobOperator;

@Autowired
JobExplorer jobExplorer;



@SuppressWarnings("unchecked")
@GetMapping("batch/failedJobs")
public Map<String, List<JobExecution>> getFailedJobs() {
    try {
        if (jobRegistry == null || jobOperator == null || jobExplorer == null) {
            System.out.println("job registry, operator or explorer is null");
        } else {
            Map<String, List<JobExecution>> allJobInstances = new HashMap<String, List<JobExecution>>();
            // Get all jobs
            jobRegistry.getJobNames().stream().forEach(jobName -> {
                jobExplorer.getJobInstances(jobName, 1, 1000).forEach(l -> {
                    System.out.println("jobName: " + jobName + " instance: " + l);
                });
                jobExplorer.getJobInstances(jobName, 1, 1000).stream().forEach(jobInstance -> {
                    List<JobExecution> execultionList = jobExplorer.getJobExecutions(jobInstance); //Failing here
                    if (execultionList != null) { 
                        System.out.println("" + execultionList);
                        execultionList.stream().forEach(l2 -> {
                            System.out.println("jobName: " + jobName + " instance: " + jobInstance
                                    + " jobExecution: " + l2);
                        });
                        if(allJobInstances.get(jobName) == null) {
                            allJobInstances.put(jobName, new ArrayList<JobExecution>());
                        }
                        allJobInstances.get(jobName).addAll((Collection<? extends JobExecution>) jobExplorer.getJobExecutions(jobInstance).stream().filter(e -> e.getStatus().equals(BatchStatus.FAILED)));
                    }else {
                        System.out.println("Could not get jobExecution for jobName " + jobName + " jobInstance: " + jobInstance);
                    }
                });
            });

            return allJobInstances;
        }

    }catch (Exception e) {
        System.out.println(e.getMessage());
        logger.info(e.getMessage());
    }
    return null;
}

1 个答案:

答案 0 :(得分:0)

我通过更改为Jackson2序列化程序修复了类似的问题:

1

你可以尝试一下。