Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
doujutun3207
flink
提交
761d0a02
F
flink
项目概览
doujutun3207
/
flink
与 Fork 源项目一致
从无法访问的项目Fork
通知
24
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
flink
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
761d0a02
编写于
9月 02, 2016
作者:
S
Stephan Ewen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[FLINK-4567] [runtime] Enhance SerializedThrowable to properly mimic Exception causes
上级
c251efca
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
83 addition
and
45 deletion
+83
-45
flink-runtime/src/main/java/org/apache/flink/runtime/util/SerializedThrowable.java
...va/org/apache/flink/runtime/util/SerializedThrowable.java
+44
-44
flink-runtime/src/test/java/org/apache/flink/runtime/util/SerializedThrowableTest.java
...rg/apache/flink/runtime/util/SerializedThrowableTest.java
+39
-1
未找到文件。
flink-runtime/src/main/java/org/apache/flink/runtime/util/SerializedThrowable.java
浏览文件 @
761d0a02
...
...
@@ -21,18 +21,19 @@ package org.apache.flink.runtime.util;
import
org.apache.flink.util.ExceptionUtils
;
import
org.apache.flink.util.InstantiationUtil
;
import
java.io.IOException
;
import
java.io.PrintStream
;
import
java.io.PrintWriter
;
import
java.io.Serializable
;
import
java.lang.ref.WeakReference
;
import
java.util.HashSet
;
import
java.util.Set
;
/**
* Utility class for dealing with user-defined Throwable types that are serialized (for
* example during RPC/Actor communication), but cannot be resolved with the default
* class loader.
*
<p>
* This exception mimics the original exception with respect to message and stack trace,
*
*
<p>
This exception mimics the original exception with respect to message and stack trace,
* and contains the original exception in serialized form. The original exception
* can be re-obtained by supplying the appropriate class loader.
*/
...
...
@@ -49,10 +50,6 @@ public class SerializedThrowable extends Exception implements Serializable {
/** The original stack trace, to be printed */
private
final
String
fullStingifiedStackTrace
;
/** A guaranteed serializable placeholder exception that will be used as
* cause and to capture the original stack trace */
private
final
Exception
placeholder
;
/** The original exception, not transported via serialization,
* because the class may not be part of the system class loader.
* In addition, we make sure our cached references to not prevent
...
...
@@ -66,33 +63,43 @@ public class SerializedThrowable extends Exception implements Serializable {
* @param exception The exception to serialize.
*/
public
SerializedThrowable
(
Throwable
exception
)
{
this
(
exception
,
new
HashSet
<
Throwable
>());
}
private
SerializedThrowable
(
Throwable
exception
,
Set
<
Throwable
>
alreadySeen
)
{
super
(
getMessageOrError
(
exception
));
if
(!(
exception
instanceof
SerializedThrowable
))
{
this
.
cachedException
=
new
WeakReference
<
Throwable
>(
exception
);
this
.
originalErrorClassName
=
exception
.
getClass
().
getName
();
this
.
fullStingifiedStackTrace
=
ExceptionUtils
.
stringifyException
(
exception
);
this
.
placeholder
=
new
Exception
(
"Serialized representation of "
+
originalErrorClassName
+
": "
+
getMessage
());
this
.
placeholder
.
setStackTrace
(
exception
.
getStackTrace
());
initCause
(
this
.
placeholder
);
// serialize and memoize the original message
byte
[]
serialized
;
try
{
serialized
=
InstantiationUtil
.
serializeObject
(
exception
);
}
catch
(
Throwable
t
)
{
// could not serialize exception. send the stringified version instead
try
{
serialized
=
InstantiationUtil
.
serializeObject
(
placeholder
);
}
catch
(
IOException
e
)
{
// this should really never happen, as we only serialize a a standard exception
throw
new
RuntimeException
(
e
.
getMessage
(),
e
);
}
serialized
=
null
;
}
this
.
serializedException
=
serialized
;
this
.
cachedException
=
new
WeakReference
<
Throwable
>(
exception
);
// record the original exception's properties (name, stack prints)
this
.
originalErrorClassName
=
exception
.
getClass
().
getName
();
this
.
fullStingifiedStackTrace
=
ExceptionUtils
.
stringifyException
(
exception
);
// mimic the original exception's stack trace
setStackTrace
(
exception
.
getStackTrace
());
// mimic the original exception's cause
if
(
exception
.
getCause
()
==
null
)
{
initCause
(
null
);
}
else
{
// exception causes may by cyclic, so we truncate the cycle when we find it
if
(
alreadySeen
.
add
(
exception
))
{
// we are not in a cycle, yet
initCause
(
new
SerializedThrowable
(
exception
.
getCause
(),
alreadySeen
));
}
}
}
else
{
// copy from that serialized throwable
...
...
@@ -100,38 +107,36 @@ public class SerializedThrowable extends Exception implements Serializable {
this
.
serializedException
=
other
.
serializedException
;
this
.
originalErrorClassName
=
other
.
originalErrorClassName
;
this
.
fullStingifiedStackTrace
=
other
.
fullStingifiedStackTrace
;
this
.
placeholder
=
other
.
placeholder
;
this
.
cachedException
=
other
.
cachedException
;
}
}
public
Throwable
deserializeError
(
ClassLoader
classloader
)
{
if
(
serializedException
==
null
)
{
// failed to serialize the original exception
// return this SerializedThrowable as a stand in
return
this
;
}
Throwable
cached
=
cachedException
==
null
?
null
:
cachedException
.
get
();
if
(
cached
==
null
)
{
try
{
cached
=
InstantiationUtil
.
deserializeObject
(
serializedException
,
classloader
);
cachedException
=
new
WeakReference
<
Throwable
>(
cached
);
}
catch
(
Exception
e
)
{
return
placeholder
;
catch
(
Throwable
t
)
{
// something went wrong
// return this SerializedThrowable as a stand in
return
this
;
}
}
return
cached
;
}
public
String
getStrigifiedStackTrace
()
{
return
fullStingifiedStackTrace
;
}
// ------------------------------------------------------------------------
// Override the behavior of Throwable
// ------------------------------------------------------------------------
@Override
public
Throwable
getCause
()
{
return
placeholder
;
}
@Override
public
void
printStackTrace
(
PrintStream
s
)
{
s
.
print
(
fullStingifiedStackTrace
);
...
...
@@ -150,15 +155,10 @@ public class SerializedThrowable extends Exception implements Serializable {
return
(
message
!=
null
)
?
(
originalErrorClassName
+
": "
+
message
)
:
originalErrorClassName
;
}
@Override
public
StackTraceElement
[]
getStackTrace
()
{
return
placeholder
.
getStackTrace
();
}
// ------------------------------------------------------------------------
// Static utilities
// ------------------------------------------------------------------------
public
static
Throwable
get
(
Throwable
serThrowable
,
ClassLoader
loader
)
{
if
(
serThrowable
instanceof
SerializedThrowable
)
{
return
((
SerializedThrowable
)
serThrowable
).
deserializeError
(
loader
);
...
...
@@ -166,7 +166,7 @@ public class SerializedThrowable extends Exception implements Serializable {
return
serThrowable
;
}
}
private
static
String
getMessageOrError
(
Throwable
error
)
{
try
{
return
error
.
getMessage
();
...
...
flink-runtime/src/test/java/org/apache/flink/runtime/util/SerializedThrowableTest.java
浏览文件 @
761d0a02
...
...
@@ -131,10 +131,48 @@ public class SerializedThrowableTest {
// deserialize the proper exception
Throwable
deserialized
=
copy
.
deserializeError
(
loader
);
assertEquals
(
clazz
,
deserialized
.
getClass
());
// deserialization with the wrong classloader does not lead to a failure
Throwable
wronglyDeserialized
=
copy
.
deserializeError
(
getClass
().
getClassLoader
());
assertEquals
(
ExceptionUtils
.
stringifyException
(
userException
),
ExceptionUtils
.
stringifyException
(
wronglyDeserialized
));
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
}
}
}
@Test
public
void
testCauseChaining
()
{
Exception
cause2
=
new
Exception
(
"level2"
);
Exception
cause1
=
new
Exception
(
"level1"
,
cause2
);
Exception
root
=
new
Exception
(
"level0"
,
cause1
);
SerializedThrowable
st
=
new
SerializedThrowable
(
root
);
assertEquals
(
"level0"
,
st
.
getMessage
());
assertNotNull
(
st
.
getCause
());
assertEquals
(
"level1"
,
st
.
getCause
().
getMessage
());
assertNotNull
(
st
.
getCause
().
getCause
());
assertEquals
(
"level2"
,
st
.
getCause
().
getCause
().
getMessage
());
}
@Test
public
void
testCyclicCauseChaining
()
{
Exception
cause3
=
new
Exception
(
"level3"
);
Exception
cause2
=
new
Exception
(
"level2"
,
cause3
);
Exception
cause1
=
new
Exception
(
"level1"
,
cause2
);
Exception
root
=
new
Exception
(
"level0"
,
cause1
);
// introduce a cyclic reference
cause3
.
initCause
(
cause1
);
SerializedThrowable
st
=
new
SerializedThrowable
(
root
);
assertArrayEquals
(
root
.
getStackTrace
(),
st
.
getStackTrace
());
assertEquals
(
ExceptionUtils
.
stringifyException
(
root
),
ExceptionUtils
.
stringifyException
(
st
));
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录