一、问题描述
今天服务升级了一个版本,在发送rabbitmq消息时报错NPE
java.lang.NullPointerException: Cannot invoke “org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry$FunctionInvocationWrapper.setSkipOutputConversion(boolean)” because “functionToInvoke” is null
at org.springframework.cloud.stream.function.StreamBridge.getStreamBridgeFunction(StreamBridge.java:215)
at org.springframework.cloud.stream.function.StreamBridge.send(StreamBridge.java:170)
二、问题排查
根据报错,可以知道是 functionToInvoke 为空,看 StreamBridge 源码(项目用的是Spring Cloud Stream)

跟进 functionCatalog.lookup 方法,一直往下,来到 BeanFactoryAwareFunctionRegistry 的 lookup 方法

发现是满足 !isFunctionDefinitionEligible(functionDefinition) 条件返回的 null,那就说明 isFunctionDefinitionEligible 方法返回了 false,debug 进去看

发现 definition 竟然包含了一个空字符串,然后开始寻找 this.functionProperties.getIneligibleDefinitions() 的由来,很显然这个是在项目启动的时候塞值的,于是在 FunctionProperties 类的 setIneligibleDefinitions 方法上打上断点,重启项目

发现确实塞了个空字符串,于是顺着往上找

发现是 kafka 相关的东西,sendToDlqAndContinue 是 kafka 的东西,但是为什么后面拼了一个逗号,不能理解,于是又找在哪里添加这个逗号的,然后在 KafkaStreamsBinderEnvironmentPostProcessor 里找到了代码

所以这个空字符串,是在 environment.getProperty(ineligibleDefinitionsPropertyKey) 里获取的,于是在 MutablePropertySources 类的所有添加方法上打上断点重来

最后在 addLast 方法里找到了,发现是微软云的 AzurePasswordlessEnvironmentPostProcessor 类中设置的

然后这段代码看着就很迷惑,创建一个空列表,然后用 String.join ,这么干的意义是什么???
然后就去github看,发现这个问题在3周前修复了
呃……这个文件直接被删了
三、解决问题
由于微软云解决问题的版本还是beta版本,暂时没考虑升级来解决问题
在配置文件里加上如下配置来解决
spring:
cloud:
function:
ineligible-definitions: xxxxx
xxxxx可以是任意字符串

1万+

被折叠的 条评论
为什么被折叠?



