Object-Oriented COBOL
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
This page is written against ISO/IEC 1989:2023 (edition 3, January 2023; an upcoming 4th edition is in ballot), in which the object-oriented facilities come from COBOL 2002; against IBM Enterprise COBOL for z/OS 6.5 (PTFs through September 2026) on z/OS 3.2, whose Language Reference and Programming Guide still document OO syntax built around Java; and against GnuCOBOL 3.2 (28 July 2023, the latest release), which does not implement the OO syntax: that was tested with cobc on 2026-10-20 and the real diagnostics are shown below. The only program on this page that was compiled with cobc -x -Wall (and with -std=ibm, without warnings) and run is the plain-COBOL substitute near the end. The OO classes and clients are labelled "z/OS; not run here" and are checked against the Language Reference and the Programming Guide. The Rocket Visual COBOL material is described from the vendor’s public documentation and was not run.
Object-oriented COBOL is the least used part of the language, and this page says so plainly. It explains the model so that the keywords and the manuals make sense, shows what a Circulation BOOKITEM class looks like on z/OS, says what each product does and does not support, and gives a procedural design that achieves the same encapsulation in every compiler. Subprograms, which are the usual alternative, are on Subprograms, CALL and Linkage; user-defined functions and prototypes are on User-Defined Functions and Prototypes; calling C, Java and Python without objects is on Interoperability with C, Java and Python; and the reference data types behind USAGE OBJECT REFERENCE are listed with the other usages on USAGE and Numeric Representation. The compiler differences are collected on Compilers and Dialects.
Where the book is outdated: Taulli’s Modern Mainframe Development (2022, chapter 7) names OO COBOL among the ways COBOL meets other languages. The Enterprise COBOL manuals since version 6.4 describe a second, non-OO route to Java (the JAVAIOP option, the JAVA-CALLABLE directive and the cjbuild utility), and version 6.5 changed how cjbuild names its output DLL. A reader who learns Java interoperability only from the OO chapter therefore misses the route IBM now documents first for existing programs. The book is cited from its publisher page only and no text from it is reproduced.
The COBOL 2002 object model
COBOL 2002 added classes and objects to a language that had only programs and data items. The model is the common one, spelled with COBOL’s usual verbosity.
| Concept | COBOL form |
|---|---|
Class |
A source unit that starts with |
Instance data |
The |
Instance method |
A |
Factory data and factory methods |
The |
Object reference |
A data item with |
Creating an instance |
|
Calling a method |
|
Inheritance |
|
|
Two ways to name the object a method is running on. |
Interface |
|
The next diagram shows the Circulation example used on this page: a BOOKITEM class with a factory side (a count shared by the whole class) and an object side (the copies of one book), and a subclass that specializes it. The base of every Enterprise COBOL class is java.lang.Object, which is what makes the classes visible to Java.
Class structure on Enterprise COBOL
The Language Reference describes the class definition as a fixed outline, and the Programming Guide describes each part as a task.
-
A class header: an
IDENTIFICATION DIVISIONwith theCLASS-IDparagraph, which names the class and its single parent withINHERITS. A COBOL class inherits, directly or indirectly, fromjava.lang.Object; the parent can itself be written in Java. -
An
ENVIRONMENT DIVISIONwhoseCONFIGURATION SECTIONholds theREPOSITORYparagraph. The paragraph is required: it relates the class names used in the source to their external names, such asjava.lang.Object. AnINPUT-OUTPUT SECTIONis not allowed at class level and goes in the individual methods that need it. -
An optional
FACTORYdefinition, ended byEND FACTORY, with its ownIDENTIFICATION DIVISION, aDATA DIVISIONfor the shared data and aPROCEDURE DIVISIONof factory methods. -
An optional
OBJECTdefinition, ended byEND OBJECT, built the same way for instance data and instance methods. -
END CLASS.
Each method starts with an IDENTIFICATION DIVISION and a METHOD-ID paragraph naming the method as a quoted literal, ends with END METHOD, and has its own LINKAGE SECTION and a PROCEDURE DIVISION with USING and RETURNING. Method names are case-sensitive and follow Java’s rules for method names, because Java clients call them by that name. Settings in the SOURCE-COMPUTER, OBJECT-COMPUTER or SPECIAL-NAMES paragraphs of the class apply to every method. Each class definition must be in a separate source file.
The Circulation BOOKITEM class (z/OS; not run here)
This is an original class written for this page and checked against the structure above; it was not compiled, because there is no Enterprise COBOL compiler in the test environment. Every item in it follows the shapes shown in the Programming Guide for the Account example. The copies counter is binary because the class can be called from Java.
IDENTIFICATION DIVISION.
CLASS-ID. BookItem INHERITS FROM Base.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
CLASS Base IS "java.lang.Object"
CLASS BookItem IS "BookItem".
*
IDENTIFICATION DIVISION.
FACTORY.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 ITEMS-CREATED PIC S9(9) BINARY VALUE 0.
PROCEDURE DIVISION.
*
IDENTIFICATION DIVISION.
METHOD-ID. "createdCount".
DATA DIVISION.
LINKAGE SECTION.
01 LK-COUNT PIC S9(9) BINARY.
PROCEDURE DIVISION RETURNING LK-COUNT.
MOVE ITEMS-CREATED TO LK-COUNT.
END METHOD "createdCount".
END FACTORY.
*
IDENTIFICATION DIVISION.
OBJECT.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 BOOK-COPIES PIC S9(9) BINARY VALUE 1.
PROCEDURE DIVISION.
*
IDENTIFICATION DIVISION.
METHOD-ID. "checkOut".
DATA DIVISION.
LINKAGE SECTION.
01 LK-LEFT PIC S9(9) BINARY.
PROCEDURE DIVISION RETURNING LK-LEFT.
IF BOOK-COPIES > 0
SUBTRACT 1 FROM BOOK-COPIES
END-IF
MOVE BOOK-COPIES TO LK-LEFT.
END METHOD "checkOut".
*
IDENTIFICATION DIVISION.
METHOD-ID. "giveBack".
DATA DIVISION.
LINKAGE SECTION.
01 LK-LEFT PIC S9(9) BINARY.
PROCEDURE DIVISION RETURNING LK-LEFT.
ADD 1 TO BOOK-COPIES
MOVE BOOK-COPIES TO LK-LEFT.
END METHOD "giveBack".
END OBJECT.
END CLASS BookItem.
Source: Enterprise COBOL for z/OS 6.5 Programming Guide: Defining a class; Programming Guide: METHOD-ID paragraph for defining a class instance method; Language Reference: COBOL class definition structure
The factory side is where an implementation would increment ITEMS-CREATED each time an instance is made, typically from a factory method that the class defines for construction; the example keeps only the reader method to stay short.
Clients: INVOKE, NEW, SELF and SUPER
A client is a program (or another class) that creates instances and calls their methods. It lists the classes it uses in its own REPOSITORY paragraph and holds instances in object reference items.
A client program (z/OS; not run here)
IDENTIFICATION DIVISION.
PROGRAM-ID. CIRCCLI.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
CLASS BookItem IS "BookItem".
DATA DIVISION.
WORKING-STORAGE SECTION.
01 BK USAGE OBJECT REFERENCE BookItem.
01 COPIES-LEFT PIC S9(9) BINARY.
PROCEDURE DIVISION.
INVOKE BookItem NEW RETURNING BK
INVOKE BK "checkOut" RETURNING COPIES-LEFT
DISPLAY "Copies left: " COPIES-LEFT
INVOKE BK "giveBack" RETURNING COPIES-LEFT
DISPLAY "Copies left: " COPIES-LEFT
STOP RUN.
The rules of INVOKE that matter in practice:
-
INVOKE class-name NEW RETURNING referencecreates an instance.RETURNINGis required. For a Java classUSINGselects the constructor; for a COBOL classUSINGmust not be specified. -
INVOKE reference "name"calls an instance method. With a class name instead of a reference, the method must be a factory method (COBOL) or a static method (Java). -
Arguments are passed
BY VALUEonly. There is noBY REFERENCEorBY CONTENTinINVOKE, which is a real difference fromCALL. -
ON EXCEPTIONruns when the object or class has no method with a matching signature. Without it, a severity-3 Language Environment condition is raised.NOT ON EXCEPTIONruns after the method returns, andEND-INVOKEmakes the statement usable inside a conditional. -
INVOKEdoes not setRETURN-CODE. -
Dynamic-length items cannot be operands, the statement is not supported when the
LP(64)option is in effect, and it cannot call AMODE 64 Java methods.
SELF and SUPER are used only inside a method. INVOKE SELF "checkOut" calls a method on the current object, honouring any override in a subclass. INVOKE SUPER "describe" also acts on the current object but starts the method lookup above the current class, so an overriding describe in RAREBOOK can call the describe of BOOKITEM and then add its own text. A subclass overrides an instance method by defining a method with the same signature.
Interfaces and polymorphism
The 2002 standard model has two ways to get polymorphism: inheritance (a RAREBOOK can be used wherever a BOOKITEM is expected, by declaring the reference as USAGE OBJECT REFERENCE BookItem) and interfaces (INTERFACE-ID and IMPLEMENTS, which describe behaviour without data). The Enterprise COBOL class-structure page does not mention INTERFACE-ID or IMPLEMENTS, and its model is a single parent class that can be a Java class; this page therefore does not show interface syntax for z/OS and treats interfaces as part of the standard model only. Check the manual of the product you use before relying on them.
IBM’s Java-based OO COBOL on z/OS
Enterprise COBOL’s OO syntax exists mainly to interoperate with Java. The Language Reference says the syntax lets a program define classes, create instances, invoke methods and inherit from Java or COBOL classes. In effect a COBOL class compiles to something the Java virtual machine can load, with java.lang.Object at the root of its inheritance chain.
| Aspect | Rule in the 6.5 manuals |
|---|---|
Threads |
Java programs can be multithreaded and send asynchronous signals, so mixing COBOL with Java requires the |
CICS |
OO programs that use Java interoperability cannot contain |
SQL |
COBOL classes cannot contain |
AMODE 64 |
The OO framework is not supported with the |
Environment |
The Programming Guide recommends developing and running OO COBOL and Java programs in the z/OS UNIX environment. |
Wrapping existing code |
COBOL classes can call procedural COBOL programs, so a class can be a wrapper that lets Java code reach existing COBOL logic. |
Other Java access |
Further capabilities come from calling Java Native Interface (JNI) services. |
Those restrictions are the heart of the story. The Circulation shop’s valuable code is batch, Db2 and CICS code; a class that cannot hold SQL or run in CICS can only be a thin shell around it, and calling a Java class from a CICS COBOL program through the OO framework is excluded outright.
Source: Enterprise COBOL for z/OS 6.5 Programming Guide: Writing object-oriented programs; Language Reference: COBOL class definition structure
Non-OO Java interoperability in 6.4 and 6.5
Enterprise COBOL 6.4 introduced a second route that needs no classes. The compiler generates stub files from ordinary COBOL programs (marked callable from Java with the JAVA-CALLABLE directive, selected by the JAVAIOP compiler option), and the cjbuild utility builds those stubs into a DLL. Programs call static Java methods with an enhanced CALL, and Java calls COBOL programs through the generated glue. The Programming Guide describes it as a more comprehensive and flexible form of COBOL/Java interoperability than the OO framework, built so that existing COBOL programs can take part with little change. Version 6.5 changed how cjbuild names its DLL when it writes to a data set (the LIB prefix is no longer added, so a full 8-character member name can be used, with JCL link-step changes), and a 2026 PTF added support for a newer Java release. When the Java version is 25 or higher the manual also asks for the --enable-native-access=ALL-UNNAMED JVM option, set through the COBJVMINITOPTIONS environment variable for COBOL-started applications.
This is why the OO route is rarely the right start today, and it is the answer to the question this page keeps asking. IBM has not removed the OO syntax from 6.5: the Language Reference and Programming Guide still document it. But for a shop that wants a COBOL program to call Java or be called from Java, the non-OO route works on programs as they are, so there is no need to wrap logic in classes, and it is the one that receives the new options and PTF attention. Use the OO syntax when you need what only it offers: subclassing a Java class in COBOL, or implementing an object that Java code treats as an instance. The full non-OO story, with the build steps, is on Interoperability with C, Java and Python. This sentence is an assessment of the documentation, not a statement by IBM that the OO syntax is deprecated; the manuals do not say that.
Rocket Visual COBOL on .NET and the JVM
Rocket Software acquired the application-modernization business of Micro Focus, whose Visual COBOL product it continues. Its approach is different from IBM’s: instead of an OO layer on a COBOL run time, the compiler can target a managed runtime. The product documentation calls the result managed COBOL, a collective term for COBOL compiled to .NET (used from Visual Studio) and COBOL compiled to the JVM (used from Eclipse). Managed COBOL has its own syntax for classes, methods, inheritance and access levels and reaches the framework class library of the platform through INVOKE and SET verbs. Procedural COBOL, compiled to native code, is documented separately in the vendor’s COBOL language reference and can be called from managed code. The Rocket documentation site is https://docs.rocketsoftware.com/ and is the place to read the manuals for the release you have; this page names no release because the vendor pages could not be verified for a current one. The practical consequence is that OO COBOL in practice means a Rocket or earlier Micro Focus shop writing .NET or Java applications in COBOL syntax, not a z/OS shop.
Source: Rocket Software documentation
GnuCOBOL and OO COBOL
GnuCOBOL 3.2 does not implement the OO syntax. This was tested rather than assumed. The class below (the BOOKITEM outline with only its object data and one method) was given to cobc from GnuCOBOL 3.2.0:
IDENTIFICATION DIVISION.
CLASS-ID. BOOKITEM INHERITS FROM BASE.
ENVIRONMENT DIVISION.
OBJECT.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-COPIES PIC 9(3) VALUE 0.
PROCEDURE DIVISION.
METHOD-ID. GET-COPIES.
DATA DIVISION.
LINKAGE SECTION.
01 LS-COPIES PIC 9(3).
PROCEDURE DIVISION RETURNING LS-COPIES.
MOVE WS-COPIES TO LS-COPIES
GOBACK.
END METHOD GET-COPIES.
END OBJECT.
END CLASS BOOKITEM.
Compiled with cobc -x -Wall (and again with -std=ibm and -std=mf, which gave the same first error and a second error that differs only in adding "(Area A)" under -std=ibm), the compiler stops at the first line:
oo1.cob:2: error: 'CLASS-ID' is a reserved word, but isn't supported
oo1.cob:2: error: syntax error, unexpected Identifier, expecting FUNCTION-ID or PROGRAM-ID
The compiler knows the words, which is why the first message says "reserved word" and not "syntax error", but treats them as unsupported. The list printed by cobc --list-reserved marks these as not implemented:
CLASS-ID No
INTERFACE-ID No
INVOKE No
METHOD-ID No
OBJECT-REFERENCE No
SELF No
SUPER No
A client with a CLASS entry in the REPOSITORY paragraph fails as well: in 3.2 that paragraph accepts FUNCTION entries (see User-Defined Functions and Prototypes) and the first CLASS line is a syntax error. Within the 3.2 behaviour tested here, the answer for GnuCOBOL is therefore: no classes, no methods, no INVOKE, no object references. The result is specific to GnuCOBOL 3.2.0 on the day of the test; the project’s own documentation, linked below, is the place to check a later release, and this page does not claim anything about unreleased versions.
The same design in plain COBOL
The useful part of a class is encapsulation: state that only a fixed set of operations can touch. A subprogram gives that in every compiler. WORKING-STORAGE in a called program keeps its values between calls, and a request code selects the operation. The next two programs build the Circulation BOOKITEM that way. The first is the "class", with BOOKREC as its private state; the second is a client that creates the item, checks it out twice, returns it and shows it.
* BOOKITEM - a book "object" built from plain COBOL: private state
* in a subprogram, public operations selected by a request code.
IDENTIFICATION DIVISION.
PROGRAM-ID. BOOKITEM.
DATA DIVISION.
WORKING-STORAGE SECTION.
COPY BOOKREC.
LINKAGE SECTION.
01 LK-REQUEST PIC X(4).
88 REQ-CREATE VALUE "NEW ".
88 REQ-CHECKOUT VALUE "OUT ".
88 REQ-RETURN VALUE "BACK".
88 REQ-SHOW VALUE "SHOW".
01 LK-BOOK-ID PIC 9(6).
01 LK-TITLE PIC X(30).
01 LK-COPIES PIC 9(3).
01 LK-RESULT PIC 9.
88 REQ-OK VALUE 0.
88 REQ-REFUSED VALUE 1.
PROCEDURE DIVISION USING LK-REQUEST LK-BOOK-ID LK-TITLE
LK-COPIES LK-RESULT.
MAIN-PARA.
SET REQ-OK TO TRUE
EVALUATE TRUE
WHEN REQ-CREATE
MOVE LK-BOOK-ID TO BOOK-ID
MOVE LK-TITLE TO BOOK-TITLE
MOVE LK-COPIES TO BOOK-COPIES
WHEN REQ-CHECKOUT
IF BOOK-COPIES > 0
SUBTRACT 1 FROM BOOK-COPIES
ELSE
SET REQ-REFUSED TO TRUE
END-IF
WHEN REQ-RETURN
ADD 1 TO BOOK-COPIES
WHEN REQ-SHOW
DISPLAY BOOK-ID " " BOOK-TITLE " " BOOK-COPIES
WHEN OTHER
SET REQ-REFUSED TO TRUE
END-EVALUATE
MOVE BOOK-COPIES TO LK-COPIES
GOBACK.
END PROGRAM BOOKITEM.
IDENTIFICATION DIVISION.
PROGRAM-ID. BOOKMAIN.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-REQUEST PIC X(4).
01 WS-BOOK-ID PIC 9(6) VALUE 1.
01 WS-TITLE PIC X(30) VALUE "BATCH PROCESSING".
01 WS-COPIES PIC 9(3) VALUE 1.
01 WS-RESULT PIC 9.
88 CALL-OK VALUE 0.
PROCEDURE DIVISION.
MAIN-PARA.
MOVE "NEW " TO WS-REQUEST
PERFORM DO-REQUEST
MOVE "OUT " TO WS-REQUEST
PERFORM DO-REQUEST
MOVE "OUT " TO WS-REQUEST
PERFORM DO-REQUEST
MOVE "BACK" TO WS-REQUEST
PERFORM DO-REQUEST
MOVE "SHOW" TO WS-REQUEST
PERFORM DO-REQUEST
STOP RUN.
DO-REQUEST.
CALL "BOOKITEM" USING WS-REQUEST WS-BOOK-ID WS-TITLE
WS-COPIES WS-RESULT
IF CALL-OK
DISPLAY WS-REQUEST " ok, copies " WS-COPIES
ELSE
DISPLAY WS-REQUEST " refused, copies " WS-COPIES
END-IF.
Compiled together with cobc -x -Wall -I. bookmain.cob bookitem.cob (and with -std=ibm), no warnings, it prints:
NEW ok, copies 001
OUT ok, copies 000
OUT refused, copies 000
BACK ok, copies 001
000001 BATCH PROCESSING 001
SHOW ok, copies 001
The second checkout is refused because no copy is left, the behaviour that the OO checkOut method expresses with its IF. What the plain design does not give is what objects give: several independent instances at once (this subprogram holds one book; a table of book records with the request code taking an index is the usual extension), inheritance (there is no RAREBOOK) and method dispatch chosen at run time. For most batch work none of that is needed. The same pattern works on z/OS under Enterprise COBOL, where the called program also keeps its WORKING-STORAGE between calls unless it is declared INITIAL.
Why OO COBOL saw little adoption
Adoption was low and the reasons can be read from the facts above. This section is an assessment, not a measurement: the manuals and the public record do not publish usage figures.
-
The standard arrived late. COBOL 2002 was published years after Java and C++ had settled the object-oriented mainstream, and the products implemented it unevenly. A language whose main use is long-lived code gets a decade of delay for free.
-
The value was already in programs and data. Existing COBOL is batch and transaction code built from programs, copybooks and files. Wrapping it in classes adds a layer without changing what it does, and the largest part of the estate cannot use the OO framework anyway (no
EXEC SQL, no CICS). -
Compilers do not agree. IBM ties OO COBOL to Java and the JVM; Rocket’s managed COBOL ties it to .NET or the JVM; GnuCOBOL has none. Code written for one cannot move to another, which is the opposite of what portability-minded COBOL shops want.
-
Restrictions and cost. The
THREADrequirement, the AMODE 64 limits, the Java setup and the z/OS UNIX recommendation make the OO route heavier than aCALL. -
A lighter alternative appeared. The non-OO interoperability of 6.4 and 6.5 and, in other places, web services and the JSON features of JSON GENERATE and PARSE connect COBOL to Java without classes.
-
Verbosity. The syntax is long, and a skilled COBOL team gains little from
INVOKE BK "checkOut" RETURNING COPIES-LEFToverCALL "BOOKITEM".
The result is that OO COBOL is mostly met as inherited code in a few Visual COBOL and Java-integration projects. Nothing here suggests starting a new z/OS batch system with it. When you do meet it, the sections above map the keywords to the manuals.
Common mistakes
-
Compiling a class with GnuCOBOL.
CLASS-ID,METHOD-IDandINVOKEgive "reserved word, but isn’t supported" in 3.2. Use a procedural design, or a vendor compiler for the OO dialect. -
Passing arguments
BY REFERENCEtoINVOKE. On Enterprise COBOL arguments toINVOKEare passedBY VALUEonly. -
Forgetting
RETURNINGonINVOKE ... NEW. The phrase is required, andUSINGis not allowed for COBOL classes. -
Wrong case in a method name. Method names are case-sensitive literals;
"checkout"does not find"checkOut", and withoutON EXCEPTIONa severity-3 condition is raised. -
Putting
EXEC SQLorEXEC CICSin a class. Neither is allowed in an Enterprise COBOL OO program that uses Java interoperability; keep that code in procedural programs and let the class call them. -
Omitting
THREAD. Mixing COBOL with Java requires theTHREADcompiler option. -
Reaching for OO to call Java. For most existing programs, the non-OO interoperability of 6.4 and 6.5 is the simpler route.
-
Combining several classes in one source file. Each COBOL class definition must be in its own file.
References
-
Enterprise COBOL for z/OS 6.5 Language Reference: COBOL class definition structure
-
Enterprise COBOL for z/OS 6.5 Language Reference: INVOKE statement
-
Enterprise COBOL for z/OS 6.5 Language Reference: CALL statement
-
Enterprise COBOL for z/OS 6.5 Programming Guide: Writing object-oriented programs
-
Enterprise COBOL for z/OS 6.5 Programming Guide: Defining a class
-
Enterprise COBOL for z/OS 6.5 Programming Guide: Defining a subclass
-
Enterprise COBOL for z/OS 6.5 Programming Guide: Non-OO COBOL/Java interoperability overview
-
Tom Taulli, Modern Mainframe Development, O’Reilly Media, 2022 (chapter 7, consulted for the topics only)