0

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]
Kirst
  • 1

1 Answers1

0

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).

        @Override
    protected Map<String, String> convertRow(String[] row) {
        String[] headers = headerRowProcessor.getHeaders();

        int size = Math.min(row.length, headers.length);

And after debugging i saw that this method(HeadersRowProcessor.class) is executed before converting the last row (withouth an empty line)

   @Override
    public void processEnded(ParsingContext context) {
        headers = null;
    }
Boris
  • 1
  • 1