powered by Jive Software

ChatStateManager and NullPointerException

Hi,

I’m running into a NullPointerException that I can’t seem to remedy when attempting to incorporate chat state. I’ve tracked the source of the exception, but I can’t figure out why it’s happening. I’ve stripped out code that I don’t think is relevant. The offending code is here:

public class SimpleXMPP implements ChatStateListener {
     Connection connection;
     ChatStateManager csm;
         private void connect(){
          try {
               this.connection = new XMPPConnection("mydomain.tld");
               this.connection.connect();
               csm = ChatStateManager.getInstance(this.connection);
          } catch (XMPPException ex) {
               // handle exception
          }
      }      public void processMessage(Chat chat, Message msg) {
          // handle incoming message
     }
         public void stateChanged(Chat chat, ChatState state) {
          // handle state change
     } }

Logging in and initializing chat happen after connect(), but the problem is at ChatStateManager.getInstance(this.connection). This, in turn, calls:

WeakReference ref = managers.get(connection);

… which returns ref = null.

So, it goes onto:

if (ref == null) {
                manager = new ChatStateManager(connection);
                manager.init();
                managers.put(connection, new WeakReference<ChatStateManager>(manager));
            }

… and the problem is specifically on manager.init(), which looks like this:

private void init() {
        connection.getChatManager().addOutgoingMessageInterceptor(outgoingInterceptor,
                filter);
        connection.getChatManager().addChatListener(incomingInterceptor);         ServiceDiscoveryManager.getInstanceFor(connection).addFeature("http://jabber.org/protocol/chatstates");
    }

The problem is that ServiceDiscoveryManager.getInstanceFor(connection) returns null. So, we get a NullPointerException on that last line, of course. So you don’t have to look it up, getInstanceFor() looks like this:

public static ServiceDiscoveryManager getInstanceFor(Connection connection) {
        return instances.get(connection);
    }

instances is empty at this point.

I’m betting that I am simply missing some important step before calling ChatStateManager.getInstance(). Any help would be greatly appreciated. Incidentally, when I remove that line (csm=ChatStateManager.getInstance…) everything works perfectly, except that, obviously, I don’t get chat state functionality.

I’m using Smack 3.3.1.

Thank you for looking.

Cheers,

Breandan

I’m betting that I am simply missing some important step before callingChatStateManager.getInstance().

Not really an improtant step, more a bug fix for the ServiceDiscoveryManager buggy getInstance() method, that needs to be fixed in a future version of Smack. I suggest you try

if (ServiceDiscoveryManager.getInstance(con) = null) new ServiceDiscoveryManager(con);

bofore using ChatStateManager, to make sure that SDM is created for this connection.

1 Like

Brilliant! Thank you so much. Works perfectly now.

For anyone else running into this, the exact code I used was:

this.connection = new XMPPConnection("mydomain.tld");
this.connection.connect(); if (ServiceDiscoveryManager.getInstanceFor(this.connection) == null)
    new ServiceDiscoveryManager(this.connection); csm = ChatStateManager.getInstance(this.connection);

I am noticing some quirkiness about the way ChatStateListener processes messages vs MessageListener. But, I believe it to be unrelated to this issue. Chat state changes are recognized just fine now, but chat messages are coming through with an empty body. I’ll dig into that and start another thread if I run across anything worth sharing.

Cheers,

Breandan