您的位置:首页 > 编程语言 > Java开发

关于 java.io.OptionalDataException

2016-07-15 17:13 573 查看
本文来自:http://jianghuguke.iteye.com/blog/939786

java.io.OptionalDataException

Java的对象传输是在一个keepalive连接上传输的,就是说建立一个网络连接后可以传输很多很多的对象实例。

譬如:A跟B通讯,A端write对象a,write对象b,write对象c;B端就要read对象a,read对象b,read对象c。

但是B端面对的是源源不断的数据,怎么才能区分出a和b的分界点呢,这个就是应用协议要解决的问题了。通用的解决方法是在write a前用一个商定的协议头,在协议头里描述数据的长度,通过这个长度来进行数据的定界。如果在write协议头的时候,序列化的a对象被修改了,那协议头的标识的长度和正式长度就不一致了,这样导致了a对象的部分数据会被read b的时候当作协议头,这样这个连接管道原来有序的数据分界就乱了,只有重置这个连接才能恢复。怎样才能重置这个连接呢,重启是最简单的办法了,重启连接的任何一端都可以。

什么情况下会出现“如果在write协议头的时候,序列化的a对象被修改”的情况呢,在并发环境下,一个线程在进行write对象a,另外一个线程在修改对象a就会导致这种情况。这种情况一般是因为应用使用非线程安全的类,譬如:HashMap,并且应用自身并发控制不严引起的。

定位问题的办法:

修改JDK 的library里的ObjectInputStream类,当出现StreamCorruptedException时把Stream里的前4K字节写到console ouput中。可以通过这个方法找到第一次破坏协议的序列化的内容,以这个序列化的内容作为线索找出应用问题发生的地方。在出现问题的系统上加上这个补丁。这个补丁需要使用-Xbootclasspath来设置,影响JVM boot ClassLoader.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 异常