XStream と Jettison を使用してグアバのマルチマップをシリアライズおよびデシリアライズしようとしています。説明する簡単なテストを次に示します。
final XStream xstream = new XStream(new JettisonMappedXmlDriver());
final Multimap<TestEnum, String> test = HashMultimap.create();
test.put(TestEnum.E1, "test");
final String json = xstream.toXML(test);
final Multimap<TestEnum, String> result = (Multimap<TestEnum, String>)xstream.fromXML(json);
次のエラーが発生します。
com.thoughtworks.xstream.converters.ConversionException: Could not call com.google.common.collect.HashMultimap.readObject() : com.test.Test$TestEnum cannot be cast to java.lang.Integer
---- Debugging information ----
message : Could not call com.google.common.collect.HashMultimap.readObject()
cause-exception : java.lang.ClassCastException
cause-message : com.test.Test$TestEnum cannot be cast to java.lang.Integer
class : com.google.common.collect.HashMultimap
required-type : com.google.common.collect.HashMultimap
converter-type : com.thoughtworks.xstream.converters.reflection.SerializableConverter
path : /com.google.common.collect.HashMultimap/com.google.common.collect.HashMultimap
line number : -1
version : 1.4.7
-------------------------------
このエラーは、enum キーを使用した場合に特に Multimap に焦点を当てていることに注意してください。multimap の代わりに Map を使用すると、エラーは発生しません。Enum の代わりに String をキーとして使用すると、エラーは発生しません。また、JSON の代わりに XML にシリアル化すると (つまり、コンストラクターで「JettisonMappedXmlDriver」を使用しない場合)、完全に機能します。
これに対する良い解決策はありますか?現在、マルチマップをコレクションのマップに置き換えるという回避策を使用していますが、マルチマップを維持する方法を見つけたいと考えています。