オブジェクト直列化ストリームプロトコル
Javaでオブジェクトをネットワーク越しに転送したりする時に使用するものに、オブジェクトの直列化があります。これはRMIやEJBの呼び出しにも使われている。
今回RMIのトラブルがあり、不具合を解析するためにTCPダンプでデータを取得し、オブジェクト直列化ストリームプロトコルの解析を実施した。
久しぶりにこれを実施したのですが、いつ見てもわかりにくいプロトコルです。
http://java.sun.com/j2se/1.5.0/ja/docs/ja/guide/serialization/spec/protocol.html#10258
整理されていて綺麗なんでしょうが、こっちはマシンではないので、インデントをつけたり並び替えをやって少し見やすくした(つもり)。
stream: magic version contents magic: STREAM_MAGIC version: STREAM_VERSION contents: content contents content content: object blockdata blockdata: blockdatashort blockdatalong blockdatashort: TC_BLOCKDATA (unsigned byte)(byte)[size] blockdatalong: TC_BLOCKDATALONG (int) (byte)[size] object: newObject newClass newArray newString newEnum newClassDesc prevObject nullReference exception TC_RESET newObject: TC_OBJECT classDesc newHandle classdata[] // data for each class classdata: nowrclass // SC_SERIALIZABLE & classDescFlag && !(SC_WRITE_METHOD & classDescFlags) wrclass objectAnnotation // SC_SERIALIZABLE & classDescFlag && SC_WRITE_METHOD & classDescFlags externalContents // SC_EXTERNALIZABLE & classDescFlag && !(SC_BLOCKDATA & classDescFlags) objectAnnotation // SC_EXTERNALIZABLE & classDescFlag && SC_BLOCKDATA & classDescFlags nowrclass: values // fields in order of class descriptor wrclass: nowrclass externalContents: // externalContent written by externalContent // writeExternal in PROTOCOL_VERSION_1. externalContents externalContent externalContent: // Only parseable by readExternal (bytes) // primitive data object objectAnnotation: endBlockData contents endBlockData // contents written by writeObject or writeExternal PROTOCOL_VERSION_2. newClass: TC_CLASS classDesc newHandle newArray: TC_ARRAY classDesc newHandle (int) values[size] newString: TC_STRING newHandle (utf) TC_LONGSTRING newHandle (long-utf) newEnum: TC_ENUM classDesc newHandle enumConstantName enumConstantName: (String)object newClassDesc: TC_CLASSDESC className serialVersionUID newHandle classDescInfo TC_PROXYCLASSDESC newHandle proxyClassDescInfo className: (utf) classDescInfo: classDescFlags fields classAnnotation superClassDesc classDescFlags: (byte) // Defined in Terminal Symbols and Constants fields: (short) fieldDesc[count] fieldDesc: primitiveDesc objectDesc primitiveDesc: prim_typecode fieldName prim_typecode: `B' // byte `C' // char `D' // double `F' // float `I' // integer `J' // long `S' // short `Z' // boolean objectDesc: obj_typecode fieldName className1 obj_typecode: `[` // array `L' // object className1: (String)object // ThinkPlus USBキ-ボ-ドString containing the field's type, in field descriptor format fieldName: (utf) proxyClassDescInfo: (int) proxyInterfaceName[count] classAnnotation superClassDesc proxyInterfaceName: (utf) superClassDesc: classDesc serialVersionUID: (long) classAnnotation: endBlockData contents endBlockData // contents written by annotateClass prevObject: TC_REFERENCE (int)handle nullReference: TC_NULL exception: TC_EXCEPTION reset (Throwable)object reset reset: // The set of known objects is discarded so the objects of the exception do not overlap with the previously sent objects or with objects that may be sent after the exception values: // The size and types are described by the classDesc for the current object classDesc: newClassDesc nullReference (ClassDesc)prevObject // an object required to be of type ClassDesc endBlockData: TC_ENDBLOCKDATA newHandle: // The next number in sequence is assigned to the object being serialized or deserialized