串行化java.lang.Throwable以及堆栈跟踪,导致链和相关的堆栈跟踪 [英] Serialize java.lang.Throwable along with stack trace, causes chain and related stack traces

查看:184
本文介绍了串行化java.lang.Throwable以及堆栈跟踪,导致链和相关的堆栈跟踪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写 GWT 应用程序,我需要发送 java.lang.Throwable 的实例(其链为导致和所有分别使用堆栈跟踪)使用标准Java序列化机制(就我而言)的 GWT RPC



问题是当我从客户端传递以下示例异常

  java.lang。由
引起的RuntimeException(message = null,stacktrace A)由
引起的java.io.IOException(message =io的问题,stacktrace B)引起的java.lang.IllegalStateException(message =某些错误文本,stacktrace C),cause = null

在服务器上以下内容:

  java.lang.RuntimeException(message =java.io.IOException:io的问题,stacktrace X) cause = this 

其中 stacktrace X 堆栈跟踪l这个异常在服务器上被反序列化的位置,即不考虑原始堆栈跟踪A,B或C.所以堆栈跟踪信息与原因链一起丢失。



阅读精湛的文章 7 GWT中的异常处理提示发现


异常是暂时的,所以从客户端到服务器也是如此(所以如果你需要在服务器端发送它作为一个单独的参数)




经过一番谷歌搜索,我得出结论,使用标准Java序列化技术的完全序列化/反序列化 java.lang.Throwable 实例的主题是不太受欢迎。实际上,我找不到图书馆和博客都没有详细描述如何实现这一点。



有没有人坚持下来解决这个问题?有没有任何建议的解决方案这个问题?



提前感谢

解决方案

好的,找到一个优雅简单的解决方案来解决我的问题:在 GWT 2.5.1 中,有一个专门针对这些需求设计的类,名为 com.google.gwt.core .client.impl.SerializableThrowable 与以下JavaDoc:


仿效的Throwable类不会递归序列化Throwables,不串行化堆栈跟踪。这个类是一个替代,可以通过为包含Throwable的类编写一个自定义序列化器来使用。请参阅LogRecord_CustomFieldSerializer作为示例。


所以,解决我的问题的代码片段如下:

  //客户端
LogServiceAsync logService = GWT.create(LogService.class);

GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler(){

@Override
public void onUncaughtException(final Throwable ex){
//换行在SerializableThrowable中保存
//序列化后的原因和堆栈跟踪
SerializableThrowable serializableEx = new SerializableThrowable(ex);
//将SerializableThrowable发送到服务器
logService.log(serializableEx ,callbackCodeDoesntMatter);
}
}

//服务器端
public class LogServiceServlet extends RemoteServiceServlet implements LogService {

@Override
public void log(final SerializableThrowable ex){
//获取原始实例Throwable与保留的
//原因和堆栈跟踪
可抛出的originalThrowable = ex.getThrowable();
originalThrowable.printStackTrace();
}
}

如果以这种方式实现,它会打印正确的堆栈跟踪信息以及正确的原因。



注意 GWT 2.6.0 com.google.gwt.core.client.impl.SerializableThrowable 不赞成使用 com.google.gwt.core.shared.SerializableThrowable 与第一个不同,只能稍微起作用,并且应该同样工作。 p>

I'm writing GWT application where I need to send instance of java.lang.Throwable (with chain of it's causes and all stack traces respectively) using GWT RPC which uses standard Java serialization mechanism (as far as I'm concerned).

The problem is that when I pass following sample exception from client:

java.lang.RuntimeException (message=null, stacktrace A) caused by
java.io.IOException (message="Problems with io", stacktrace B) caused by
java.lang.IllegalStateException (message="Some error text", stacktrace C), cause=null

on the server I get the following:

java.lang.RuntimeException (message="java.io.IOException: Problems with io", stacktrace X) cause=this

where stacktrace X is simply stack trace leading to place where this exception was deserialized on the server i.e. with no regards to original stack traces A, B or C. So stacktrace information is lost along with causes chain.

After reading superb article 7 Tips for Exception Handling in GWT it was found out that

the stack trace within an exception is transient, and so is lost from client to server (so if you need it on the server side, send it as a separate parameter)

After a bit of googling, I came to conclusion that topic of fully serializing/deserializing instances of java.lang.Throwable using standard Java serialization technique is not so popular. Actually I couldn't find neither libraries nor blogs with detailed description on how to achieve this.

Has anybody stucked upon and solved such problem before? Are there any suggested solutions to this problem?

Thanks in advance!

解决方案

Ok, found an elegant and simple solution to my problem: in GWT 2.5.1 there is a class designed specifically for those needs called com.google.gwt.core.client.impl.SerializableThrowable with following JavaDoc:

The emulated Throwable class does not serialize Throwables recursively and does not serialize the stack trace. This class is an alternative, and can be used by writing a custom serializer for the class which contains a Throwable. See LogRecord_CustomFieldSerializer as an example.

So, code snippet solving my problem is the following:

// client-side
LogServiceAsync logService = GWT.create(LogService.class);

GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {

    @Override
    public void onUncaughtException(final Throwable ex) {
        // wrapping throwable in SerializableThrowable to preserve 
        // causes and stack traces upon serialization
        SerializableThrowable serializableEx = new SerializableThrowable(ex);
        // sending instance of SerializableThrowable to server
        logService.log(serializableEx, callbackCodeDoesntMatter);
    }
}

// server-side
public class LogServiceServlet extends RemoteServiceServlet implements LogService {

    @Override
    public void log(final SerializableThrowable ex) {
        // getting original instance Throwable with preserved
        // causes and stack traces
        Throwable originalThrowable = ex.getThrowable();
        originalThrowable.printStackTrace();
    }
}

If implemented in this way, it prints correct stack trace info along with correct causes.

NOTE In GWT 2.6.0 class com.google.gwt.core.client.impl.SerializableThrowable is deprecated in favor of com.google.gwt.core.shared.SerializableThrowable which differs from the first one only slightly and should work similarly.

这篇关于串行化java.lang.Throwable以及堆栈跟踪,导致链和相关的堆栈跟踪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆