java.lang.NullPointerException:在 org.apache.camel.model.ModelHelper.getNamespaceAwareFromExpression(ModelHelper.java:263) 处为空

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

我们在调用时在题目中提到的coe行有NPE

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

在 Apache Camel 中。即从 XML 配置加载路由时。很明显,导致异常的问题是 XML 中的一些不明确的更改,仍然使其有效,但不知何故使其失败。我认为在验证 XML 的一致性时应该更早地抛出错误消息。现在它是一种运行时异常。

完整的堆栈跟踪是:

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

路线的关键部分是:

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

但我认为不应该退出任何配置以抛出此异常。

Camel 和 Spring 引导版本是:

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

缺少关键部分:

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

没有它它仍然有效,但抛出了上面的异常。但据我了解,不应为任何类型的路由配置抛出此异常,即使对于有效配置也不应抛出。

您必须在 <when> 中包含表达式,因为这是必需的。但是 XML 可能在没有 XSD 验证的情况下加载。