OpenWire Version 2 is not the latest version.
This article references OpenWire V2 which is no longer the latest version, the default setting shown in this article may not reflect the current defaults, see this page for the latest default OpenWire settings.

Overview

OpenWire is used to marshal objects to byte arrays and back. We will refer to the marshaled objects as commands.

A TCP network connection would see multiple commands back to back on the stream. Commands are not delimited in anyway and are variable sized.

+---------+  +---------+      +---------+
| command |  | command | .... | command |
+---------+  +---------+      +---------+

All data primitive types used in the encoded commands are encoded in big-endian/network byte order.

primitive types and encoding:
             |               |               |               |               |               |               
+----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ 
| byte     | | | char      | | | short     | | | int       | | | long      | | | float     | | | double    | 
+----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ 
| 1 octect | | | 2 octects | | | 2 octects | | | 4 octects | | | 8 octects | | | 4 octects | | | 8 octects | 
+----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ 
             |               |               |               |               |               |               

Wire Format Negotiation

OpenWire is an extensible in that it supports adding new encoding options while still being backward compatible with previous versions of the protocol. Every OpenWire protocol session initially starts with all encoding options turned off and at version 1 of command marshalers. An initial WIREFORMAT_INFO command is exchanged between the two nodes so that additional encoding features can be enabled. If both sides request an encoding feature to be enabled then it will be enabled. The command marshalers used will be the highest version that they both support.

+-------------------------+ +---------+  +---------+      +---------+
| WIREFORMAT_INFO command | | command |  | command | .... | command |
+-------------------------+ +---------+  +---------+      +---------+

Command Encoding

Every command is encoded as follows:

command encoding:
[=If SizePrefixDisabled =] 
[ option is not enabled. ]
[ +------+               ] +------+-------------------------+
[ | size |               ] | type | command-specific-fields |
[ +------+               ] +------+-------------------------+
[ | int  |               ] | byte | (size-1) octects        |
[ +------+               ] +------+-------------------------+
[========================]
Field Description
size Holds how many subsequent bytes are in the the command
type Command type identifier
command-specific-fields The data for the command. It is encoding depends on the type used

If a command type does not have any command specific content, then size would be 1.

Prefixing the size on every command is done to aid in non-blocking IO processing so that receiver can easily determine when a whole command has been received and can be processed. But finding out the size of command takes additional buffering on the sender size and is not needed if the receiver is doing blocking IO. If the SizePrefixDisabled option is enabled after the exchange of WIREFORMAT_INFO packets, then every subsequent command will not have the size prefixed.

Command Types

Type Identifier Command Description
1WIREFORMAT_INFO  
2BROKER_INFO  
3CONNECTION_INFO  
4SESSION_INFO  
5CONSUMER_INFO  
6PRODUCER_INFO  
7TRANSACTION_INFO  
8DESTINATION_INFO  
9REMOVE_SUBSCRIPTION_INFO  
10KEEP_ALIVE_INFO  
11SHUTDOWN_INFO  
12REMOVE_INFO  
14CONTROL_COMMAND  
15FLUSH_COMMAND  
16CONNECTION_ERROR  
17CONSUMER_CONTROL  
18CONNECTION_CONTROL  
21MESSAGE_DISPATCH  
22MESSAGE_ACK  
23ACTIVEMQ_MESSAGE  
24ACTIVEMQ_BYTES_MESSAGE  
25ACTIVEMQ_MAP_MESSAGE  
26ACTIVEMQ_OBJECT_MESSAGE  
27ACTIVEMQ_STREAM_MESSAGE  
28ACTIVEMQ_TEXT_MESSAGE  
30RESPONSE  
31EXCEPTION_RESPONSE  
32DATA_RESPONSE  
33DATA_ARRAY_RESPONSE  
34INTEGER_RESPONSE  
40DISCOVERY_EVENT  
50JOURNAL_ACK  
52JOURNAL_REMOVE  
53JOURNAL_TRACE  
54JOURNAL_TRANSACTION  
55DURABLE_SUBSCRIPTION_INFO  
60PARTIAL_COMMAND  
61PARTIAL_LAST_COMMAND  
65REPLAY  
70BYTE_TYPE  
71CHAR_TYPE  
72SHORT_TYPE  
73INTEGER_TYPE  
74LONG_TYPE  
75DOUBLE_TYPE  
76FLOAT_TYPE  
77STRING_TYPE  
78BOOLEAN_TYPE  
79BYTE_ARRAY_TYPE  
90MESSAGE_DISPATCH_NOTIFICATION  
91NETWORK_BRIDGE_FILTER  
100ACTIVEMQ_QUEUE  
101ACTIVEMQ_TOPIC  
102ACTIVEMQ_TEMP_QUEUE  
103ACTIVEMQ_TEMP_TOPIC  
110MESSAGE_ID  
111ACTIVEMQ_LOCAL_TRANSACTION_ID  
112ACTIVEMQ_XA_TRANSACTION_ID  
120CONNECTION_ID  
121SESSION_ID  
122CONSUMER_ID  
123PRODUCER_ID  
124BROKER_ID  

Command Field Encoding

All OpenWire commands use the same algorithm when encoding their fields. The algorithm restricts commands to use fields that are of the following type:

  • Java primitive types
  • String
  • Byte Arrays
  • N Sized Byte Arrays
  • Throwable
  • Nested OpenWire commands
  • Nested OpenWire command arrays
  • Cached Nested OpenWire commands

Notice that OpenWire commands can nest other OpenWire commands in it's fields. Care must be taken that only acyclic graphs of commands are marshaled.

String Type Encoding

Strings fields may be null. If it is null then it encodes to a single "0" byte.

string encoding:
             [=If not-null is 1===========]
+----------+ [ +-------+----------------+ ]
| not-null | [ | size  | encoded-string | ]
+----------+ [ +-------+----------------+ ]
| byte     | [ | short | size octects   | ]
+----------+ [ +-------+----------------+ ]
             [============================]
Field Description
not-null 1 if the string is not null, 0 if the string is null
size The number of bytes of the UTF-8 Encoded string
encoded-string The UTF-8 encoded form of the string

Byte Array Type Encoding

Byte array fields may be null. If it is null then it encodes to a single "0" byte.

byte-array encoding:
             [=If not-null is 1========]
+----------+ [ +------+--------------+ ]
| not-null | [ | size | data         | ]
+----------+ [ +------+--------------+ ]
| byte     | [ | int  | size octects | ]
+----------+ [ +------+--------------+ ]
             [=========================]
Field Description
not-null 1 if the byte array is not null, 0 if it is null
size The number of bytes in the byte array
data The data of the byte array

N Sized Byte Array Type Encoding

Fixed Size Byte array fields may NOT be null and their length must be N length. Used for byte arrays that are always a fixed size.

N-sized-byte-array encoding:
+-----------+
| data      |
+-----------+
| N octects |
+-----------+
Field Description
data The data of the byte array

Throwable Type Encoding

Throwable fields may be null. If it is null then it encodes to a single "0" byte.

throwable encoding:
             [=If not-null is 1===========================================================================]
             [                               [=If StackTraceEnabled option is enabled.==================] ]
             [                               [             [=Repeated size times======================] ] ]
+----------+ [ +----------------+---------+  [ +-------+ [ +--------+--------+--------+-------------+ ] ] ]
| not-null | [ | exception-name | message |  [ | size  | [ | class  | method | file   | line-number | ] ] ]
+----------+ [ +----------------+---------+  [ +-------+ [ +--------+--------+--------+-------------+ ] ] ]
| byte     | [ | string         | string  |  [ | short | [ | string | string | string | int         | ] ] ]
+----------+ [ +----------------+---------+  [ +-------+ [ +--------+--------+--------+-------------+ ] ] ]
             [                               [           [============================================] ] ]
             [                               [==========================================================] ]
             [============================================================================================]
Field Description
not-null 1 if the Throwable not null, 0 if the Throwable is null
exception-name The class name of the exception
message The exception message
size The number of stack frames in the stack trace
class The name of the class in a stack frame
method The name of the method in a stack frame
file The name of the file in a stack frame
line-number The line number in a stack frame

If the StackTraceEnabled encoding option is enabled after the exchange of WIREFORMAT_INFO packets, then every Throwable filed will have stack trace data appended to it.

Nested Command Type Encoding

Nested command fields may be null. If it is null then it encodes to a single "0" byte.

nested-object encoding:
             [=If not-null is 1===================]
+----------+ [ +------+-------------------------+ ]
| not-null | [ | type | command-specific-fields | ]
+----------+ [ +------+-------------------------+ ]
| byte     | [ | byte | variable sized          | ]
+----------+ [ +------+-------------------------+ ]
             [====================================]
Field Description
not-null 1 if the Throwable not null, 0 if the Throwable is null
type Command type identifier
command-specific-fields The data for the command. It is encoding depends on the type used

Cached Nested Command Type Encoding

Nested Command types can be cached so that subsequent marshaling operations of the same object result in a smaller on the wire size. By default the CacheEnabled option is not enabled and therefore standard nested-object encoding is used.

cached-object-encoding:
[=If CacheEnabled option is enabled=====================]
[                       [=If new-value is 1===========] ]
[ +-----------+-------+ [ +-------------------------+ ] ]
[ | new-value | key   | [ | command-specific-fields | ] ]
[ +-----------+-------+ [ +-------------------------+ ] ]
[ | byte      | short | [ | nested-object           | ] ]
[ +-----------+-------+ [ +-------------------------+ ] ]
[                       [=============================] ]
[=====================================================] ]

[=If CacheEnabled option is disabled =]
[ +-------------------------+         ]
[ | command-specific-fields |         ]
[ +-------------------------+         ]
[ | nested-object           |         ]
[ +-------------------------+         ]
[=====================================]
Field Description
new-value 1 if the value is not in the cache, 0 if it already is in the cache
key Key used to identify the value in the cache
command-specific-fields The data for the command. It is encoding depends on the type used

Loose Encoding

The default encoding explained so far is called "loose encoding" and is the default encoding used when OpenWire if first initialized. Loose encoding is simple to implement does not add much CPU overhead to the marshaling/unmarshaling process. It is able to marshal an object graph in single pass of the object tree.

Tight Encoding

Another encoding option is supported by OpenWire which is called TightEncoding. When tight encoding is used, it uses bit streams to marshal all the boolean values that would have taken up a byte in loose encoding to a bit in the bit stream. To build the bit stream 2 passes through the object graph are taken so this is more CPU intensive marshaling process but it produces a smaller on the wire size.

© 2004-2011 The Apache Software Foundation.
Apache ActiveMQ, ActiveMQ, Apache, the Apache feather logo, and the Apache ActiveMQ project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.
Graphic Design By Hiram