GWT - 偶尔出现 com.google.gwt.user.client.rpc.SerializationException

Posted

技术标签:

【中文标题】GWT - 偶尔出现 com.google.gwt.user.client.rpc.SerializationException【英文标题】:GWT - occasional com.google.gwt.user.client.rpc.SerializationException 【发布时间】:2011-01-08 12:44:38 【问题描述】:

我们会被偶尔出现的异常所困扰,例如:

com.google.gwt.user.client.rpc.SerializationException:类型“xxx”不可分配给“com.google.gwt.user.client.rpc.IsSerializable”并且没有自定义字段序列化程序。对于出于安全考虑,此类型不会被序列化。例如:instance = xxx 在 com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:610) 在 com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:129) 在 com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter$ValueWriter$8.write(ServerSerializationStreamWriter.java:152) 在 com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeValue(ServerSerializationStreamWriter.java:534) 在 com.google.gwt.user.server.rpc.RPC.encodeResponse(RPC.java:609) 在 com.google.gwt.user.server.rpc.RPC.encodeResponseForSuccess(RPC.java:467) 在 com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:564) 在 com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:188) 在 de.softconex.travicemanager.server.TraviceManagerServiceImpl.processCall(TraviceManagerServiceImpl.java:615) 在 com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:224) 在 com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:710) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:803) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 在 org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179) 在 org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 在 org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262) 在 org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:419) 在 org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:378) 在 org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1508) 在 java.lang.Thread.run(Thread.java:619)

应用程序正常运行。指示的类实现 Serializable(整个对象图)。

到目前为止,唯一的模式/观察结果是:

我们似乎只有在 iframe 中使用应用程序时才会出现问题

问题似乎是在部署新版本的应用程序时发生的

在隐私模式下运行 firefox(禁用所有缓存等)并不能解决问题

有什么想法吗?

霍尔格

【问题讨论】:

【参考方案1】:

你检查了吗http://code.google.com/webtoolkit/doc/latest/tutorial/RPC.html#serialize 文章说: 它有一个带有任何访问修饰符的默认(零参数)构造函数(例如private Foo() 将起作用)

我总是忘记 zeroargument const。当我制作一个可序列化的对象时:D

【讨论】:

哇,对于那个恕我直言,这不是最好的例外信息!?我一直在调试代码,可以看到我的班级没有进入白名单,但不知道为什么 - 太简单了! Kerem 所说的绝对是关键。我们遇到的另一个问题是您不应该尝试序列化内部类。所有被序列化的类本身应该是单独的类。 @Kerem 链接不再存在http://code.google.com/webtoolkit/doc/latest/tutorial/RPC.html#serialize【参考方案2】:

很可能的原因 - 旧版本的客户端仍然缓存在浏览器中。它发送 rpc 请求,但服务器已经重新启动并且具有更新版本的 rpc 文件 (*.symbolMap)

【讨论】:

是的,在干净的重建之后,我开始看到这个错误。在查看代码并验证所有 RPC 类都可序列化后,我清除了浏览器缓存,一切正常。【参考方案3】:

我在 Ubuntu Lucid amd64 中使用 Tomcat6 + Devmode 时遇到了问题。使用 com.google.gwt.user.client.rpc.IsSerializable 而不是 java.io.Serializable 似乎解决了这个问题。

【讨论】:

我可以确认这个问题。必须将所有 java.io.Serializable 转换为 GWT isSerializable 才能在 Linux 机器而不是 Windows 上托管应用程序。使用isSerializable,任何操作系统都可以。似乎并非所有排列都正确构建。 不仅在 linux 上,在 windows 上使用 glassfish 时也会发生这种情况 我确认此修复解决了我的问题。当直接连接到我的网站时,它已经在工作,但嵌入到 iPhone 或 android 应用程序中时,网络服务会出现此错误。通过使用 IsSerializable 它解决了问题 @Sven Does GWT isSerializable 将解决这个问题,而与操作系统和应用程序/Web 服务器无关,而不是 java.io.Serializable。【参考方案4】:

我假设您正在在本地主机在托管模式运行应用程序?如果是这样,您可能需要留意 work 目录(或者如果您不在 tomcat 服务器中运行应用程序,则为等效目录)。检查 webapp 的文件夹中的序列化策略文件 (*.gwt.rpc)。

它们可能没有正确加载,到目前为止我们发现的唯一解决方法是在每次序列化错误后重新启动服务器。

问题是由于 GWT 将在运行时生成其序列化策略文件,假设您在托管模式下运行。在编译模式下,GWT 将在编译时生成所有必要的文件。 AFAIK,tomcat 无法在运行时加载资源文件,因此不会在每次第一次需要时都包含序列化文件。

重新启动服务器时,tomcat 能够拾取之前生成的文件,因此您不应在重新启动后收到相同的错误。

你能验证一下吗?

【讨论】:

这就是在我的案例中实际发生的情况......我在没有 GWT 的情况下完全编译了服务器端应用程序,并希望在单独的步骤中执行此操作。我必须在编译 GWT 部分后重新启动应用程序服务器,然后一切正常:-) 感谢您的提示。【参考方案5】:

如果您在 JBoss 上运行,这可能是由于先前部署的应用程序在取消部署时没有被删除。要解决此问题,您必须在 JBoss 中修改以下文件: $JBOSS_HOME/server/default/deployers/jbossweb.deployer/META-INF/war-deployers-jboss-beans.xml 并将以下属性设置为 true:deleteWorkDirOnContextDestroy

如果之前部署的应用程序没有清理干净,GWT 可能会混淆它需要加载哪个 RPC 文件,最终导致那些 SerializationException

【讨论】:

【参考方案6】:

我遇到了同样的问题,我从另一个人那里找到了解决方案:

“有可能您有一个实现 Serializable 的类,并且您在该类中有一个不可序列化的属性字段,因此您可能会遇到此异常。”

非常感谢那个人:)

我的建议是让你的类中的所有字段(不是原始类型)也实现 Serializable!这解决了我的问题。

【讨论】:

刚刚遇到同样的问题。一切都很好,公共类实现了 Serializable 除了一个新的嵌入式私有类没有实现 Serializable。【参考方案7】:

当使用 JDK 1.7 编译 GWT 2.5 应用程序时会出现此问题。 GWT 2.5 支持 JDK 1.6,使用此版本的 JDK 将解决此问题。

【讨论】:

【参考方案8】:

所以 RPC 文件是独一无二的,因为它们由 servlet 加载并且在 GWT 中使用。请参阅http://code.google.com/webtoolkit/release-notes.html#Release_Notes_1_4_59,其中显示“此文件必须作为公共资源部署到您的 Web 服务器,可通过 ServletContext.getResource() 从 RemoteServiceServlet 访问”

是否有可能新应用程序正在动态重新加载并且 getResource 以某种方式失败?重新启动应用程序会解决问题吗?

【讨论】:

【参考方案9】:

我遇到了同样的错误,并通过清理浏览缓存和导航历史来解决此问题。

【讨论】:

在我的项目中,我设法通过删除文件夹gwt-unitCache 来解决它。 从技术上讲,这是因为@user2229686 所说的。【参考方案10】:

我也收到了 SerializationException,但我也看到此错误出现在序列化异常之前:

[正常运行时间报告/2.340102563369350884]。: 示例:错误:找不到模板 注册确认.vm

结果发现我的速度模板有问题。一旦我解决了这个问题,SerializationException 就不再出现了,所以如果您按照 Kerem 的建议仍然有问题,请在您的日志中查找其他异常。

【讨论】:

【参考方案11】:

了解确切问题的最佳方法是使用 -logLevel DEBUG 或 TRACE 编译代码并检查内部验证单元。我相信您也能够找出行号的确切问题。

【讨论】:

【参考方案12】:

首先确保您有一个“干净”的可序列化类,即空构造函数,没有实现可序列化的内部类,并且使用 GWT 可序列化类而不是 Java 可序列化类。 然后只需在隐身标签 (Chrome) 中打开您的网站即可解决问题。本地浏览器缓存导致加载旧的 rpc 文件。

【讨论】:

以上是关于GWT - 偶尔出现 com.google.gwt.user.client.rpc.SerializationException的主要内容,如果未能解决你的问题,请参考以下文章

“com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException”出现在控制台上

GWT 序列化异常

尽早避免 GWT 的 com.google.gwt.user.client.rpc.SerializationException 的最佳实践

com.google.gwt.view.client.Range 的 GWT SerializationException

GWT Servlet 错误 com.google.gwt.user.client.rpc .StatusCodeException: Tomcat 服务器上的 404

java.lang.NoClassDefFoundError: com/google/gwt/core/client/GWTBridge