java.lang.NullPointerException: null at org.apache.camel.model.ModelHelper.getNamespaceAwareFromExpression(ModelHelper.java:263)

Viewed 435

We have the NPE at the line of coe mentioned at the topic when calling for

RoutesDefinition routesDefinition=context.loadRoutesDefinition(new ByteArrayInputStream(value.getBytes(StandardCharsets.UTF_8)));

in Apache Camel. I.e when loading the route from XML config. It is clear that the problem caused the exception is some unclear change in XML, still making it valid, but somehow making it to fail. I believe that the error message should be thrown earlier when the consistency of XML is validated. Now it is a kind runtime exception.

The full stacktrace is:

13:35:01.768 [main] ERROR s.services.XMLRouteServiceImpl - Could not restart source
java.lang.NullPointerException: null
    at org.apache.camel.model.ModelHelper.getNamespaceAwareFromExpression(ModelHelper.java:263)
    at org.apache.camel.model.ModelHelper.applyNamespaces(ModelHelper.java:252)
    at org.apache.camel.model.ModelHelper.loadRoutesDefinition(ModelHelper.java:188)
    at org.apache.camel.model.ModelHelper.loadRoutesDefinition(ModelHelper.java:153)
    at org.apache.camel.impl.DefaultCamelContext.loadRoutesDefinition(DefaultCamelContext.java:1030)
    at sekaicamelproxy.builders.XMLCamelRouteBuilder.<init>(XMLCamelRouteBuilder.java:31)
    at sekaicamelproxy.services.XMLRouteServiceImpl.restartSource(XMLRouteServiceImpl.java:59)
    at io.vavr.Value.forEach(Value.java:340)
    at sekaicamelproxy.services.XMLRouteServiceImpl.restartAllRoutes(XMLRouteServiceImpl.java:177)
    at sekaicamelproxy.services.XMLRouteServiceImpl$$FastClassBySpringCGLIB$$f0155a48.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
    at sekaicamelproxy.services.XMLRouteServiceImpl$$EnhancerBySpringCGLIB$$38f84a05.restartAllRoutes(<generated>)
    at sekaicamelproxy.MqttToKafkaProxy.initializeRoutes(MqttToKafkaProxy.java:31)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:261)
    at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:179)
    at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:142)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359)
    at org.springframework.boot.context.event.EventPublishingRunListener.running(EventPublishingRunListener.java:105)
    at org.springframework.boot.SpringApplicationRunListeners.running(SpringApplicationRunListeners.java:78)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:332)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
    at sekaicamelproxy.Application.main(Application.java:10)

The critical part of the route is:

                      <when>
                        <log message="Processing as sattelites are more than 0"/>
                        <setHeader headerName="timestamp">
                            <jsonpath>$.t</jsonpath>
                        </setHeader>
                        <setHeader headerName="messageId">
                            <simple>${header.unit_id}-${header.timestamp}</simple>
                        </setHeader>
                        <setHeader headerName="kafka.KEY">
                            <simple resultType="java.lang.String">${header.unit_id}</simple>
                        </setHeader>
                        <idempotentConsumer messageIdRepositoryRef="deduplicationRepo">
                            <header>messageId</header>
                            <removeHeaders pattern="*" excludePattern="messageId|kafka\.KEY"/>
                            <to uri="micrometer:timer:camel.proxy.minifinder.getmessages.kafka?action=start" />
                            <log message="Deduplicated: body\n ${body}"/>
                            <to uri="micrometer:timer:camel.proxy.minifinder.getmessages.kafka?action=stop" />
                        </idempotentConsumer>
                    </when>

But I believe no config should exit to make this exception to be thrown.

Camel and Spring Boot versions are:

<camel.version>2.24.3</camel.version>
<spring-boot.version>2.1.8.RELEASE</spring-boot.version>
2 Answers

It was missing the key part of :

<when>
    <simple>${header.sattelitesCount} > 0</simple>

Without it it was still valid, but throwed the exception above. But for my understanding, this Exception shouldn't be thrown there for any kind of route config, even not for the valid config.

You must have the expression in the <when> as that is required. However the XML is likely loaded without XSD validation.

Related