COBOL COBOL 2014 (ISO/IEC 1989:2014), built with GnuCOBOL 3.x Β·
β verified by execution on 2026-08-16
For decades, COBOL systems communicated using fixed-width flat files and EBCDIC character sets. Today, they need to communicate with microservices, web browsers, and mobile applications. The lingua franca of modern communication is JSON (JavaScript Object Notation).
Rather than forcing developers to write complex C wrappers or Java bridge layers, modern COBOL compilers introduced native support for parsing and generating JSON payloads. In this lesson, we will explore the JSON GENERATE statement, a powerful tool for serializing COBOL data structures directly into web-ready JSON strings.
To see why COUNT IN is important, predict what happens to the fixed-length PIC X(50) receiving string after the JSON is generated. We will append a <END> marker to reveal any invisible characters:
Predict the outputcobol
Read the code. What exactly will it print? Commit to an answer before you look.
While JSON GENERATE smartly trims trailing spaces from individual values (like βALICEβ), the target JSON-OUTPUT variable is still a fixed-length COBOL string. This means the resulting JSON payload is padded with spaces up to its 50-byte length! If we send this over a network, we waste bandwidth and risk confusing strict JSON parsers.
Generating Basic JSON
The JSON GENERATE statement takes a source COBOL data item (usually a Group Item) and serializes it into a receiving string.
Here is a basic example converting an employee record into JSON. Notice the output has trailing spaces because the receiving PIC X(100) variable is fixed-length!
cobolβ verified output
IDENTIFICATION DIVISION. PROGRAM-ID. JSON-GEN. DATA DIVISION. WORKING-STORAGE SECTION. 01 EMP-REC. 05 EMP-ID PIC 9(4) VALUE 1234. 05 EMP-NAME PIC X(10) VALUE "ALICE". 01 JSON-OUTPUT PIC X(100). PROCEDURE DIVISION. JSON GENERATE JSON-OUTPUT FROM EMP-REC. DISPLAY JSON-OUTPUT. STOP RUN.
Output
{"EMP-REC":{"EMP-ID":1234,"EMP-NAME":"ALICE"}}
Your output
Trimming the Output with COUNT IN
Because COBOL strings are fixed-length, sending JSON-OUTPUT directly over a network would transmit 90 bytes of empty space. The COUNT IN phrase solves this by storing the exact length of the generated JSON into a variable. You can then use reference modification (1:JSON-LEN) to extract exactly what you need.
cobolβ verified output
IDENTIFICATION DIVISION. PROGRAM-ID. JSON-CNT. DATA DIVISION. WORKING-STORAGE SECTION. 01 EMP-REC. 05 EMP-ID PIC 9(4) VALUE 1234. 05 EMP-NAME PIC X(10) VALUE "ALICE". 01 JSON-OUTPUT PIC X(100). 01 JSON-LEN PIC 9(4). PROCEDURE DIVISION. JSON GENERATE JSON-OUTPUT FROM EMP-REC COUNT IN JSON-LEN. DISPLAY JSON-OUTPUT(1:JSON-LEN). STOP RUN.
Output
{"EMP-REC":{"EMP-ID":1234,"EMP-NAME":"ALICE"}}
Your output
Exception Handling and Suppressing Fields
What if your receiving field isnβt large enough? JSON GENERATE will trigger an exception condition. You can handle this gracefully with the ON EXCEPTION phrase.
Additionally, you donβt always want to send every piece of data inside a record over an API. The SUPPRESS phrase allows you to exclude specific fields (like sensitive security data) from the generated JSON payload.
cobolβ verified output
IDENTIFICATION DIVISION. PROGRAM-ID. JSON-SUP. DATA DIVISION. WORKING-STORAGE SECTION. 01 EMP-REC. 05 EMP-ID PIC 9(4) VALUE 1234. 05 EMP-SSN PIC X(9) VALUE "SECRET". 01 JSON-OUT PIC X(100). 01 JSON-LEN PIC 9(4). PROCEDURE DIVISION. JSON GENERATE JSON-OUT FROM EMP-REC COUNT IN JSON-LEN SUPPRESS EMP-SSN END-JSON. DISPLAY JSON-OUT(1:JSON-LEN). STOP RUN.
Output
{"EMP-REC":{"EMP-ID":1234}}
Your output
A Note on OCCURS and JSON PARSE
While JSON GENERATE creates JSON, the JSON PARSE statement does the reverse: turning JSON into COBOL data structures. While this is fully implemented in IBM Enterprise COBOL, in GnuCOBOL 3.x, JSON PARSE is currently a syntax stub. It will compile (with a -Wpending warning) but silently skip parsing at runtime!
Another current limitation in GnuCOBOL 3.x is that JSON GENERATE does not fully support OCCURS arrays yet; it will typically emit only the first element of the array and issue a -Wpending compile warning.
For now, rely on JSON GENERATE for flat COBOL-to-API needs, and use specialized libraries or preprocessors if you need to ingest JSON or serialize complex arrays in GnuCOBOL.
Check yourself
Which COBOL statement is used to serialize a group item into a JSON string?
Reveal answer
JSON GENERATE β The JSON GENERATE statement is a standard COBOL feature designed to transform COBOL data into a JSON string.
Why is the COUNT IN phrase crucial when generating JSON in COBOL?
Reveal answer
It captures the exact length of the generated JSON so you can trim trailing spaces from the fixed-length receiving field. β COBOL variables are fixed-length, so a PIC X(100) receiving field will pad the JSON with spaces. COUNT IN lets you capture the actual size to substring it later.
What happens if the receiving field for JSON GENERATE is too small to hold the result?
Reveal answer
An exception condition is triggered and JSON-CODE becomes non-zero. β If the output exceeds the target area, an exception triggers. You can handle this gracefully with the ON EXCEPTION clause.
Challenges
π Bug Hunt+20 XP
The code below generates JSON but sends trailing spaces. Fix it by capturing the exact length with COUNT IN and using reference modification on the display.
This code runs. It just does the wrong thing. Read it, find the defect,
fix it β the tests below decide when you are right.
cobolβ solution verified at build time
COBOL has no in-browser runtime, so this one is pen-and-paper: work out what the
fixed code should be, then open the solution and compare. The expected output
below is real β it came from compiling the solution with GnuCOBOL when this page
was built.
Test 1 β expects "{\"EMP-REC\":{\"EMP-NAME\":\"ALICE\"}}<END>"
Need a hint? (β25% XP)
Add a JSON-LEN variable. Use COUNT IN JSON-LEN. DISPLAY JSON-OUTPUT(1:JSON-LEN) '<END>'.
What happens if you run `JSON PARSE` in GnuCOBOL 3.x? (Does it error on compile, crash, or compile with a warning but do nothing?)
cobolβ solution verified at build time
COBOL has no in-browser runtime, so this one is pen-and-paper: work out what the
fixed code should be, then open the solution and compare. The expected output
below is real β it came from compiling the solution with GnuCOBOL when this page
was built.
Test 1 β expects "Compiles with warning but does nothing"
Need a hint? (β25% XP)
It's a syntax stub.
Show solution (0 XP)
IDENTIFICATION DIVISION.PROGRAM-ID. CHAL2.PROCEDURE DIVISION. DISPLAY "Compiles with warning but does nothing". STOP RUN.