使用Smack 4.1的XMPP客户端在登录期间给出NullPointerException

时间:2015-03-14 06:35:25

标签: java xmpp ejabberd smack

我正在尝试使用Smack 4.1.0-rc3来实现连接到ejabberd xmpp服务器的java xmpp客户端。我使用以下代码连接到服务器。

    XMPPTCPConnectionConfiguration connConfig =    XMPPTCPConnectionConfiguration
            .builder()
            .setServiceName("example.com")
            .setHost("192.168.56.101")
            .setPort(5222)
            .setCompressionEnabled(false)
            .setSecurityMode(SecurityMode.disabled)
            .setHostnameVerifier(new HostnameVerifier() {
                public boolean verify(String arg0, SSLSession arg1) {
                    return true;
                }
            })
            .setUsernameAndPassword(user, pass).build();

    connection = new XMPPTCPConnection(connConfig);
    connection.connect();
    connection.login();

执行'connection.login()'时,我收到以下NullPointerException。

Exception in thread "main" java.lang.NullPointerException
at org.jivesoftware.smack.util.stringencoder.Base64.encode(Base64.java:64)
at org.jivesoftware.smack.util.stringencoder.Base64.encode(Base64.java:60)
at org.jivesoftware.smack.util.stringencoder.Base64.encodeToString(Base64.java:42)
at org.jivesoftware.smack.sasl.SASLMechanism.authenticate(SASLMechanism.java:199)
at org.jivesoftware.smack.sasl.SASLMechanism.authenticate(SASLMechanism.java:169)
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:236)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.loginNonAnonymously(XMPPTCPConnection.java:365)
at org.jivesoftware.smack.AbstractXMPPConnection.login(AbstractXMPPConnection.java:452)
at org.jivesoftware.smack.AbstractXMPPConnection.login(AbstractXMPPConnection.java:410)
at org.org.oodlezz.unio.jabber.client.XmppClient.connect(XmppClient.java:88)
at org.org.oodlezz.unio.jabber.client.Client.main(Client.java:32)

我在代码中做错了吗?能否请您指出使用Smack 4.1.0-rc3的正确示例?

6 个答案:

答案 0 :(得分:33)

这个页面上的其他答案有部分答案,但尝试它们我发现真正缺少的是对smack-java7库的依赖。添加此依赖项会导致调用初始化程序,设置base64encoder,因此NullPointerException消失。

在Android上,用smack-android替换smack-java7。

答案 1 :(得分:5)

您的代码没问题,但可能需要正确的依赖项,您可以将它放在pom.xml文件中

<dependencies>
    <dependency>
        <groupId>org.igniterealtime.smack</groupId>
        <artifactId>smack-java7</artifactId>
        <version>4.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.igniterealtime.smack</groupId>
        <artifactId>smack-tcp</artifactId>
        <version>4.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.igniterealtime.smack</groupId>
        <artifactId>smack-im</artifactId>
        <version>4.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.igniterealtime.smack</groupId>
        <artifactId>smack-extensions</artifactId>
        <version>4.1.1</version>
    </dependency>
</dependencies>

这基于:https://github.com/igniterealtime/Smack/wiki/Smack-4.1-Readme-and-Upgrade-Guide

你可以把你需要的smack版本。

如果您不熟悉maven中的一些第一步,这可能对您有用:https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html

希望有这个帮助!

答案 2 :(得分:3)

正如Stephen所建议的那样,Base64encoder确实是空的,因为它没有被设置。要初始化您必须在项目中包含smack-java7模块。

在连接之前,你必须使用

初始化smack
new Java7SmackInitializer().initialize();

对于Android,我相信您可以使用

实现这一目标
new AndroidSmackInitializer().initialize();

答案 3 :(得分:1)

我使用4.1.0-rc3。就我而言,我没有遇到NPE。该示例有效。

以下是pom.xml的一部分。

的pom.xml

<properties>
    <smack.version>4.1.0-rc3</smack.version>
</properties>
...
<dependencies>
    <dependency>
        <groupId>org.igniterealtime.smack</groupId>
        <artifactId>smack-core</artifactId>
        <version>${smack.version}</version>
    </dependency>
    <dependency>
        <groupId>org.igniterealtime.smack</groupId>
        <artifactId>smack-tcp</artifactId>
        <version>${smack.version}</version>
    </dependency>
    <dependency>
        <groupId>org.igniterealtime.smack</groupId>
        <artifactId>smack-java7</artifactId>
        <version>${smack.version}</version>
    </dependency>
...
</dependencies>
...

示例代码只是,

AbstractXMPPConnection conn = new XMPPTCPConnection("xxx", "yyy", "zzz");

conn.connect();
conn.login();

答案 4 :(得分:0)

删除它:

  

编译&#34; org.igniterealtime.smack:smack - java7:4.1.4&#34;

并添加:

  

编译&#34; org.igniterealtime.smack:smack - android:4.1.4&#34;

答案 5 :(得分:0)

当互联网不可用时我得到空指针异常,我没有初始化与XMPP的任何连接。所以,Base64没有在smack的任何地方初始化。在这种情况下,我需要使用以下方法手动初始化SmackInitializer:

//SELECT record form table 
SqlDataAdapter adap = new SqlDataAdapter("SELECT * FROM TABLE_NAME WHERE is_done=0 AND date>DATEADD(minute,-5,GETDATE())", conn);
DataTable dt = new DataTable();
adap.Fill(dt);
for (int i = 0; i < dt.Rows.Count; i++)
{
  string parameters= dt.Rows[i]["parameters"] + "";
  string api = "http://domain.com/page.aspx?parameters=" + parameters;
  HttpWebRequest httpreq = (HttpWebRequest)WebRequest.Create(api);
  HttpWebResponse httpres = (HttpWebResponse)httpreq.GetResponse();
  StreamReader sr = new StreamReader(httpres.GetResponseStream());
  string results = sr.ReadToEnd();
  sr.Close();
  if (results.Contains("<?xml version=\"1.0\" encoding=\"utf-8\" ?>"))
  {
     try
     {
      string response= "";
      XmlDocument xmlDoc = new XmlDocument();
      xmlDoc.LoadXml(results);
      var res2 = xmlDoc.SelectNodes("RechargeRequest/RequestResponse/APIRef");
      if (res2 != null)
        response= res2[0].InnerText;
      SqlCommand cmd = new SqlCommand("UPDATE TABLE_NAME SET field='" + response+ "',is_done=1 WHERE id=" + rId, conn);
      conn.Open();
      cmd.ExecuteNonQuery();
      conn.Close();
    }
    catch (Exception ex)
    {

    }
  }
}

此行在smack库中调用AndroidSmackInitializer类initialize():

new AndroidSmackInitializer().initialize(); // Add this single line for initialization