Good afternoon, playing around with Univocity CSV unmarshalling. Using this route works fine for marshalling to a list but using the asMap=true option fails with a Nullpointer exception. Is there anything obvious missing? Currently using Spring Boot 2.5.5 and Apache Camel 3.12.0.
@Override
public void configure() {
log.info("StartApplication...Camel");
UniVocityCsvDataFormat dataFormat = new UniVocityCsvDataFormat()
.setNullValue("N/A")
.setLazyLoad(true)
.setAsMap(true);
from("file://source/?idempotent=false&delete=false")
.startupOrder(1)
.autoStartup(true)
.routeId("read-csv")
.log("Filename:${file:name}")
.unmarshal(dataFormat).split().body()
.log("${body}");
log.info("StopApplication...Camel");
}
This is the error that shown with asMap=true, but it works with asMap=false.
java.lang.NullPointerException: null
at org.apache.camel.dataformat.univocity.Unmarshaller$MapRowIterator.convertRow(Unmarshaller.java:188) ~[camel-univocity-parsers-3.12.0.jar:3.12.0]
at org.apache.camel.dataformat.univocity.Unmarshaller$MapRowIterator.convertRow(Unmarshaller.java:167) ~[camel-univocity-parsers-3.12.0.jar:3.12.0]
at org.apache.camel.dataformat.univocity.Unmarshaller$RowIterator.next(Unmarshaller.java:116) ~[camel-univocity-parsers-3.12.0.jar:3.12.0]
at org.apache.camel.dataformat.univocity.Unmarshaller.convertToList(Unmarshaller.java:74) ~[camel-univocity-parsers-3.12.0.jar:3.12.0]
at org.apache.camel.dataformat.univocity.Unmarshaller.unmarshal(Unmarshaller.java:61) ~[camel-univocity-parsers-3.12.0.jar:3.12.0]
at org.apache.camel.dataformat.univocity.AbstractUniVocityDataFormat.unmarshal(AbstractUniVocityDataFormat.java:128) ~[camel-univocity-parsers-3.12.0.jar:3.12.0]
at org.apache.camel.support.processor.UnmarshalProcessor.process(UnmarshalProcessor.java:64) ~[camel-support-3.12.0.jar:3.12.0]
at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:469) ~[camel-core-processor-3.12.0.jar:3.12.0]
at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:179) ~[camel-base-engine-3.12.0.jar:3.12.0]
at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:64) ~[camel-base-engine-3.12.0.jar:3.12.0]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:184) ~[camel-core-processor-3.12.0.jar:3.12.0]
at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:399) ~[camel-base-engine-3.12.0.jar:3.12.0]
at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:492) ~[camel-file-3.12.0.jar:3.12.0]
at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:245) ~[camel-file-3.12.0.jar:3.12.0]
at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:206) ~[camel-file-3.12.0.jar:3.12.0]
at org.apache.camel.support.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:191) ~[camel-support-3.12.0.jar:3.12.0]
at org.apache.camel.support.ScheduledPollConsumer.run(ScheduledPollConsumer.java:108) ~[camel-support-3.12.0.jar:3.12.0]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[na:na]
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
Add a new line at the end of the file and it will work. The headers are set to null in this method when the last line is read. (Unmarshaller class).
And after debugging i saw that this method(HeadersRowProcessor.class) is executed before converting the last row (withouth an empty line)