diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java index cf9ad0415..ca2fb0389 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java @@ -1424,7 +1424,21 @@ public final class Roster extends Manager { // means that rosterver was used and the roster hasn't changed (much) since the // version we presented the server. So we simply load the roster from the store and // await possible further roster pushes. - for (RosterPacket.Item item : rosterStore.getEntries()) { + List storedItems = rosterStore.getEntries(); + if (storedItems == null) { + // The roster store was corrupted. Reset the store and reload the roster without using a roster version. + rosterStore.resetStore(); + try { + reload(); + } catch (NotLoggedInException | NotConnectedException + | InterruptedException e) { + LOGGER.log(Level.FINE, + "Exception while trying to load the roster after the roster store was corrupted", + e); + } + return; + } + for (RosterPacket.Item item : storedItems) { RosterEntry entry = new RosterEntry(item, Roster.this, connection); addUpdateEntry(addedEntries, updatedEntries, unchangedEntries, item, entry); } diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/DirectoryRosterStore.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/DirectoryRosterStore.java index aa0be4df1..816d87890 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/DirectoryRosterStore.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/DirectoryRosterStore.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -124,11 +125,10 @@ public final class DirectoryRosterStore implements RosterStore { for (File file : fileDir.listFiles(rosterDirFilter)) { Item entry = readEntry(file); if (entry == null) { - LOGGER.severe("Roster store file '" + file + "' is invalid."); - } - else { - entries.add(entry); + // Roster directory store corrupt. Abort and signal this by returning null. + return null; } + entries.add(entry); } return entries; @@ -179,6 +179,12 @@ public final class DirectoryRosterStore implements RosterStore { return setRosterVersion(version); } + + @Override + public void resetStore() { + resetEntries(Collections.emptyList(), ""); + } + private static Item readEntry(File file) { Reader reader; try { @@ -212,4 +218,5 @@ public final class DirectoryRosterStore implements RosterStore { String encodedJid = Base32.encode(bareJid.toString()); return new File(fileDir, ENTRY_PREFIX + encodedJid); } + } diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/RosterStore.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/RosterStore.java index ab7e39649..068c31c3f 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/RosterStore.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/RosterStore.java @@ -70,4 +70,10 @@ public interface RosterStore { */ public boolean removeEntry(Jid bareJid, String version); + /** + * Reset the store by removing all entries and setting the version to the empty String. + * + * @since 4.2 + */ + public void resetStore(); }