Glaber / Zabbix Java Gateway Protocol
This document describes the wire protocol between the Glaber server (or proxy) Java poller and the Java gateway process. The protocol is inherited from Zabbix and is implemented on the poller side in src/zabbix_server/poller/checks_java.c and on the gateway side in src/zabbix_java/.
Overview
| Aspect | Detail |
|---|---|
| Transport | Plain TCP (no TLS in the poller path) |
| Default port | 10052 (ZBX_DEFAULT_GATEWAY_PORT in include/zbxcomms.h) |
| Configuration | JavaGateway, JavaGatewayPort in zabbix_server.conf / zabbix_proxy.conf |
| Message encoding | UTF-8 JSON payload inside a binary ZBXD frame |
| Connection model | One request per accepted connection; gateway closes the socket after the response |
| Batching | Multiple item keys can be sent in a single request; gateway returns one result object per key, in the same order |
The Java poller connects to the gateway, sends one framed JSON request, reads one framed JSON response, then closes the connection (zbx_tcp_connect → zbx_tcp_send → zbx_tcp_recv → zbx_tcp_close in get_values_java()).
Reference Code
| Component | Path |
|---|---|
| Poller: build request, parse response | src/zabbix_server/poller/checks_java.c |
| Poller headers / request type constants | src/zabbix_server/poller/checks_java.h |
| JSON tag names and request type strings | include/zbxjson.h |
| TCP framing (server/poller) | src/libs/zbxcomms/comms.c, include/zbxcomms.h |
| Gateway: TCP framing | src/zabbix_java/src/com/zabbix/gateway/BinaryProtocolSpeaker.java |
| Gateway: dispatch and JSON envelope | src/zabbix_java/src/com/zabbix/gateway/SocketProcessor.java |
| Gateway: JSON field names | src/zabbix_java/src/com/zabbix/gateway/ItemChecker.java |
| Gateway: internal vs JMX handling | InternalItemChecker.java, JMXItemChecker.java |
Binary Framing (ZBXD)
Both peers use the same 4-byte magic and protocol version byte 0x01 (ZBX_TCP_PROTOCOL). Payload length fields are little-endian.
Request (Glaber server / proxy → Java gateway)
The poller sends via zbx_tcp_send(), which uses the standard Zabbix TCP header for non-large messages:
Offset Size Field
------ ---- -----
0 4 Magic: ASCII "ZBXD"
4 1 Flags: 0x01 (ZBX_TCP_PROTOCOL; no compression for Java poller)
5 4 Data length (uint32 LE) — size of JSON body
9 4 Reserved (uint32 LE) — 0 when payload is uncompressed
13 N JSON body (UTF-8)
Total header size: 13 bytes + JSON body.
The Java gateway reads the first 5 bytes (ZBXD + 0x01), then reads 8 bytes as a single uint64 LE length, then reads exactly that many bytes of JSON (BinaryProtocolSpeaker.getRequest()). This is compatible with the poller layout: with reserved = 0, the eight bytes are {data_len, 0} on little-endian hosts, which equals data_len as a 64-bit integer.
Response (Java gateway → Glaber server / proxy)
The gateway sends:
Offset Size Field
------ ---- -----
0 4 Magic: ASCII "ZBXD"
4 1 Protocol version: 0x01
5 8 Data length (uint64 LE) — size of JSON body
13 N JSON body (UTF-8)
The poller receives via zbx_tcp_recv(), which parses the same ZBXD header and, for normal messages, two uint32 length fields (equivalent to one uint64 when the high dword is zero). Implementations that talk to the gateway should use the gateway response layout (5 + 8 + body) or the full Zabbix receive parser.
Compression (ZBX_TCP_COMPRESS) and large-message (ZBX_TCP_LARGE) flags are not used on the Java poller connection.
JSON Request
Every request is a single JSON object.
Common fields
| Field | JSON type | Required | Description |
|---|---|---|---|
request |
string | yes | "java gateway internal" or "java gateway jmx" |
keys |
array of strings | yes | Item keys to evaluate (same order as expected in data) |
Constants in C: ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_TAG_KEYS, ZBX_PROTO_VALUE_JAVA_GATEWAY_INTERNAL, ZBX_PROTO_VALUE_JAVA_GATEWAY_JMX (include/zbxjson.h).
Constants in Java: ItemChecker.JSON_TAG_*, ItemChecker.JSON_REQUEST_*.
Internal request
Used for gateway health and metadata (e.g. zabbix[java,,ping], zabbix[java,,version]).
request value: "java gateway internal"
Example:
{
"request": "java gateway internal",
"keys": ["zabbix[java,,ping]"]
}
Built in get_values_java() when request == ZBX_JAVA_GATEWAY_REQUEST_INTERNAL.
JMX request
Used for JMX item keys. All keys in one batch must share the same connection parameters; the poller validates this before sending.
request value: "java gateway jmx"
| Field | JSON type | Required | Description |
|---|---|---|---|
username |
string | no | JMX credentials |
password |
string | no | JMX credentials |
jmx_endpoint |
string | no* | JMX service URL (e.g. service:jmx:rmi:///jndi/rmi://host:port/jmxrmi) |
*The gateway expects jmx_endpoint for JMX checks (JMXItemChecker); the poller includes it when set on the item.
Example:
{
"request": "java gateway jmx",
"username": "admin",
"password": "secret",
"jmx_endpoint": "service:jmx:rmi:///jndi/rmi://127.0.0.1:12345/jmxrmi",
"keys": [
"jmx[\"java.lang:type=Memory\",\"HeapMemoryUsage.used\"]",
"jmx[\"java.lang:type=Runtime\",\"Uptime\"]"
]
}
JSON Response
Success
| Field | JSON type | Description |
|---|---|---|
response |
string | Must be "success" (ZBX_PROTO_VALUE_SUCCESS) |
data |
array | One object per successful item key in the request, in the same order as keys with errcodes[i] == SUCCEED on the poller side |
Each element of data is an object with either:
| Field | Meaning |
|---|---|
value |
Item value as text (ITEM_VALUE_TYPE_TEXT on the poller) |
error |
Per-item failure message; poller sets NOTSUPPORTED |
Example (all keys succeeded):
{
"response": "success",
"data": [
{ "value": "123456789" },
{ "value": "42" }
]
}
Example (mixed per-item results):
{
"response": "success",
"data": [
{ "value": "123456789" },
{ "error": "cannot connect to JMX endpoint: ..." }
]
}
The poller walks data in order and assigns results only to items that were SUCCEED before the call (parse_response() in checks_java.c). The number of objects in data must match the number of such items; otherwise the poller reports a gateway error.
Failure (whole request)
| Field | JSON type | Description |
|---|---|---|
response |
string | Must be "failed" (ZBX_PROTO_VALUE_FAILED) |
error |
string | Human-readable reason |
Example:
{
"response": "failed",
"error": "bad request tag value: 'unknown'"
}
On failure, the poller treats the error as NETWORK_ERROR and applies the same error message to all items in the batch that were eligible for the gateway call.
Request / Response Flow
sequenceDiagram
participant Poller as Java poller (server/proxy)
participant GW as Java gateway
Poller->>GW: TCP connect (JavaGateway:JavaGatewayPort)
Poller->>GW: ZBXD frame + JSON request
GW->>GW: Parse JSON, dispatch by request type
alt success
GW->>Poller: ZBXD frame + JSON {response: success, data: [...]}
else fatal error
GW->>Poller: ZBXD frame + JSON {response: failed, error: "..."}
end
Poller->>GW: TCP close
GW->>Poller: TCP close
Gateway processing (SocketProcessor):
- Read framed request.
- Read
requeststring →InternalItemCheckerorJMXItemChecker. - For each string in
keys, produce{ "value": "..." }or{ "error": "..." }. - Send
{ "response": "success", "data": [ ... ] }, or on exception{ "response": "failed", "error": "..." }.
Poller-Side Response Handling
parse_response() in checks_java.c requires:
- Valid JSON root object.
responsetag present.- If
response == "success":dataarray present; enough elements for each polled item; each element is an object withvalueorerror. - If
response == "failed":errortag present.
Connection or framing failures are reported via zbx_socket_strerror() and mapped to GATEWAY_ERROR for affected items.
Internal Item Keys (Gateway Behavior)
For java gateway internal, the reference gateway (InternalItemChecker) supports keys of the form:
zabbix[java,,<parameter>]
| Parameter | Returned value |
|---|---|
ping |
"1" |
version |
Gateway version string |
Other parameters or key IDs produce a per-item error in data (not a top-level failed response).
Implementation Notes for Third-Party Gateways
- Listen on the configured port (default
10052), typically0.0.0.0. - Accept connections; handle each connection in a worker thread (the reference gateway uses a thread pool sized by
START_POLLERS). - Read the full ZBXD request using blocking I/O (gateway uses
readFully). - Parse JSON; require
requestandkeys. - Write a ZBXD-framed JSON response using the gateway response format (5-byte header + 8-byte LE length + body).
- Close the socket after the response.
- Match key order in
datato the order of strings inkeysfor the items the poller marks as active in the batch.
A minimal test stub can return the same string (e.g. current timestamp) in every value field as long as framing and JSON shape match this document.
Configuration
| Parameter | Default | Description |
|---|---|---|
JavaGateway |
(empty) | Hostname or IP of the gateway |
JavaGatewayPort |
10052 |
TCP port |
Gateway-side defaults are in src/zabbix_java/glaber_java_gateway.conf (LISTEN_PORT=10052, START_POLLERS, etc.).
Related Monitoring Items
Frontend / documentation often refers to items such as zabbix[java,,ping] and zabbix[java,,version] for gateway availability. Those use the internal request path described above.