1

I'm running guava-14.0.1 and I have the following code:

public class LinearClsMalletAdaptor extends Classifier implements Serializable{
    private BiMap<Double, String> indexToLabel;
.........

classifier = new LinearClsMalletAdaptor(sp, model, hashBiMap.inverse());

classifier is the object I wish to persist, and I have no problems with serializing and deserializing it on my Mac.

However, using the same serialized file I sent my friend, he encountered the following problem on Windows machine during deserialization:

java.lang.ClassCastException: com.google.common.collect.HashBiMap cannot be cast to 

    com.google.common.collect.AbstractBiMap
           at com.google.common.collect.AbstractBiMap$Inverse.readObject(AbstractBiMap.java:390)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
           at java.lang.reflect.Method.invoke(Method.java:597)
           at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
           at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
           at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
           at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
           at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
           at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
           at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
           at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
           at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
           at java.util.HashMap.readObject(HashMap.java:1030)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
           at java.lang.reflect.Method.invoke(Method.java:597)
           at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
           at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
           at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
           at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
           at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
           at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
           at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
           at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
           at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
           at sg.edu.astar.i2r.batc.projects.getme.core.classify.hier.topdown.TopDownClassificationAnnotator.initialize(TopDownClassificationAnnotator.java:63)
           at 

If he performs the serialization on his own machine, then this problem does not occur. I'm a little confused, is the HashBiMap class serializable? The api docs says

A HashBiMap and its inverse are both serializable.

But this discussion over here seems to confuse a little?

Community
  • 1
  • 1
goh
  • 27,631
  • 28
  • 89
  • 151

2 Answers2

1

As chrylis and Tasm suggest, the problem is a mismatch between Guava versions. One version of Guava cannot necessarily read an object serialized by another. (Source: the Guava homepage, which says: "Serialized forms of ALL objects are subject to change. Do not persist these and assume they can be read by a future version of the library.")

You can deduce that the versions are different because HashBiMap used to extend AbstractBiMap but no longer does.

(By the way, your link to the confusing discussion is confusing because it's about GWT serialization, which is separate from plain Java serialization. It's not involved here. That discussion ought to be a clearer about that than it is.)

Community
  • 1
  • 1
Chris Povirk
  • 3,738
  • 3
  • 29
  • 47
  • Chris, I dunno, at least it seems that maven is reporting that I'm using 14.0.1 on both machines – goh Oct 01 '13 at 03:12
  • Hmm, then I wonder if there are multiple versions of Guava present on one of the machines. Let's see what we can find out about `HashBiMap` by evaluating a couple expressions on each machine: (1) `HashBiMap.class.getProtectionDomain().getCodeSource().getLocation()`. That should point you at the jar that the classes are found in. (2) `HashBiMap.class.getSuperclass()`. That should show whether the class extends `AbstractBiMap` in each case or not. – Chris Povirk Oct 01 '13 at 15:34
0

HashBiMap is serializable

public final class HashBiMap<K, V> extends AbstractMap<K, V> implements BiMap<K, V>, Serializable

There is another issue look at stack. You are trying to deserialize different object.

I mean this file contains another class AbstractBiMap and you are expecting BiMap.

BiMap have nothing in common with AbstractBiMap.

Only EnumBiMap EnumHashBiMap and Inverse extends AbstractBiMap

Of course I'm talking about guava 14.0.1 so make sure that in both cases you are using same guava version.

Tasm
  • 249
  • 1
  • 7