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.