使用 RPC 记录的异常抛出 IncompatibleRemoteServiceException

Posted

技术标签:

【中文标题】使用 RPC 记录的异常抛出 IncompatibleRemoteServiceException【英文标题】:Exceptions logged with RPC are throwing IncompatibleRemoteServiceException 【发布时间】:2013-04-03 14:16:12 【问题描述】:

没错,基础知识,这是在 GWT2.5.0 / JDK1.6 上运行的,并且或多或少地按照文档的设置进行设置

gwt.xml

<inherits name="com.google.gwt.logging.Logging" />

<set-property name="gwt.logging.simpleRemoteHandler"
    value="ENABLED" />
<set-property name="gwt.logging.logLevel" value="INFO" />
<set-property name="gwt.logging.enabled" value="TRUE" />
<set-property name="gwt.logging.developmentModeHandler"
    value="ENABLED" />
<set-property name="gwt.logging.systemHandler" value="DISABLED" />
<set-property name="gwt.logging.popupHandler" value="DISABLED" />
<set-property name="gwt.logging.consoleHandler" value="ENABLED" />
<set-property name="gwt.logging.firebugHandler" value="ENABLED" />

我用下面的代码强制异常,只是一个简单的 NullPointException

     try 
        Level n = null;
        n.getName();
       catch (NullPointerException ex)              
        logger.log(Level.SEVERE, "Null Exception Hit", ex);
      

但是由于某种原因,当向服务器抛出异常时会抛出这个

[WARN] remoteLogging: An IncompatibleRemoteServiceException was thrown while processing this call.
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: Type 'com.google.gwt.core.client.impl.SerializableThrowable' was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field serializer. For security purposes, this type will not be deserialized.
at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:323)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:206)

RPC servlet 已正确配置,如果我只抛出消息而不是异常,它会很好地记录回服务器。

根据远程服务器日志记录的文档,这应该“正常工作”,我不明白为什么会出现这种情况。在我看来,SerializableThrowable 根据定义应该是可序列化的。我知道您必须跳过一些障碍才能使您自己的类可序列化,但是我读过的所有内容都表明我应该能够毫无问题地将异常抛回服务器。有任何想法吗?从 2.5.0 开始,serializableThrowable 似乎已移至 com.google.gwt.core.shared.SerializableThrowable,但我不认为这样做。

【问题讨论】:

【参考方案1】:

因为 Exception 的超类是 Throwable 并且它实现了 java.io.Serializable

需要注意的重要一点是,在完整的 Java JRE 中实现 java.io.Serializable 的类都没有在 GWT 的模拟 JRE 中实现 java.io.Serializable。这意味着在 JRE 中实现 java.io.Serializable 的 类型(如 Throwable 或 StackTraceElement)将无法通过 GWT RPC 跨网络传输,因为客户端无法序列化/反序列化它们。但是,对于其他类型(如 String、Number 等)来说,这不是问题……它们没有在模拟的 JRE 中实现 java.io.Serializable 但具有自定义字段序列化器,以便它们可以正确序列化。

GWT serialization policy

【讨论】:

它并没有抱怨 Throwable,而是将抛出的异常识别为类型“com.google.gwt.core.client.impl.SerializableThrowable”并抱怨它不能分配给“com.google.gwt”。 user.client.rpc.IsSerializable' 这可能是由于运行时发生的。我知道的是 GWT 无法处理从 RuntimeException 扩展的未序列化的未经检查的异常。 顺便说明一下,向服务器抛出异常背后的需求是什么?(summa-tech.com/blog/2012/06/11/…)? 对,我已按照该链接上的说明进行操作,并且我的代码(包括我抛出异常的方式)直接取自 developers.google.com/web-toolkit/doc/latest/… 和 developers.google.com/web-toolkit/doc/latest/… 堆栈跟踪正在按顺序发回帮助查找和解决错误,而无需我们的用户自行通过电子邮件向我们发送错误。 似乎有问题,可能放置一张票会引起实施者的注意。

以上是关于使用 RPC 记录的异常抛出 IncompatibleRemoteServiceException的主要内容,如果未能解决你的问题,请参考以下文章

Spring AMQP RPC消费者并抛出异常

getDeclaredMethod 抛出异常

拦截 GWT RPC 的异步代理服务异常

Azure 函数应该记录错误还是抛出异常?

记录后重新抛出 UncaughtExceptionHandler 异常

运行时异常后 GWT RPC 调用不回滚事务