Я пытаюсь сериализовать некоторые объекты класса InstitutionResultView, который в основном является оболочкой для дерева гуавы TreeMultimap :
import java.io.Serializable;
import java.text.Collator;
import java.util.Comparator;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.collect.Maps.EntryTransformer;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Ordering;
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
public class InstitutionResultView implements Serializable {
private static final long serialVersionUID = -8110992296090587657L;
private final SortedSetMultimap<String, Institution> nameToInstitutionsMapping = TreeMultimap.create(
Ordering.from(StringComparators.AS_IS), // insertion order
Ordering.natural() // <----- this works when serializing object
// Ordering.from(Collator.getInstance()) // <----- when used instead previous line gives an exception when serializing
.nullsFirst().onResultOf(StringInstitutionFunctions.BY_NAME) // sort by name
.compound(
Ordering.natural().nullsFirst().onResultOf(IntegerInstitutionFunctions.BY_ID) // sort by id
));
public SortedSetMultimap<String, Institution> institutions() {
return nameToInstitutionsMapping;
}
public void setInstitutions(final Multimap<String, Institution> institutions) {
this.nameToInstitutionsMapping.clear();
this.nameToInstitutionsMapping.putAll(institutions);
}
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("nameToInstitutionsMapping", Multimaps.transformEntries(nameToInstitutionsMapping, EntryTransformers.TO_NAME_WITH_CATEGORY))
.toString();
}
Во время сериализации я получаю исключение:
java.io.NotSerializableException: java.text.RuleBasedCollator at
java.io.ObjectOutputStream.writeObject0 (ObjectOutputStream.java:1164)
на
...
com.google.common.collect.TreeMultimap.writeObject (TreeMultimap.java:180)
...
Я обнаружил эту ошибку в базе данных ошибок Sun , которая охватывает очень похожий случай с моей, но не указывает на какое-либо разрешение. Я попытался добавить временное поле экземпляра Collator:
private transient Collator collatorInstance = Collator.getInstance();
и используя его как Ordering.from(collatorInstance)
, но все равно он не работает.
Буду рад, если кто-нибудь подскажет, что делать, чтобы решить эту проблему.
РЕДАКТИРОВАТЬ - Вот что сработало для меня (благодаря @Puce и его ответу):
class CollatorWrapper implements Comparator<String>, Serializable {
private static final long serialVersionUID = 1L;
private transient Collator collatorInstance;
public CollatorWrapper() {
super();
initCollatorInstance();
}
@Override
public int compare(final String o1, final String o2) {
return collatorInstance.compare(o1, o2);
}
private void initCollatorInstance() {
collatorInstance = Collator.getInstance();
}
private void writeObject(final java.io.ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initCollatorInstance();
}
}