HashBiMap SerializationException或如何序列化IsSerializable不适用的类?

时间:2013-01-03 10:29:58

标签: gwt serialization guava

问题似乎并非所有Guava类都可以开箱即用。

我找到了一个非常好的解决方案,并希望分享它。 (在本例中为HashBiMap)。 (也许一些番石榴开发者可能会将这一天应用到理想的所有类中)

如果您复制以下类(并可能将其调整为您的可序列化类),您将在Javadoc注释中获得进一步的调查详细信息。

package com.google.common.collect;

import java.util.LinkedHashMap;
import java.util.Map;

import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
import com.google.gwt.user.client.rpc.core.java.util.Map_CustomFieldSerializerBase;

/**
 * idea taken from some <a href=
 * "http://code.google.com/r/baggiogamp-guava/source/browse/gwt-src/com/google/common/collect/RegularImmutableBiMap_CustomFieldSerializer.java?r=a7aa10ddb815ce7996f3fae103bfd3823b1336ed&spec=svn6923b5fac0feb7005429d0b24be93b91685f9637"
 * >com/google/common/collect/RegularImmutableBiMap_CustomFieldSerializer.java</
 * a> <br/>
 * Problem was, that {@link HashBiMap} seems not to be serializable for GWT:
 * <ul>
 * <li>it nor its super classes do not implement com.google.gwt.user.client.rpc.IsSerializable (why?)</li>
 * <li>the following solution does not work if only applied to some super class, e.g. AbstractBiMap</li>
 * </ul>
 * <pre>
 * com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: The response could not be deserialized
    at com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter.onResponseReceived(RequestCallbackAdapter.java:221)
    at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:287)
    at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:395)
    at sun.reflect.GeneratedMethodAccessor119.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:338)
    at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:219)
    at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
    at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:571)
    at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:279)
    at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
    at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
    at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:242)
    at sun.reflect.GeneratedMethodAccessor116.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293)
    at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
    at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
    at java.lang.Thread.run(Unknown Source)
Caused by: com.google.gwt.user.client.rpc.SerializationException: com.google.common.collect.HashBiMap/1352983899
    at com.google.gwt.user.client.rpc.impl.SerializerBase.getTypeHandler(SerializerBase.java:153)
    at com.google.gwt.user.client.rpc.impl.SerializerBase.instantiate(SerializerBase.java:114)
    at com.google.gwt.user.client.rpc.impl.ClientSerializationStreamReader.deserialize(ClientSerializationStreamReader.java:396)
    at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:119)
    at mycomp.shared.conf.Config_FieldSerializer.deserialize(Config_FieldSerializer.java:12)
    at mycomp.shared.conf.Config_FieldSerializer.deserial(Config_FieldSerializer.java:35)
    at com.google.gwt.user.client.rpc.impl.SerializerBase.deserialize(SerializerBase.java:95)
    at com.google.gwt.user.client.rpc.impl.ClientSerializationStreamReader.deserialize(ClientSerializationStreamReader.java:398)
    at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:119)
    at com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter$ResponseReader$8.read(RequestCallbackAdapter.java:106)
    at com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter.onResponseReceived(RequestCallbackAdapter.java:214)
    at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:287)
    at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:395)
    at sun.reflect.GeneratedMethodAccessor119.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:338)
    at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:219)
    at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
    at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:571)
    at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:279)
    at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
    at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
    at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:242)
    at sun.reflect.GeneratedMethodAccessor116.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293)
    at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
    at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
    at java.lang.Thread.run(Unknown Source)
 * </pre>
 * 
 * @author ADietrich
 * 
 */
public class HashBiMap_CustomFieldSerializer {

    public static void deserialize(SerializationStreamReader reader,
        HashBiMap<?, ?> instance) {
    }

    public static HashBiMap<Object, Object> instantiate(
            SerializationStreamReader reader) throws SerializationException {
        Map<Object, Object> entries = new LinkedHashMap<Object, Object>();
        Map_CustomFieldSerializerBase.deserialize(reader, entries);
        return HashBiMap.create(entries);
    }

    public static void serialize(SerializationStreamWriter writer,
        HashBiMap<?, ?> instance) throws SerializationException {
        Map_CustomFieldSerializerBase.serialize(writer, instance);
        }
}

1 个答案:

答案 0 :(得分:0)

实施Serializable仅适用于specially designed classes。番石榴的课程不是那样设计的(出于各种原因)。因此,我们需要为每个班级添加特殊支持。我们已经为某些课程完成了这项工作,我们可以为其他课程做到这一点,尽管存在权衡。我们有a feature request for GWT serialization,您可以在其中阅读更多详细信息并提出请求。但是,我首先考虑在RPC接口中使用ImmutableBiMap而不是HashBiMap。与大多数不可变类型一样,ImmutableBiMap已经是GWT可序列化的。