Apache Camel: Univocity Map Unmarshalling NullPointer



下午好,正在玩Univocity CSV解组。使用此路由可以很好地封送到列表,但使用asMap=true选项会失败,并出现Nullpointer异常。有什么明显的东西不见了吗?目前使用Spring Boot 2.5.5和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");

}

这是当asMap=true时显示的错误,但当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]

在文件末尾添加新行,就可以了。当读取最后一行时,此方法将头文件设置为空。(解组程序类).

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

调试后,我看到这个方法(HeadersRowProcessor.class)在转换最后一行(没有空行)之前执行

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

最新更新