HashBiMap SerializationException 或如何序列化 IsSerializable 不适用的类?
Posted
技术标签:
【中文标题】HashBiMap SerializationException 或如何序列化 IsSerializable 不适用的类?【英文标题】:HashBiMap SerializationException or how to serialize classes where IsSerializable is not applicable? 【发布时间】:2013-01-03 10:29:58 【问题描述】:问题似乎是并非所有 Guava 类都可以开箱即用地序列化。
我找到了一个很好的解决方案并喜欢分享它。 (在这种情况下为 HashBiMap)。 (也许某些 Guava 开发人员有一天会将此应用到理想的所有类中)
如果您复制以下类(并可能将其调整为您的待序列化类),您将在 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);
【问题讨论】:
It's ok to ask and answer your own question,但你必须把它分成一个问题和一个答案帖子! 我想这样做,但新用户只能在 8 小时后回答自己的问题:-/ 我不明白。HashBiMap
是Serializable
,你用的是旧版本吗?
我不知道为什么它不起作用。您应该可以自己尝试使用一些包含空 HashBiMap
字段的类。 java.io.Serializable
vs. com.google.gwt.user.client.rpc.IsSerializable
... 这个答案说使用哪个并不重要:***.com/a/3065519/1915920,但是当我开始我的第一个 GWT 项目时,我发现了与 BiMap 无关的案例使用后者(但也许这只是我在摆弄各种可能性后的解释:-))
对此的正确回应是向 Guava 提交错误报告。
【参考方案1】:
实现Serializable
仅对specially designed classes 就足够了。 Guava 的类不是这样设计的(出于各种原因)。因此,我们需要为每个单独的类添加特殊支持。我们已经为某些课程做到了这一点,我们也可以为其他课程做到这一点,尽管有一些权衡。我们有a feature request for GWT serialization,您可以在其中阅读更多详细信息并提出请求。但是,我首先会考虑在您的 RPC 接口中使用ImmutableBiMap
,而不是HashBiMap
。 ImmutableBiMap
和大多数不可变类型一样,已经是 GWT 可序列化的。
【讨论】:
(抱歉-现在才看到答案。我没有收到您的帖子的提醒。)非常感谢您的建议,尽管如果我想在客户端上操作地图可能会出现问题-侧面(可能或多或少)!以上是关于HashBiMap SerializationException 或如何序列化 IsSerializable 不适用的类?的主要内容,如果未能解决你的问题,请参考以下文章