Reputation: 3744
I have spring job that read a file, process the data then write it in an oracle database.
I'm having an issue when declaring my job, the error :
The method listener(Object) is ambiguous for the type SimpleStepBuilder< Map< String,Object >,Map< String,Object >>
I do not understand the error, why it is not using listener(ItemListener..) method
. Any ideas ?
EDIT : Using separate listeners, having 3 objects implementing ItemWriteListener<T>
, ItemReadListener<T>
and ItemProcessorListener<T,O>
and building the step like that :
//...
.reader(/* custom ItemReader */)
.listener(/* custom ItemReadListener<T> */)
.listener(/* custom ItemWriterListener<T> */)
.listener(/* custom ItemProcessorListener<T,O> */)
//...
.build();
The error disapear, but I still don't understand why it does not work with ItemListenerSupport
class..
Here is how my step is built :
SimpleStepBuilder<Map<String, Object>, Map<String, Object>> stepBuilder = stepBuilderFactory
.get("testStep")
.<Map<String, Object>, Map<String, Object>>chunk(5000)
.reader(/* custom ItemReader<Map<String, Object>> object */));
.processor(/*custom ItemProcessor<Map<String, Object>, Map<String, Object>> object */))
.writer(/*custom ItemWriter<Map<String,Object> object */)
.listener(new GenericItemListener<Map<String, Object>, Map<String, Object>>())
.build();
Here is my custom ItemListenerSupport
:
import java.util.List;
import org.springframework.batch.core.listener.ItemListenerSupport;
public class GenericItemListener<I, R> extends ItemListenerSupport<I, R> {
@Override
public void onReadError(Exception e) {
//do something
}
@Override
public void onWriteError(Exception e, List<? extends R> items) {
//do something
}
@Override
public void onProcessError(I items, Exception e) {
//do something
}
}
Upvotes: 4
Views: 3839
Reputation: 6822
ItemListenerSupport
is a convenience class that allows you to create a listener for reading, processing and writing in one place. The idea is that there may be a lot of common logic among the three different tasks and so this becomes a central place.
For that reason, and because a listener is attached at the different steps, you should attach the listener multiple time as needed and cast accordingly:
SimpleStepBuilder<Map<String, Object>, Map<String, Object>> stepBuilder = stepBuilderFactory
.get("testStep")
.<Map<String, Object>, Map<String, Object>>chunk(5000)
.reader(/* custom ItemReader<Map<String, Object>> object */))
.listener((ItemReadListener)genericItemListener)
.processor(/*custom ItemProcessor<Map<String, Object>, Map<String, Object>> object */))
.listener((ItemProcessorListener)genericItemListener)
.writer(/*custom ItemWriter<Map<String,Object> object */)
.listener((ItemWriterListener)genericItemListener)
.listener(new GenericItemListener<Map<String, Object>, Map<String, Object>>())
.build();
Upvotes: 2
Reputation: 2871
I encountered the same problem.
I don't know if it's the best way to handle this but I bypassed it by casting my ItemListenerSupport sub-class to an ItemProcessListener
Here the listener:
class CustomListener extends ItemListenerSupport<Input, Output> {
@Override
public void onProcessError(Input item, Exception e) {
log.error(item.toString(), e);
}
public ItemProcessListener<? super Input, ? super Output> asItemProcessListener() {
return this;
}
}
Here the step definition
steps.get("step").<Input, Output>chunk(10)
.reader(reader)
.listener(listener.asItemProcessListener())
.processor(processor)
.build()
Upvotes: 3