AsyncItemWriter – 当将自定义类从 Future 中解包时出现 ClassCastException。

huangapple go评论70阅读模式
英文:

AsyncItemWriter - Facing ClassCastException when unwrapping custom class into Future

问题

我正在编写一个Spring Batch作业,它读取一些数据并将其写入文件。数据被分成3个块,每个块在合并之前都需要写入单独的文件。读取和聚合工作正常进行。

然而,当异步写入器抛出错误时 -- java.lang.ClassCastException: 无法将类package.Custom强制转换为类java.util.concurrent.Future

看起来我的自定义DTO没有解包为Future对象。
以下是我缩写的代码

@Bean
public Step workerStep() throws Exception {
    return stepBuilderFactory.get(WORKER_BEAN)
            .<Custom, Custom>chunk(CHUNK_SIZE)
            .reader(reader(null))
            .writer(writer())
            .taskExecutor(threadPoolExecutor)
            .throttleLimit(THROTTLE_LIMIT)
            .build();
}

@Bean
@StepScope
public CustomReader reader(@Value("#{stepExecutionContext['currentMod']}") Long currentMod) {
    if ( ... some logic ... ) {
        return null;
    }
    return new CustomReader();
}

@Bean
@StepScope
public AsyncItemWriter writer() throws Exception {
    AsyncItemWriter<Custom> asyncItemWriter = new AsyncItemWriter<>();
    asyncItemWriter.setDelegate(delegateWriter(null));
    asyncItemWriter.afterPropertiesSet();
    return asyncItemWriter;
}

@Bean(destroyMethod=EMPTY)
@StepScope
public CustomWriter<Custom> delegateWriter(@Value("#{stepExecutionContext['currentMod']}") Long currentMod) {
    CustomWriter<Custom> customWriter = new CustomWriter<>();

    customWriter.setLineAggregator(new DelimitedLineAggregator<Custom>() {
        {
            setDelimiter(COMMA);
            setFieldExtractor(new BeanWrapperFieldExtractor<Custom>() {
                {
                    setNames( ... get names logic ... );
                }
            });
        }
    });

    customWriter.setResource(new FileSystemResource(name));
    
    // ... header call-back logic ...
    
    customWriter.setAppendAllowed(true);
    customWriter.setShouldDeleteIfEmpty(true);
    customWriter.setShouldDeleteIfExists(true);
    return customWriter;
}

@Bean
public TaskExecutor taskExecutor() {
    return new SimpleAsyncTaskExecutor(THREAD_NAME_PREFIX);
}
英文:

I'm writing a spring batch job that reads some data and writes it to a file. The data is partitioned into 3 chunks, each of which need to be written to an individual file before being combined. The reading and aggregation are working fine.

However, when the asynchronous writer is throwing an error -- java.lang.ClassCastException: class package.Custom cannot be cast to class java.util.concurrent.Future

It seems like my Custom DTO isn't unwrapping into a Future object.
Here's my abridged code

 @Bean
public Step workerStep() throws Exception {
return stepBuilderFactory.get(WORKER_BEAN)
.&lt;Custom, Custom&gt;chunk(CHUNK_SIZE)
.reader(reader(null))
.writer(writer())
.taskExecutor(threadPoolExecutor)
.throttleLimit(THROTTLE_LIMIT)
.build();
}
@Bean
@StepScope
public CustomReader reader(@Value(&quot;#{stepExecutionContext[&#39;currentMod&#39;]}&quot;) Long currentMod) {
if ( ... some logic ... ) {
return null;
}
return new CustomReader();
}
@Bean
@StepScope
public AsyncItemWriter writer() throws Exception {
AsyncItemWriter&lt;Custom&gt; asyncItemWriter = new AsyncItemWriter&lt;&gt;();
asyncItemWriter.setDelegate(delegateWriter(null));
asyncItemWriter.afterPropertiesSet();
return asyncItemWriter;
}
@Bean(destroyMethod=EMPTY)
@StepScope
public CustomWriter&lt;Custom&gt; delegateWriter(@Value(&quot;#{stepExecutionContext[&#39;currentMod&#39;]}&quot;) Long currentMod) {
CustomWriter&lt;Custom&gt; customWriter = new CustomWriter&lt;&gt;();
customWriter.setLineAggregator(new DelimitedLineAggregator&lt;Custom&gt;() {
{
setDelimiter(COMMA);
setFieldExtractor(new BeanWrapperFieldExtractor&lt;Custom&gt;() {
{
setNames( ... get names logic ... );
}
});
}
});
customWriter.setResource(new FileSystemResource(name));
// ... header call-back logic ...
customWriter.setAppendAllowed(true);
customWriter.setShouldDeleteIfEmpty(true);
customWriter.setShouldDeleteIfExists(true);
return customWriter;
}
@Bean
public TaskExecutor taskExecutor() {
return new SimpleAsyncTaskExecutor(THREAD_NAME_PREFIX);
} 

答案1

得分: 1

AsyncItemWriter 期望的项目是包装在 Future 中的(请参阅 Javadoc),而这通常是由 AsyncItemProcessor 完成的。AsyncItemWriterAsyncItemProcessor 联合使用以实现 fork/join 场景,详见异步处理器部分。

英文:

The AsyncItemWriter expects items that are wrapped in a Future (See Javadoc), and this is typically done by an AsyncItemProcessor. The AsyncItemWriter and AsyncItemProcessor are used in conjunction to implement a fork/join scenario, see Asynchronous Processors section.

huangapple
  • 本文由 发表于 2020年8月19日 07:23:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63477978.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定