Looks like RosterGroup.addEntry doesn’'t work in Smack 2.0 (latest sources)
Here is the test:
private static void testSetGroup() throws XMPPException {
XMPPConnection c = new XMPPConnection(“localhost”);
try {
try {
c.getAccountManager().createAccount(“bob”, “ddd”);
c.getAccountManager().createAccount(“alice”, “ddd”);
}
catch(Exception e){ // already exists?}
c.login(“bob”, “ddd”);
Roster bobRoster = c.getRoster();
bobRoster.createEntry(“alice@localhost”, “Alice”, new String[0]);
RosterGroup someGroup = bobRoster.createGroup(“someGroup”);
RosterEntry entry = bobRoster.getEntry(“alice@localhost”);
Assert.assertNotNull(entry);
someGroup.addEntry(entry);
Assert.assertTrue(someGroup.contains(entry));
c.close();
c = new XMPPConnection(“localhost”);
c.login(“bob”, “ddd”);
Assert.assertNotNull(c.getRoster().getGroup(“someGroup”));
} finally {
c.getAccountManager().deleteAccount();
}
}
/pre
The last assertion in this test fails.
To fix the problem, addEntry should be rewritten this way:
public void addEntry(RosterEntry entry) throws XMPPException {
PacketCollector collector = null;
// Only add the entry if it isn’'t already in the list.
synchronized (entries) {
if (!entries.contains(entry)) {
RosterPacket packet = new RosterPacket();
packet.setType(IQ.Type.SET);
RosterPacket.Item item = RosterEntry.toRosterItem(entry);
// Add this group name
item.addGroupName(getName());
packet.addRosterItem(item);
// Wait up to a certain number of seconds for a reply from the server.
collector = connection
.createPacketCollector(new PacketIDFilter(packet.getPacketID()));
connection.sendPacket(packet);
}
}
if (collector != null) {
IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
collector.cancel();
if (response == null) {
throw new XMPPException(“No response from the server.”);
}
// If the server replied with an error, throw an exception.
else if (response.getType() == IQ.Type.ERROR) {
throw new XMPPException(response.getError());
}
// Add the new entry to the group since the server processed the request successfully
addEntryLocal(entry);
}
}
/pre
Another issue is, that to prevent ConcurrentModificationException (I got it sometimes in multithreaded environment), the last statements in addEntry and removeEntry methods should use addEntryLocal and removeEntryLocal instead of plain access to ‘‘entries’’ list.
With kind regards,
KIR