使用Smack XMPP客户端连接FCM端点时触发NullPointerException
Firebase XMPP端点连接问题(使用Smack库)
问题说明
尝试用Java Openfire Smack库连接Firebase XMPP端点接收上游消息,不确定server domain的正确值,始终触发NullPointerException,未找到该库与Firebase结合的示例。
异常信息
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.jivesoftware.smack.util.dns.DNSResolver.lookupHostAddress(org.minidns.dnsname.DnsName, java.util.List, org.jivesoftware.smack.ConnectionConfiguration$DnssecMode)" because the return value of "org.jivesoftware.smack.util.DNSUtil.getDNSResolver()" is null at org.jivesoftware.smack.tcp.rce.RemoteXmppTcpConnectionEndpoints.lookup(RemoteXmppTcpConnectionEndpoints.java:71) at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectUsingConfiguration(XMPPTCPConnection.java:591) at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection.java:849) at org.jivesoftware.smack.AbstractXMPPConnection.connect(AbstractXMPPConnection.java:526) at XmppClientModule.run(XmppClientModule.java:38) at Main.main(Main.java:8)
当前连接配置代码
private static final String fcmServer = "fcm-xmpp.googleapis.com"; private static final int fcmPort = 5236; private static final String fcmSenderId = "101010101010@fcm-xmpp.googleapis.com"; private static final String fcmApiKey = "XXX"; private XMPPTCPConnectionConfiguration configuration; private XMPPTCPConnection connection; public XmppClientModule() { try { configuration = XMPPTCPConnectionConfiguration.builder() .setUsernameAndPassword(fcmSenderId, fcmApiKey) .setXmppDomain("fcm-xmpp.googleapis.com") .setHost(fcmServer) .setPort(fcmPort) .setSecurityMode(ConnectionConfiguration.SecurityMode.required) .build(); }catch (Exception e){ System.out.println("Error handling"); } connection = new XMPPTCPConnection(configuration); }
当前依赖配置
dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.2' implementation 'org.igniterealtime.smack:smack-core:4.4.6' implementation 'org.igniterealtime.smack:smack-tcp:4.4.6' implementation 'org.igniterealtime.smack:smack-extensions:4.4.6' implementation 'org.igniterealtime.smack:smack-xmlparser-xpp3:4.4.6' }
解决方案
1. 补充DNS解析依赖
NullPointerException的核心原因是Smack 4.x默认依赖minidns进行DNS解析,但当前依赖中未包含,需添加:
implementation 'org.igniterealtime.smack:smack-resolver-minidns:4.4.6'
2. 修正XMPP Domain和SenderId格式
- XMPP Domain:根据Firebase XMPP规范,正确值应为
fcm.googleapis.com,而非fcm-xmpp.googleapis.com - SenderId:仅需填写Firebase项目编号(即
101010101010),不需要添加@fcm-xmpp.googleapis.com后缀
3. 显式初始化DNS解析器(确保依赖加载)
在建立连接前添加初始化代码:
DNSUtil.setDNSResolver(new MiniDnsResolver());
修改后的连接配置代码
private static final String fcmServer = "fcm-xmpp.googleapis.com"; private static final int fcmPort = 5236; private static final String fcmSenderId = "101010101010"; // 仅项目编号 private static final String fcmApiKey = "XXX"; private XMPPTCPConnectionConfiguration configuration; private XMPPTCPConnection connection; public XmppClientModule() { try { // 初始化DNS解析器 DNSUtil.setDNSResolver(new MiniDnsResolver()); configuration = XMPPTCPConnectionConfiguration.builder() .setUsernameAndPassword(fcmSenderId, fcmApiKey) .setXmppDomain("fcm.googleapis.com") // 修正XMPP域名 .setHost(fcmServer) .setPort(fcmPort) .setSecurityMode(ConnectionConfiguration.SecurityMode.required) .build(); }catch (Exception e){ e.printStackTrace(); // 替换为更详细的错误日志 } connection = new XMPPTCPConnection(configuration); }
修改后的依赖配置
dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.2' implementation 'org.igniterealtime.smack:smack-core:4.4.6' implementation 'org.igniterealtime.smack:smack-tcp:4.4.6' implementation 'org.igniterealtime.smack:smack-extensions:4.4.6' implementation 'org.igniterealtime.smack:smack-xmlparser-xpp3:4.4.6' // 添加DNS解析依赖 implementation 'org.igniterealtime.smack:smack-resolver-minidns:4.4.6' }
内容的提问来源于stack exchange,提问作者Dominik Kerestes
相关产品推荐
相关产品推荐

