cat
cat copied to clipboard
[Integration] Cat integration CatRegistryFactoryWrapper NullPointerException
Describe the bug CatRegistryFactoryWrapper has a potential NPE bug
To Reproduce
- install artifact cat-monitor Dubbo整合插件
- start application
<dependency>
<groupId>net.dubboclub</groupId>
<artifactId>cat-monitor</artifactId>
<version>x.x.x</version>
</dependency>
Expected behavior normal startup
Versions Dubbo 3.1.6 Spring 5.2.8.RELEASE
Exception
02 八月 2024 16:51:53,669 175090 [localhost-startStop-1] INFO org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils - [DUBBO] Start registering instance address to registry., dubbo version: 3.1.6, current host: 172.17.0.1
02 八月 2024 16:51:53,696 175117 [localhost-startStop-1] WARN org.apache.dubbo.registry.client.AbstractServiceDiscovery - [DUBBO] No valid instance found, stop registering instance address to registry., dubbo version: 3.1.6, current host: 172.17.0.1, error code:
1-12. This may be caused by , go to https://dubbo.apache.org/faq/1/12 to find instructions.
02 八月 2024 16:51:53,698 175119 [localhost-startStop-1] ERROR org.apache.dubbo.config.deploy.DefaultApplicationDeployer - [DUBBO] Dubbo Application[1.1](xxxx-plat-rdc) found failed module: Dubbo Module[1.1.1], dubbo version: 3.1.6, current host: 172.17.0.1, error code: 5-14. This may be caused by , go to https://dubbo.apache.org/faq/5/14 to find instructions.
java.lang.NullPointerException
at net.dubboclub.catmonitor.registry.registry.CatRegistryFactoryWrapper$RegistryWrapper.register(CatRegistryFactoryWrapper.java:58)
at org.apache.dubbo.registry.ListenerRegistryWrapper.register(ListenerRegistryWrapper.java:62)
at org.apache.dubbo.registry.integration.RegistryProtocol.register(RegistryProtocol.java:212)
at org.apache.dubbo.registry.integration.RegistryProtocol.export(RegistryProtocol.java:250)
at org.apache.dubbo.qos.protocol.QosProtocolWrapper.export(QosProtocolWrapper.java:77)
at org.apache.dubbo.rpc.protocol.ProtocolSecurityWrapper.export(ProtocolSecurityWrapper.java:80)
at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.export(ProtocolListenerWrapper.java:64)
at org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper.export(ProtocolFilterWrapper.java:58)
at org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper.export(ProtocolSerializationWrapper.java:47)
at org.apache.dubbo.rpc.Protocol$Adaptive.export(Protocol$Adaptive.java)
at org.apache.dubbo.config.ServiceConfig.doExportUrl(ServiceConfig.java:717)
at org.apache.dubbo.config.ServiceConfig.exportRemote(ServiceConfig.java:695)
at org.apache.dubbo.config.ServiceConfig.exportUrl(ServiceConfig.java:636)
at org.apache.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol(ServiceConfig.java:445)
at org.apache.dubbo.config.ServiceConfig.doExportUrls(ServiceConfig.java:429)
at org.apache.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:391)
at org.apache.dubbo.config.ServiceConfig.export(ServiceConfig.java:243)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.exportServiceInternal(DefaultModuleDeployer.java:350)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.exportServices(DefaultModuleDeployer.java:322)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.startSync(DefaultModuleDeployer.java:158)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.start(DefaultModuleDeployer.java:139)
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onContextRefreshedEvent(DubboDeployApplicationListener.java:113)
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:102)
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:47)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
https://github.com/dianping/cat/blob/60693f75f6ccc34ac9dc73b5c44526a7d2f20b35/integration/apache-dubbo/src/main/java/net/dubboclub/catmonitor/registry/CatRegistryFactoryWrapper.java#L37
经过Debug 构造函数这里接收了空值,难以复现,但2024年了,还是遇到了
@Override
public Registry getRegistry(URL url) {
return new RegistryWrapper(registryFactory.getRegistry(url)); // registryFactory.getRegistry = null
}
class RegistryWrapper implements Registry {
private Registry originRegistry;
public RegistryWrapper(Registry originRegistry) {
this.originRegistry = originRegistry;
}
......
@Override
public void register(URL url) {
originRegistry.register(appendProviderAppName(url)); //NPE : originRegistry = null
}
临时修复建议
@Override
public Registry getRegistry(URL url) {
Registry registry = registryFactory.getRegistry(url);
if (registry == null) {
logger.info("registry is null url " + url);
return registry;
}
return new RegistryWrapper(registry);
}
依据:可以看到 Dubbo 的 ListenerRegistryWrapper 进行了registry != null 判断,并且从该PR开始,getRegistry根据check进行判断,check=false的时候,registry是可以等于null的
https://github.com/apache/dubbo/pull/8483
public class ListenerRegistryWrapper implements Registry {
@Override
public void register(URL url) {
try {
if (registry != null) {
registry.register(url);
}
} finally {
if (!UrlUtils.isConsumer(url)) {
listenerEvent(serviceListener -> serviceListener.onRegister(url, registry));
}
}
}
}
依据2:
public abstract class AbstractRegistryFactory implements RegistryFactory {
......
if (check && registry == null) {
throw new IllegalStateException("Can not create registry " + url);
}
if (registry != null) {
REGISTRIES.put(key, registry);
}
return registry;
}
}