NPE RoomInfo line 91

getRoomInfo from jabber.org throws a null pointer excpetion:

MultiUserChat.getRoomInfo(ConnectionManager.getInstance().getXMPPConnection(), address);

java.lang.NullPointerException

at org.jivesoftware.smackx.muc.RoomInfo.<init>(RoomInfo.java:91)

at org.jivesoftware.smackx.muc.MultiUserChat.getRoomInfo(MultiUserChat.java:208)

Hi,

I’m confirming this issue.

It is caused by RoomInfo trying to iterate over some FormFields that are not present in the IQ received from the server.

On my ejabberd2 server, a muc disco IQ carries no muc#roominfo_description nor muc#roominfo_subject fields.

As the RoomInfo constructors does not check their nullibility, a NPE is thrown each time I call MultiUserChat.getRoomInfo(…);

A simple “if (form.getField(”…") != null) { …}" for each of these fields would prevent the application from crashing.

I ran into this problem as well. I was able to work around it by creating my own “RoomInfoSubset” object that does its own disco#info query on a room, then just pulls out the features and FormFields that I care about (with null checking!) I definitely shouldn’t have to do this, but it works.

RoomInfoSubset(XMPPConnection connection, String roomJid) throws XMPPException
    {
        DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(roomJid);

        passwordProtected = info.containsFeature("muc_passwordprotected");

        Form form = Form.getFormFrom(info);
        topic = "";
        if (form != null)
        {
            FormField field = form.getField("muc#roominfo_subject");
            if (field != null)
            {
                Iterator values = field.getValues();

                if (values.hasNext())
                {
                    topic = values.next();
                }
            }
        }
    }

Something like that is how I get the values to indicate whether the room is password protected, and the room’s subject. My object also has getters (obviously.) If there is a better way to do this when there is a risk of null fields, I’d love to hear it - as it is, the RoomInfo object is only marginally useful if there is any chance your app will be run using any XMPP server other than openfire. I never had a problem with openfire, but ran into this issue hitting Jabber’s XCP server.

This still hasn’t been fixed in 3.2.2…

Its an easy enough workaround but its an even easier fix to implement.

Starting at line 92 of RoomInfo this code needs to replace that block in case of any empty element.

FormField descField = form.getField(“muc#roominfo_description”);

if (descField != null){

Iterator it = descField.getValues();

while (it.hasNext()) {

String val = it.next();

if (val != null && val.length() > 0) {

this.description = (descField == null || !(it.hasNext())) ? “” : val;

break;

}

}

}

FormField subjField = form.getField(“muc#roominfo_subject”);

if (subjField != null){

Iterator it = subjField.getValues();

while (it.hasNext()) {

String val = it.next();

if (val != null && val.length() > 0) {

this.subject = (subjField == null || !(it.

hasNext())) ? “” : val;

break;

}

}

}

FormField occCountField = form.getField(“muc#roominfo_occupants”);

if (occCountField != null){

Iterator it = occCountField.getValues();

while (it.hasNext()) {

String val = it.next();

if (val != null && val.length() > 0) {

this.occupantsCount = occCountField == null ? -1

: Integer.parseInt(val);

break;

}

}

}

Are you sure you are using 3.2.2. This was fixed in March 2011 (commit 12200) , there is even a test case to validate that an empty data form will still parse. It will return empty strings for those fields.

This is what that bit of code currently looks like.

if (form != null) {

FormField descField = form.getField(“muc#roominfo_description”);

this.description = ( descField == null || !(descField.getValues().hasNext()) )? “” : descField.getValues().next();

FormField subjField = form.getField(“muc#roominfo_subject”);

this.subject = ( subjField == null || !(subjField.getValues().hasNext()) ) ? “” : subjField.getValues().next();

FormField occCountField = form.getField(“muc#roominfo_occupants”);

this.occupantsCount = occCountField == null ? -1 : Integer.parseInt(occCountField.getValues()

.next());

}

1 Like

According to http://xmpp.org/extensions/xep-0128.html a field is able to have multiple value elements which causes the code below:

FormField occCountField = form.getField(“muc#roominfo_occupants”);

this.occupantsCount = occCountField == null ? -1 : Integer.parseInt(occCountField.getValues()

.next());

to be incorrect in some cases…

In the server implementation I am working against I occasionally run across an empty ‘value’ element that causes the above line to fail.

Such an example is:

0

Granted I don’t understand why the server does it this way, but according to the schema it is technically valid.

To my understanding (and I admit, this could be wrong), the only reason the schema allows it is so the single field schema can support any field type, including types for both single and multiple values.

The determination for the number of values present in a result, and for that matter the content itself in list cases, is determined by the field type of the form, not the schema. Which makes the example you provided incorrect, in that the field type is specified as text-single.

If your example had two actual values, then we would have no idea which one should be chosen.

That makes sense, I just know the server I’m hitting had that blank field in it and if there was some kind of check to verify that you don’t have an empty or non-number value then an error wouldn’t get thrown.

The code snippet above will at least let anyone else be aware of this issue if the xmpp server they are hitting happens to give them that strange behavior as well.