COBOL Programming With VSCode PDF
COBOL Programming With VSCode PDF
Programming
with VSCode
A beginner’s guide to COBOL using modern tooling
Preface
Abstract
One computer programming language was designed specifically for business,
Common Business-Oriented Language, COBOL. Today COBOL remains as
relevant as ever, handling $3 trillion in commerce every day.
William Yates is a Software engineer working for IBM UK. For the majority of
his career he has working on the CICS TS product mainly as a software tester and
now as Test Architect. He has delivered technical content for many Redbooks,
video courses and at conferences around the world. He is also one of the leaders
of the Galasa project, building an open source integration test framework for
hybrid cloud applications available at https://galasa.dev
Acknowledgements
Special thanks to the following people for participating in the residency to shape
the content in this publication.
➢ Dr. Tak Auyeung, Professor, American River College
➢ Jeffrey Bisti, Z Ecosystem Architect, IBM
➢ Ilicena Elliott, IT Specialist II, Employment Development Department
➢ Martin Keen, Technical Content Services, IBM
➢ Sudharsana Srinivasan, z Influencer Ecosystem Program Coordinator, IBM
➢ Suzy Wong, Information Technology Specialist, DMV
Left-to-right: Ilicena, Suzy, Makenzie, Martin, Paul, and Tak
Part 1 - Getting started
Chapter 1. Why COBOL?
1 https://thenewstack.io/cobol-everywhere-will-maintain/
2 https://freedomafterthesharks.com/2016/06/27/exactly-what-is-cobol-and-why-is-cobol-still-a-widely-used-language-in-it/
1.3 Why should I care about COBOL?
The COBOL programming language, COBOL compiler optimization, and
COBOL run time performance have over 50 years of technology advancements
that contribute to the foundation of world's economy. The core business logic of
many large enterprises has decades of business improvement and tuning
embedded in COBOL programs.
The point is - whatever you read or hear about COBOL, be very skeptical. If you
have the opportunity to work directly with someone involved in writing or
maintaining critical business logic using COBOL, you will learn about the
operation of the core business. Business managers, business analysts, and decision
makers come and go. The sum of all good business decisions can frequently be
found in the decades of changes implemented in COBOL programs. The answer
to "How does this business actually work?" can be found in COBOL programs.
Add the following to your awareness of COBOL. It is an absolute myth that you
must be at least 50 years old to be good with COBOL. COBOL is incredibly easy
to learn and understand. One of the many reasons financial institutions like
COBOL, is the fact that it is not necessary to be a programmer to read and
understand the logic. This is important because critical business logic code is
subject to audit. Auditors are not programmers. However, auditors are
responsible for ensuring the business financial statements are presented fairly. It
is COBOL processing that frequently result in the business ledger updates and
subsequent financial statements.
It's no secret that lots of banks still run millions of lines of COBOL on
mainframes. They probably want to replace that at some point. So why haven't
they? Most banks have been around long enough to still feel the pain from the
~1960's software crisis. After spending enormous amounts of money, and time,
on developing their computer systems, they finally ended up with a fully
functional, well-tested, stable COBOL core system.
Speaking with people that have worked on such systems, nowadays they have
Java front ends and wrappers which add functionality or more modern interfaces,
they run the application on virtualized replicated servers, but in the end,
everything runs through that single core logic. And that core logic is rarely
touched or changed, unless necessary.
From a software engineering perspective, that even makes sense. Rewrites are
always more expensive than planned, and always take longer than planned (OK,
probably not always. But often.). Never change a running system etc., unless very
good technical and business reasons exist.
2. VSCode with Z Open Editor and ZOWE
extensions
In this chapter we will explain how to use the IBM Z Open Editor extension for
VSCode and how using it can help you develop COBOL source code in a feature
rich environment.
➢ 2.4 Code-completion
▪ COBOL reserved word completion
▪ Variable completion
▪ CICS, MQ, DB2 API completion
➢ 2.6 Summary
2.1 Introduction to the IBM Z Open Editor
This section introduces the IBM Z Open Editor.
The language server protocol defines six broad capabilities that should be
implemented for a language server to be LSP compliant. These capabilities
include code completion, hover, jump to definition, workspace symbols, find
references and diagnostics. The IBM Z Open Editor provides compliant language
servers for both the Enterprise Cobol and Enterprise PL/I for z/OS languages. In
addition to being compliant, they also provide additional capabilities that we will
discuss further on.
Note: More information on Language Server Protocol implementations can be found at:
https://langserver.org
2.2.2 Margins
The first thing you will notice when editing COBOL source code is that VSCode
will have inserted five vertical lines down the file. These lines segment each line
of code into the areas reserved for sequence numbers, comment / continuation
characters, area A and area B. When coding without this basic aid I cannot
recount the number of times I have made a compilation error because I started
coding in the wrong column. This alone is a very useful aid to a new COBOL
programmer. Move information about COBOL syntax and in particular the
columns will be discussed later
2.2.3 Variable expansion
As you browse through CBL001.COBOL type CTRL + G to jump to a specific
line of code. A small dialog will open asking you for the line you wish to jump
to, type 68 and press the enter key. VSCode will highlight that line of code and
navigate you directly to it, as shown in Figure 1.
If you hover your mouse over the 'ACCT-NO-O' field a pop up will appear
displaying the declaration of that variable, shown in Figure 2.
Since this field is a 05-level variable nested within a 01-level variable, the pop up
shows the declaration of the field as an eight-byte picture variable, the name of
the parent structure and the file definition that it is within. If you hold the
CMD/Ctrl key while hovering over the field, then the pop up will additionally
contain the line of code where the variable is defined as well as the following
three lines of code. These features can be extremely helpful when analyzing
existing code.
Clicking on any of the items in the breadcrumb trail will highlight that element of
the code in the editor, quickly showing you the location of that element within the
code. It will also show a view of the code in a pop-up window, shown in Figure
5. , similar to the outline view previously discussed.
Figure 5. Pop-up view of code via breadcrumb selection
Note: If SHIFT+F12 does not work for your machine, you may need to use the
key combination, Fn+F12 instead.
Figure 6. Finding paragraph/variable references in VSCode
2.4 Code-completion
Code completion isn't exactly a new concept in most IDEs. For example, the
Eclipse editor has provided auto-completion for Java APIs for a long time. The
same key combination, CTRL+SPACE, triggers this auto-completion function
while you are coding and can be used to help guide you through COBOL syntax
and CICS, IMS API calls.
You can see that not only is the variable ACCT-BALANCE prompted as a
potential candidate, but it also presents ACCT_BALANCE IN ACCT-FIELDS.
You will note that both the declaration of the variable and the reference on line 68
have been updated to the new value. As stated previously, the same process also
works for paragraph names. For example, go ahead and refactor the name of the
paragraph READ-RECORD to be READ-NEW-RECORD.
Now we need to introduce an error into the code. After line 68, add the line:
MOVE ACCT-NO TO ACCT-N-0.
Note that this line incorrectly identifies the second variable, which doesn't exist.
Once entering that line, you will notice that the invalid variable has been
underlined in red to highlight it as an error. Also, the problems view has a new
error. Clicking on the error will highlight the line of code at fault in the editor,
shown in Figure 10. , allowing you to view the error directly.
Now that you see where the error is located, it can now be corrected. As soon as
the error has been rectified, the problem disappears from the problem view.
2.6 Summary
In this chapter you have been able to go through some of the editing features of
the Z Open Editor for VSCode. These capabilities make editing COBOL, PL/Iand
JCL a lot friendlier and easier than some of the other editors in the market.
3. Installation of VSCode and extensions
This chapter covers all aspects of download and installation of Visual Studio (VS)
Code and any prerequisites that are needed. It includes:
➢ 3.4 Summary
3.1 Install prerequisites
This section will cover the necessary steps and information to download and
install the prerequisites needed for the subsequent labs within this book. This
software is needed for one of more of the applications we will be utilizing in our
labs throughout the book. The prerequisites include:
➢ 3.1.1 - Install node.js
➢ 3.1.2 - Install Java SDK
If you do not see a version number after you submit the command, you do not
have node.js installed, or if it shows a version less than v8, you should continue
following these instructions. If you do see a version number and it is v8 or
higher, you can move on to section 3.1.2, Install Java SDK.
https://nodejs.org/en/download/
This process will install the latest versions of Node.js and the node package
manager (npm) and overwrite any older version files in your system. This
removes the step of needing to manually uninstall the previous versions
beforehand.
3. Once completed, verify the installation and proper version number, as shown
previously in Example 1.
Note: The version numbers in our examples are provided purely for reference and
may not reflect the latest versions of the software.
If you do not see a version number after you submit the command, you do not
have Java installed or if it shows a version less than v8, you should continue
following these instructions. The display format of the version number for Java is
slightly different than what is displayed for node.js. With Java, the second value
in the displayed version number, i.e. the "8" in Example 2. , is the version
number. So, our example is showing Java SDK version 8. If you do see a version
number and it is v8 or higher, you can move on to section 3.2, Install VSCode.
2. If your version of Java displayed is less than v8, you need to uninstall the
current version on your workstation and reinstall the correct version. Follow
the link below to uninstall instructions that represent your workstation
operating system (OS).
o Linux:
https://www.java.com/en/download/help/linux_uni
nstall.xml
o Mac:
https://www.java.com/en/download/help/mac_unins
tall_java.xml
o Windows:
https://www.java.com/en/download/help/uninstall
_java.xml
3. Once Java is uninstalled from your workstation, you can click the Java JDK 8
download link below and follow the installation instructions for your specific
OS.
https://www.oracle.com/java/technologies/javase-
jdk8-downloads.html
Note: You will be prompted to register a new Oracle account in order to download
the installation file, please do so. If you have an existing account, you may use
that to log in and continue.
https://code.visualstudio.com/download
Note: Be sure to select the correct installation file for your workstations respective OS,
shown in Figure 1.
https://ibm.github.io/zopeneditor-
about/Docs/zowe_interactwithzos.html.
https://ibm.github.io/zopeneditor-
about/Docs/introduction.html#key-capabilities.
Note: There may be some limitations with IBM Z Open Editor if running a 32-
bit Java version on Windows.
3.4 Summary
In this chapter you have been introduced to VSCode and some of the extension
tools available to it. We have walked through the process of installing the pre-
requisite software, Node.js and Java SDK, as well as VSCode, Zowe Explorer and
IBM Z Open Editor. You have also been briefly introduced to the utility of these
extensions in VSCode. In the subsequent chapters we will delve deeper into how
and when to use them and get some practice through lab assignments.
Part 2 - Learning COBOL
Chapter 4. Basic COBOL
➢ 4.6 Lab 1
4.1 COBOL characteristics
COBOL is an English-like computer language enabling COBOL source code to
be easier to read, understand, and maintain. Learning to program in COBOL
includes knowledge of COBOL source code rules, COBOL reserved words,
COBOL structure, and the ability to locate and interpret professional COBOL
documentation. These COBOL characteristics must be understood, to be
proficient in reading, writing, and maintaining COBOL programs.
4.2.1 What are the coding rules and the reference format?
COBOL source code is column dependent, meaning column rules are strictly
enforced. Each COBOL source code line has five areas, where each of these
areas has a beginning and ending column.
A few COBOL reserved words pertinent to this book are: PERFORM, MOVE,
COMPUTE, IF, THEN, ELSE, EVALUATE, PICTURE, etc.. You can find a
table of all COBOL reserved words is located at:
https://www.ibm.com/support/knowledgecenter/zh/SSZJPZ_
9.1.0/com.ibm.swg.im.iis.ds.mfjob.dev.doc/topics/r_dmn
jbref_COBOL_Reserved_Words.html
1. IDENTIFICATION DIVISION
The IDENTIFICATION DIVISION identifies the program with a name and,
optionally, gives other identifying information, such as the Author name, program
compiled date (last modified), etc.
2. ENVIRONMENT DIVISION
The ENVIRONMENT DIVISION describes the aspects of your program that
depend on the computing environment, such as the computer configuration and
the computer inputs and outputs.
3. DATA DIVISION
The DATA DIVISION is where characteristics of data are defined in one of the
following sections:
➢ FILE SECTION:
Defines data used in input-output operations.
➢ LINKAGE SECTION:
Describe data from another program.
4. PROCEDURE DIVISION
The PROCEDURE DIVISION contains instructions related to the manipulation
of data and interfaces with other procedures are specified.
https://www.ibm.com/support/pages/enterprise-cobol-
zos-documentation-library
Three ‘Enterprise COBOL for z/OS” manuals are referenced throughout the
chapters as sources of additional information, for reference and to advance the
level of knowledge. They are:
1. Language Reference - Describes the COBOL language such as program
structure, reserved words, etc.
http://publibfp.boulder.ibm.com/epubs/pdf/igy6lr3
0.pdf
4.6 Lab 1
In this lab exercise you will connect to an IBM Z system, view a simple COBOL
hello world program in VSCode, submit JCL to compile the COBOL program,
and view the output. Refer to Chapter 3, “ Installation of VSCode and
extensions”, to configure VSCode with the Zowe Explorer and Z Open Editor
extensions if you have not already done so.
1. The lab assumes installation of VSCode with Z Open Editor and Zowe
Explorer extensions as shown in Figure 2.
4. A box appears to define a new profile. Click + to the left of Create a New
Connection to z/OS as shown in Figure 5.
6. VSCode prompts for z/OSMF URL and port as shown in Figure 7. The
z/OSMF URL and port will normally be provided by z/OS System
Administrator.
10. The connection prompts for the Username Password as shown in Figure 11.
13. Result is Favorites in the Data Sets, Unix System Services, and Jobs sections
as shown in Figure 14.
14. Again, click on the + to the far right on the Data Sets selection. Result is
another prompt to Create a New Connection to z/OS. LearnCOBOL is in the
connection list. Select LearnCOBOL for the Data Sets available to the
previously defined LearnCOBOL connection to z/OS as shown in Figure 15.
15. Expansion of LearnCOBOL reads “Use the search button to display datasets”.
Click the search button as shown in Figure 16.
Figure 16. Search button
16. A prompt to “Select a filter” appears for ID Z99998. Select the + to ‘Create a
new filter” as shown in Figure 17.
17. A prompt appears to enter the filter name to be searched as shown in Figure
18.
18. ID Z99998 has lab data set names that begin the Z99998. Therefore, Z99998
is entered as the filter to searched for ID Z99998 as shown in Figure 19.
19. A list of data set names beginning with Z99998 for ID Z99998 from z/OS
Connection LearnCOBOL appears as shown in Figure 20.
Figure 20. Filtered data set names
20. Expand Z99998.CBL to view COBOL source members, then select member
HELLO to see a simple COBOL ‘Hello World!’ program as shown in Figure
21.
21. Expand Z99998.JCL to view JCL and select member HELLO which is the
JCL to compile and execute simple ‘Hello World!’ COBOL source code as
shown in Figure 22.
23. Observe the ‘Jobs’ section in Zowe Explorer as shown in Figure 24.
24. Again, click on the + to the far right on the Jobs selection. Result is another
prompt to ‘Create new’. Select LearnCOBOL from the list as shown in
Figure 25.
25. As a result, the JCL jobs owned by ID Z99998 appears. HELLOCBL is the
JCL job name previously submitted. Expand HELLOCBL output to view
sections of the output as shown in Figure 26.
Figure 26. HELLOCBL output
28. The following URL is another excellent document describing the above
VSCode and Zowe Explore details with examples:
https://marketplace.visualstudio.com/items?itemName=
Zowe.vscode-extension-for-zowe
5. Data division
Understanding COBOL variables and program processing of variables are
essential to effectively learning the COBOL language. An experienced COBOL
programmer must master characteristics of COBOL variables and the program
processing using the variables introduced in this chapter. The objective is to
introduce the reader to the basics of COBOL variables while exposing the reader
to the many advanced COBOL variable options.
Following this chapter is a lab available to compile and execute the COBOL
source code provided later in the chapter. Following the successful compile and
execution of one provided program, a second provided COBOL program with a
minor change is available to compile. The second program has an embedded
error and on compile will fail. The failed compilation is an opportunity to
identify the error associated with the significance of PICTURE clause data types
associated with the operation of the COMPUTE statement (discussed in this
chapter) and how to solve the error.
➢ 5.3 Literals
▪ Figurative constants
▪ Data relationships
▪ Levels of data
➢ 5.5 Lab 2
5.1 Variables / Data-items
A COBOL variable, also known as a data-item, is a name and is chosen by the
COBOL programmer. The named variable is coded to hold data where the data
value can vary, hence the generic term 'variable'. A COBOL variable name is also
known as 'Data Name'. A COBOL variable name has restrictions.
Note: A full list of COBOL reserved words can be found in the Enterprise COBOL
Language Reference, Appendix E.
When COBOL source code is compiled into an executable program, the COBOL
compiler is expecting a named COBOL variable to possess attributes such as a
length and data type. During program execution, the variable represents a defined
area of processing memory where the memory location has a maximum length
and designated data type.
A list of the most common COBOL data types are:
➢ Numeric (0-9)
➢ Alphabetic (A-Z), (a-z), or a space
➢ Alphanumeric Numeric and Alphabetic Combination
5.3 Literals
A COBOL literal is constant data value, meaning the value will not change like a
variable can. The COBOL statement, DISPLAY "HELLO WORLD!", is a
COBOL reserved word, DISPLAY, followed by a literal, HELLO WORLD!
Level numbers
A structured level number hierarchic relationship is available to all DATA
DIVISION sections. Figure 1. shows the level number hierarchic relationship
with programmer chosen level numbers, variable names and PIC clauses in the
File Section where “01 PRINT-REC” references the following “05”-level group
of variables and the “01 ACCT-FIELDS” references the following “05"-level
group of variables. Observe 05-level CLIENT-ADDR is further subdivided into
several 10-level names. COBOL code referencing the name CLIENT-ADDR
includes the 10-level names.
1. View the PAYROL00 COBOL source code member in the 'id'.CBL data set.
2. Submit the JCL member, PAYROL00, from the id.JCL, where id is your
id,dropdown. This is where id.JCL(PAYROL00) compiles and successfully
executes the PAYROL00. program.
Note: If you receive this error message after submitting the job:
That is because you submitted the job from the .CBL data set and not the .JCL data set.
3. View both compile and execution of PAYROL00 job output, referenced in Figure
4.
Compile
Execution
4. Next, view PAYROL0X COBOL source code member in id.CBL data set.
5. View and submit the JCL member, PAYROL0X, from the id.JCL dropdown. This
is where id.JCL(PAYROL0X) compiles and executes the PAYROL0X program.
Do you notice a difference between this compile and the previous job compile
shown in Figure 5. ?
The difference is the return/completion code associated with each job output,
located both next to the job output name within the JOBS section as shown above,
or at the end of the compile output as, 0Return code ##. A return code of 12
means there was an error, but how do we know what that error was? Continue to
find out!
7. Observe the text associated with IGYPA3146-S on line 137 within the job output
(compile), illustrated in Figure 6.
8. After modifying, re-submit the PAYROL0X JCL to verify the problem has been
identified and corrected, resulting in a successful compile and execution with a
return code of zero, shown in Figure 7.
First Submit
Second Submit
➢ 6.4 Lab 3
6.1 COBOL code used for sequential file handling
COBOL code used for sequential file handling involves:
➢ ENVIRONMENT DIVISION.
o SELECT clauses
o ASSIGN clauses
➢ DATA DIVISION.
o FD statements
➢ PROCEDURE DIVISION.
o OPEN statements
o CLOSE statements
o READ INTO statement
o WRITE FROM statement
Figure 1. FILE-CONTROL
While SELECT gives a name to an internal file and ASSIGN gives a name to the
external dataset name, a COBOL program needs more information about both.
The COBOL compiler is given more information about both in the DATA
DIVISION, FILE SECTION.
The COBOL reserved word 'FD' is used to give the COBOL compiler more
information about internal file names in the FILE-SECTION. The code below the
FD statement is the record layout. The record layout consists of level numbers,
variable names, data types, and lengths as shown in Figure 2.
Figure 2. FILE-SECTION
6.1.5 Blocks
Each record read by the program can result in disk storage access. A program
typically reads 1 record at a time in sequential order until all records are read.
When a record is read, the record retrieved from disk is stored in memory for
program access. When each next record read requires the need to retrieve the
record from disk, system performance is impacted negatively. Records can be
blocked where a block is a group of records. The result is when the first record is
read, then an entire block of records is read into memory assuming the program
will be reading the second, third, etc. records avoiding unnecessary disk retrievals
and negative system performance. The memory holding a record or block of
records to be read by the program is known as a buffer. COBOL BLOCK
CONTAINS clause is available to specify the size of the block in the buffer.
Observe Figure 3.
The JCL statement required by the compiled COBOL program during execution
to redirect ACCTREC to the MY.DATA z/OS controlled dataset is shown in
Example 2.
Example 2. JCL statement
——————————————————————————————————————————————————————
//ACCTREC DD DSN=MY.DATA,DISP=SHR
As a result, the COBOL internal ACCT-REC file name reads data records from
sequential dataset named MY.DATA.
JCL is a separate z/OS technical skill. The introduction to COBOL explains just
enough about JCL to understand how the COBOL internal file name locates the
external sequential dataset name. To read more on JCL, visit the IBM Knowledge
Center:
https://www.ibm.com/support/knowledgecenter/zosbasics/
com.ibm.zos.zjcl/zjclc_basicjclconcepts.htm
Figure 4. OPEN-FILES
6.2.2 Close input and output
COBOL inputs and outputs should be closed at program completion or better yet
when the program is done reading from or writing to the internal file name.
Figure 5. closes the internal file name ACCT-REC and internal file name PRINT-
LINE, then stops processing, STOP RUN.
Figure 5. CLOSE-STOP
➢ READ-NEXT-RECORD
➢ CLOSE-STOP
➢ READ-RECORD
➢ WRITE-RECORD
Note: COBOL is English-like and COBOL reserved words are English-like. The
programmer is free to use English-like variable names to help remember the purpose of the
variable names. The PROCEDURE DIVISION structure is English-like. A paragraph
contains one or more sentences. A sentence contains one or more statements. The implicit
scope terminator, a period (.), terminates a sentence or terminates several consecutive
statements which would be analogous to a compounded sentence where ‘and’ joins
potentially independent sentences together.
6.4 Lab 3
The lab associated with this chapter demonstrates the ‘end-of-file’ COBOL
coding technique for reading all data records from a sequential file. If a step has
an asterisk (*) next to it, it will have a hint associated at the end of the lab content.
1. If not already, open VSCode and select Zowe Explorer from the left sidebar.
Note: If you are opening a new instance of VSCode (i.e. you closed out of it after the previous
usage), you may need to 'Select a filter' again. You can do so by selecting the search icon ( )
next to your named connection in the DATA SETS section and then reselecting the filter
previously used. It should be in the listed filters after you have selected the search symbol.
2. View these COBOL source code members listed in the id.CBL data set:
➢ CBL0001
➢ CBL0002
Figure 8. Id.JCL(CBL0001J).jcl
Locate COBOL compiler severe message IGYPS2121-S within the output file
referred to in step 7, shown in Figure 10.
8. Edit CBL(CBL0002):
➢ Determine appropriate spelling of PRINT-REX, correct it within the source
code and save the updated source code.
9. Re-submit job, JCL(CBL0002J), using the DATA SET section and view the
output in the JOBS section.
➢ COBRUN:SYSPRINT(101) COBOL program compiler output
➢ RUN:PRTLINE(103) is the COBOL program execution output (if correction
is successful)
14. View CBL0003J output using the JOBS section, your output should look like
Figure 12.
➢ RUN:PRTLINE - COBOL program execution output (if correction is
successful)
➢ 7.6 Summary
7.1 Styles of programming
Before we discuss in more detail how to structure a program written in COBOL,
it's important to understand the type of language COBOL is and how it's both
different from other languages and how it affects the way you might structure
your programs.
...
CLOSE PRINT-LINE.
STOP RUN.
Although this code is very simple to read, it's not very elegant, there is a lot of
code repetition as the number is increased. Obviously, we want to provide some
structure to the program. There are three keywords that we can use to transfer
control to a different section of the source code and provide the structure we need.
These keywords are PERFORM, GO TO and CALL.
PERFORM WRITE-NEW-RECORD.
PERFORM WRITE-NEW-RECORD.
PERFORM WRITE-NEW-RECORD.
PERFORM WRITE-NEW-RECORD.
PERFORM WRITE-NEW-RECORD.
PERFORM WRITE-NEW-RECORD.
PERFORM WRITE-NEW-RECORD.
PERFORM WRITE-NEW-RECORD.
PERFORM WRITE-NEW-RECORD.
PERFORM WRITE-NEW-RECORD.
CLOSE PRINT-LINE.
STOP RUN.
WRITE-NEW-RECORD.
ADD 1 TO COUNTER GIVING COUNTER
MOVE COUNTER TO MSG-TO-WRITE
WRITE PRINT-REC.
In this example, the three lines of code that constructed a new line of output and
printed it has been extracted into a new paragraph called WRITE-NEW-
RECORD. This paragraph is then performed ten times by use of the PERFORM
keyword. Each time the PERFORM keyword is used, execution jumps to the
paragraph WRITE-NEW-RECORD, executes the three lines contained within that
paragraph before returning to the line following the PERFORM statement. The
concept of a paragraph will be covered later in this chapter in more depth.
CLOSE PRINT-LINE.
STOP RUN.
In this example, we are using the PERFORM keyword in a way that is similar to a
for loop in other languages. The loop runs from the PERFORM keyword to the
END-PERFORM keyword. Each time execution iterates over the loop, the value
of COUNTER is incremented and tested by one. For comparison, the same loop
would be written in Java like so:
Although the COBOL version is perhaps more verbose than a for loop in other
languages, it is easier to read, and remember you always have autocomplete (if
you are using a good editor) to help you with the typing.
Example 5. GO TO example
——————————————————————————————————————————————————————
PERFORM WRITE-NEW-RECORD.
GO TO WRITE-NEW-RECORD.
PERFORM WRITE-NEW-RECORD.
If we were to compile and run the program, you would see that although the job
ABENDS (abnormally ends) with a 4038-abend code, it did execute some of the
code and wrote the first two lines of the output. If you were to look at the output
in more detail, you would see a message like the following:
So, what went so terribly wrong when we used the GO TO command? To answer
this, we need to understand the key difference between GO TO and PERFORM.
On the first line we used the PERFORM keyword, that transferred control to the
WRITE-NEW-RECORD paragraph. Once the execution reached the end of that
paragraph, execution returned to the line following the PERFORM statement.
The next line used the GOTO keyword to again transfer control to the WRITE-
NEW-RECORD paragraph, which prints the second line of output. However,
when that paragraph completed, execution continued to the next line following the
WRITE-NEW-RECORD paragraph. Since there are no lines of code following
that paragraph the processor tried to execute code beyond the program, z/OS
caught this as a problem and abended the program.
As we can see, the use of GO TO causes a branch of execution that doesn't return
to the line of code that issued it. Let's demonstrate how messy this code can get:
Note: Both the TO and ON parts of the conditional GO TO statement can be omitted,
giving a statement that looks like GO SAY-HELLO-WORLD DEPENDING FLAG.
Which although is less verbose, is no less easy to understand.
So why teach you something that we have said is messy and not advised? Well,
by giving you some understanding of its behavior, you will be better equipped
when looking through existing code and maintaining it.
Considering that a program can be made up of multiple paragraphs and that the
PERFORM keyword can be used to call the paragraph, either conditionally or as
part of a loop, it is easy to see that good paragraph design really helps makes your
COBOL more structured and readable.
Remember that you can also perform other paragraphs within existing paragraphs.
This nested calling of paragraphs can again, help to structure your code. (maybe
an example here)
Because the paragraphs are numbered and appear in the source code in that
order, when a sentence references a paragraph it is easier to know where in the
program that paragraph might appear. When initially structuring a program in
this way, the numbers used would only increment the highest significant
figure, allowing for new paragraphs to be inserted in between if needed.
Although the rise of modern editors, which allow outlining and instant
jumping to a reference or declaration, makes this technique of less necessity, it
is still useful to understand.
1000-OPEN-FILES.
OPEN INPUT ACCT-REC.
OPEN OUTPUT PRINT-LINE.
*
2000-READ-NEXT-RECORD.
PERFORM 4000-READ-RECORD
PERFORM UNTIL LASTREC = 'Y'
PERFORM 5000-WRITE-RECORD
PERFORM 4000-READ-RECORD
END-PERFORM.
*
3000-CLOSE-STOP.
CLOSE ACCT-REC.
CLOSE PRINT-LINE.
STOP RUN.
*
4000-READ-RECORD.
READ ACCT-REC
AT END MOVE 'Y' TO LASTREC
END-READ.
*
5000-WRITE-RECORD.
MOVE ACCT-NO TO ACCT-NO-O.
MOVE ACCT-LIMIT TO ACCT-LIMIT-O.
MOVE ACCT-BALANCE TO ACCT-BALANCE-O.
MOVE LAST-NAME TO LAST-NAME-O.
MOVE FIRST-NAME TO FIRST-NAME-O.
MOVE COMMENTS TO COMMENTS-O.
WRITE PRINT-REC.
——————————————————————————————————————————————————————
The required number of times that the code should be executed can either be a
literal, as above, or the value of a numeric variable as shown in Example 11.
where the PERFORM keyword is being used to execute a paragraph.
Note: The use of the THRU keyword can also be used alongside the TIMES, UNTIL
and VARYING keywords, to allow the list of paragraphs to be executed rather than just
a single paragraph or blocks of code.
In this case, the Boolean condition is evaluated before the loop is executed.
However, if you wish for the loop to be executed at least once before the
condition is evaluated, you can alter the sentence to read:
In this example, the variable counter is tested to see if it equals 11, as long as it
doesn't then it is incremented, and the sentences nested within the perform
statement are executed. This construct can be extended, exemplified in Example
18.
This is really, just two for loops nested within each other. This construct is very
useful when iterating over tables or nested record structures. As for each loop of
the outer varying loop, the inner loop will be executed five times. As mentioned
previously, the test of the condition will be assumed by COBOL to be at the
beginning of the loop, however, it can be specified to be evaluated at the end of
the loop by adding the phrase WITH TEST AFTER to the initial perform
sentence.
7.5 Using subprograms
So far, we have only examined the internal structure of a single COBOL program.
As programs increase in function and number, it is common that a programmer
might want certain aspects of a programs function to be made available to other
programs within the system. Abstracting generic functions into their own
program and allowing them to be called from other programs can reduce the
amount of code duplication within a system and therefore decrease the cost of
maintenance, as fixes to shared modules only need to be made once.
Note: Although here we will describe the COBOL native way of calling another program,
note that some middleware products will provide APIs that might do this in an enhanced
way.
When calling another program, we need to consider three main concerns: how we
will reference the program we wish to call, the parameters we want to send to the
target program and the parameter that we wish the target program to return.
Note: When passing variables either BY REFERENCE or BY CONTENT, note you can
send data items of any level. Which means you can pass entire data structures, handy for
dealing with common records.
You might also see the phrase, BY VALUE, being used in a CALL sentence. BY
VALUE is similar to BY CONTENT, as a copy of the content of the variable is
passed. The difference is that only a subset of COBOL datatypes are supported
and you can only specify elementary data-items. This is because BY VALUE is
primarily used when COBOL is calling a program of another language (such as
C).
7.6 Summary
In summary, this chapter should provide the necessary foundation to understand
structured programming and how it relates to COBOL and its importance to
understanding and maintaining code. Many examples of how, when and why to
implement key techniques have been provided and explained for further
understanding. You should be able to identify the basic differences between
structured programming (COBOL) and OO programming (Java). You should
also understand the general concept of the best practices in the structure of the
Procedure Division with reference to the design and content of paragraphs,
program control options and ways to call other programs within the same system.
8. File output
Designing a structured layout that is easy to read and understand is required to
format output. Designing a structured layout involves column headings and
variable alignment using spaces, numeric format, currency format, etc. This
chapter aims to explain this concept utilizing example COBOL code to design
column headings and align data names under the such headings. At the end of the
chapter you are asked to complete a lab that practices implementation of the
components covered.
A capability of COBOL data output formatting that is worth noting but not
covered in this chapter is that COBOL is a web enabled computer language.
COBOL includes easy and quick transformation of existing COBOL code to write
JSON (JavaScript Object Notation) where the output is sub-sequentially formatted
for a browser, a smartphone, etc. Frequently, the critical data accessed by a smart
phone, such as a bank balance, is stored and controlled by z/OS where a COBOL
program is responsible for retrieving and returning the bank balance to the smart
phone.
➢ 8.5 Lab 4
8.1 Review of COBOL write output process
This section briefly reviews certain aspects of the ENVIRONMENT DIVISION
for the purpose of understanding how it ties together with the content of this
chapter.
8.2.1 FILLER
Observe the data name FILLER. While most data fields have unique names,
FILLER is a COBOL reserved word data name, that is useful for output
formatting. This is in part because FILLER allocates memory space without the
need for a name. Also, FILLER allocated memory has a defined length in the
output line and may contain spaces or any literal. Figure 2. shows multiple
VALUE SPACES for FILLER. SPACES create white space between data-items
in the output which is valuable in keeping the code readable. More specifically in
Figure 2. FILLER PIC X(02) VALUE SPACES, represents the output line
containing two spaces.
Figure 2. FILLER
➢ HEADER-2:
o Writes literals
o Examples:
▪ ‘Year’ followed by a variable name
▪ ‘Month’ followed by a variable name
▪ ‘Day’ followed by a variable name
➢ HEADER-3:
o Writes literals
o Examples:
▪ ‘Account’ followed by FILLER spacing
▪ ‘Last Name’ followed by FILLER spacing
▪ ‘Limit’ followed by FILLER spacing
▪ ‘Balance; followed by FILLER spacing
➢ HEADER-4:
o Writes dashes followed by FILLER spacing
Figure 3. Designed output structure layout
8.3.1 HEADER-2
HEADER-2 includes the year, month, day of the report together with FILLER
area, creating blank spaces between the year, month, and day, as you can see in
Figure 3. Figure 4. is an example of the data name layout used to store the
values of CURRENT-DATE. The information COBOL provides in CURRENT-
DATE is used to populate the output file in HEADER-2.
.
Figure 4. CURRENT-DATE intrinsic function
4. Observe the report data lines are written without dollar currency symbol,
illustrated in Figure 7.
7. Observe the report data lines should now include the dollar currency symbol.
➢ 9.5 Conditions
▪ Relation conditions
▪ Class conditions
▪ Sign conditions
➢ 9.6 Lab 5
9.1 Boolean logic, operators, operands, and identifiers
Programs make decisions based upon the programmer written logic. Program
decisions are made using Boolean logic where a conditional expression is either
true or false, yes or no. A simple example would be a variable named
'LANGUAGE'. Many programming languages exist; therefore, the value of
variable LANGUAGE could be Java, COBOL, etc... Assume the value of
LANGUAGE is COBOL. Boolean logic is, IF LANGUAGE = COBOL, THEN
DISPLAY COBOL, ELSE DISPLAY NOT COBOL. IF triggers the Boolean
logic to determine the condition of true/false, yes/no, applied to LANGUAGE =
COBOL which is the conditional expression. The result of IF condition executes
what follows THEN when the condition is true and executes what follows ELSE
when the condition is false.
A list of COBOL Boolean relational operators for each of the common type of
COBOL conditional expressions are represented in Figures 1, 2 and 3 below.
9.5 Conditions
A conditional expression can be specified in either simple conditions or complex
conditions. Both simple and complex conditions can be enclosed within any
number of paired parentheses; the parentheses, however, do not change whether
the condition is simple or complex. This section will cover three of the five
simple conditions:
➢ Relation
➢ Class
➢ Sign
Note: To read more information about these conditions please visit the link:
IBM Knowledge Center - Enterprise COBOL for z/OS 4.2.0
9.6 Lab 5
This lab requires two COBOL programs, CBL0006 and CBL0007 and two
respective JCL Jobs, CBL0006J and CBL0007J, to compile and execute the
COBOL programs. All of which are provided to you in your VSCode - Zowe
Explorer.
2. Compare CBL0006 with CBL0005 from the previous lab. Do you notice the
differences?
a. Observe the new CLIENTS-PER-STATE line within the WORKING-
STORAGE > PROCEDURE DIVISION.
b. Observe the new paragraph IS-STATE-VIRGINIA within that same
division.
c. This paragraph checks whether the client is from Virginia. If that
condition is met (true) then the program should add 1 to the clients from
Virginia total.
d. Program writes “Virginia Clients = “, in last line of report.
3. Submit CBL0006J
4. View the job output from the JOBS section and verify the steps mentioned
above were executed.
5. Submit CBL0007J
8. Re-submit CBL0007J
9. Validate that the syntax error was corrected by getting an error free output
file.
Lab Hints
7.
10. Arithmetic expressions
This chapter aims to introduce the concept of implementing arithmetic
expressions in COBOL programs. We will review the basic concept of arithmetic
expressions, operators, statements, limitations, statement operands, as well as
precedence of operation within the expressions. You will be able to follow along
with a comprehensive example exhibiting the usage of arithmetic expressions in a
COBOL program that you have seen in previous chapters and labs. Following the
chapter is a lab to practice the implementation of what you have learned.
➢ 10.6 Lab 6
10.1 What is an arithmetic expression?
Arithmetic expressions are used as operands of certain conditional and arithmetic
statements. An arithmetic expression can consist of any of the following items:
Identifiers and literals that appear in arithmetic expressions must represent either
numeric elementary items or numeric literals on which arithmetic can be
performed. If the value of an expression to be raised to a power is zero, the
exponent must have a value greater than zero. Otherwise, the size error condition
exists. In any case where no real number exists as the result of an evaluation, the
size error condition exists.
- Subtraction - Multiplication by -1
* Multiplication
/ Division
** Exponentiation
10.2.1 Parentheses
Parentheses are used to denote modifications to normal order of operations
(precedence rules). An arithmetic expression within the parentheses is evaluated
first and result is used in the rest of the expression. When expressions are
contained within nested parentheses, evaluation proceeds from the least inclusive
to the most inclusive set. That means you work from the inner most expression
within parentheses to the outer most. The precedence for how to solve an
arithmetic expression in Enterprise COBOL with parentheses is:
1. Parentheses (simplify the expression inside them)
2. Unary operator
3. Exponents
4. Multiplication and division (from left to right)
5. Addition and subtraction (from left to right)
Parentheses either eliminate ambiguities in logic where consecutive operations
appear at the same hierarchic level or modify the normal hierarchic sequence of
execution when necessary. When the order of consecutive operations at the same
hierarchic level is not completely specified by parentheses, the order is from left
to right.
An arithmetic expression can begin only with a left parenthesis, a unary operator,
or an operand (that is, an identifier or a literal). It can end only with a right
parenthesis or an operand. An arithmetic expression must contain at least one
reference to an identifier or a literal.
DIVIDE Superimposing all receiving data items except the REMAINDER data-item
In all arithmetic statements, it is important to define data with enough digits and
decimal places to ensure the required accuracy in the result. Arithmetic precision
details are available in the IBM Enterprise COBOL Programming Guide
Appendix A.
Figure 3. READ-NEXT-RECORD.
Figure 5. WRITE-TLIMIT-TBALANCE
10.6 Lab 6
This lab requires two COBOL programs, CBL0008 and CBL0009 and two
respective JCL Jobs, CBL0008J and CBL0009J, to compile and execute the
COBOL programs. All of which are provided to you in your VSCode - Zowe
Explorer.
2. Submit CBL0008J
3. Observe report written with trailers consisting of limit and balance totals at the
bottom of the output.
4. Submit CBL0009J
5. Was the job successful? If not, find the compile error message to understand
why.
7. Re-submit CBL0009J
8. Validate that the syntax error was corrected by getting an error free output file
like in Figure 8. The correction should report written with trailers consisting
of limit and balance totals, like Figure 6.
➢ 11.3 Lab 7
11.1 Data representation
Data such as numerical values and text are internally represented by zeros and
ones in most computers, including mainframe computers used by enterprises.
While data representation is a somewhat complex topic in computer science, a
programmer does not always need to fully understand how various alternative
representations work. It is important, however, to understand the differences and
how to specify a specific representation when needed.
COMP-1
This is also known as a single-precision floating point number representation.
Due to the floating-point nature, a COMP-1 value can be very small and close to
zero, or it can be very large (about 10 to the power of 38). However, a COMP-1
value has limited precision. This means that even though a COMP-1 value can be
up to 10 to the power of 38, it can only maintain about seven significant decimal
digits. Any value that has more than seven significant digits are rounded. This
means that a COMP-1 value cannot exactly represent a bank balance like
$1,234,567.89 because this value has nine significant digits. Instead, the amount
is rounded. The main application of COMP-1 is for scientific numerical value
storage as well as computation.
COMP-2
This is also known as a double-precision floating point number representation.
COMP-2 extends the range of value that can be represented compared to COMP-
1. COMP-2 can represent values up to about 10 to the power of 307. Like
COMP-1, COMP-2 values also have a limited precision. Due to the expanded
format, COMP-2 has more significant digits, approximately 15 decimal digits.
This means that once a value reaches certain quadrillions (with no decimal
places), it can no longer be exactly represented in COMP-2.
COMP-2 supersedes COMP-1 for more precise scientific data storage as well as
computation. Note that COMP-1 and COMP-2 have limited applications in
financial data representation or computation.
COMP-3
This is also known as packed BCD (binary coded decimal) representation. This
is, by far, the most utilized numerical value representation in COBOL programs.
Packed BCD is also somewhat unique and native to mainframe computers such as
the IBM z architecture.
COMP-4
COMP-4 is only capable of representing integers. Compared to COMP-1 and
COMP-2, COMP-4 can store and compute with integer values exactly (unless a
division is involved). Although COMP-3 can also be used to represent integer
values, COMP-4 is more compact.
COMP-5
COMP-5 is based on COMP-4, but with the flexibility of specifying the position
of a decimal point. COMP-5 has the space efficiency of COMP-4, and the
exactness of COMP-3. Unlike COMP-3, however, a COMP-5 value cannot
exceed 18 decimal digits.
EBCDIC
Extended Binary Coded Decimal Interchange Code (EBCDIC) is an eight binary
digits character encoding standard, where the eight digital positions are divided
into two pieces. EBCDIC was devised in the early 1960’s for IBM computers.
EBCDIC is used to encode text data so that text can be printed or displayed
correctly on devices that also understand EBCDIC.
ASCII
American Standard Code for Information Interchange, ASCII, is another binary
digit character encoding standard.
EBCDIC vs ASCII
Why are these two standards when they seemingly perform the same function?
EBCDIC is a standard that traces its root to punch cards designed in 1931.
ASCII, on the other hand, is a standard that was created, unrelated to IBM punch
cards, in 1967. A COBOL program natively understands EBCDIC, and it can
comfortably process data originally captured in punch cards as early as 1931.
ASCII is mostly utilized by non-IBM computers.
COBOL can encode and process text data in EBCDIC or ASCII. This means a
COBOL program can simultaneously process data captured in a census many
decades ago while exporting data to a cloud service utilizing ASCII or Unicode.
It is important to point out, however, that the programmer must have the
awareness and choose the appropriate encoding.
11.3 Lab 7
Many of the previous COBOL lab programs you have worked with thus far are
reading records containing two packed decimal fields, the client account limit and
the client account balance. In lab 6, the total of all client account limits and
balances used a COMPUTE statement, where the COMP-3 fields contained the
packed decimal internal data.
What happens when an internal packed decimal field is not described using COMP-3?
Without using COMP-3 to describe the field, the COBOL program treats the data
as DISPLAY data (EBCDIC format). This lab demonstrates what happens during
program execution without using COMP-3.
2. Observe that the compile of the COBOL source was successful, however, also
observe that the execution of the job failed. How can you tell?
There's no CC code next to CBL0010J(JOB#), instead there is an
ABENDU4038 message. U4038 is a common user code error typically
involving a mismatch between the external data and the COBOL
representation of the data.
Lab Hints
4. The ACCT-LIMIT PIC clause in the ACCT-FIELDS paragraph should be the
same as the PIC clause for ACCT-BALANCE.
12. Intrinsic functions
Today’s COBOL is not your parents COBOL. Today’s COBOL includes decades
of feature/function rich advancements and performance improvements. Decades
of industry specifications are applied to COBOL to address the growing needs of
businesses. What Enterprise COBOL for z/OS promised and delivered, is
decades of upward compatibility with new releases of hardware and operating
system software. The original DNA of COBOL evolved into a powerful,
maintainable, trusted, and time-tested computer language with no end in sight.
Among the new COBOL capabilities is JSON GENERATE and JSON PARSE,
providing an easy to use coding mechanism to transform DATA DIVISION
defined data-items into JSON for a browser, a smart phone, or any IoT (Internet
of Things) device to format in addition to transforming JSON received from a
browser, a smart phone, or any IoT device into DATA DIVISION defined data-
items for processing. Frequently, the critical data accessed by a smart phone,
such as a bank balance, is stored and controlled by z/OS where a COBOL
program is responsible for retrieving and returning the bank balance to the smart
phone. COBOL has become a web enabled computer language.
Previous COBOL industry specifications included intrinsic functions, which
remain largely relevant today. An experienced COBOL programmer needs to be
familiar with intrinsic functions and stay aware of any new intrinsic functions
introduced. This chapter aims to cover the foundation of intrinsic functions and
their usage in COBOL.
➢ 12.4 Lab 8
12.1 What is an intrinsic function?
Intrinsic functions are effectively re-usable code with simple syntax
implementation and are another powerful COBOL capability. Intrinsic functions
enable desired logic processing with a single line of code. They also provide
capabilities for manipulating strings and numbers. Because the value of an
intrinsic function is derived automatically at the time of reference, you do not
need to define these functions in the DATA DIVISION.
The code shown in Example 1. above, displays the following messages on the
system logical output device:
Hello World!
HELLO WORLD!
hello world!
HELLO WORLD!
LNAME(1:1)
LNAME(4:2)
2. Observe the report output, last name, with first character upper-case and the
remaining characters lower-case.
Figure 1. , below, illustrates the difference in output from lab 6 compared to
this lab. Notice that in the previous lab, the last names were listed in all
capitalized characters, whereas, as previously stated, this lab output has only
the first character of the last name capitalized.
4. Submit CBL0012J
7. Re-submit CBL0012J
8. Corrected CBL0012 source code should compile and execute the program
successfully. A successful compile will result in the same output as
CBL0011J.
Lab Hints
6. Refer to CBL0011 line 120 for the proper formatting of the function-name
causing the compile error.
Part 3 - VSCode alternatives and testing
➢ 13.3 Summary
13.1 Install prerequisites
This section will cover the necessary steps and information to download and
install the prerequisites needed for the installation of IBM Developer for z/OS.
This includes both hardware and software pre-requisites. It is important to verify
your workstation hardware and software meets the prerequisites below before
attempting to install IBM Developer for z/OS (IDz).
2. Check the box, then scroll to the bottom of the page and click Select
4. Click either the Installation Manager install option or the Eclipse p2 install
option
o Note that Installation Manager is preferred as it automates much of the
install process.
1. Select the product by checking the box next to IBM Developer for z/OS in
Install Packages, shown in Figure 1.
2. Click Next
o Installation Manager will download the software components after
resolving references to your operating system and to the Trial Software
Repository.
6. From Select Language - English is the default, but you can change the
language from the displayed product options.
Note: The version numbers in our examples are provided purely for reference and
may not reflect the latest versions of the software.
13.3 Summary
In this chapter we have walked through the process of downloading and installing
IBM's Installation Manage. Which was subsequently used to walk through a
series of dialogs to install IDz.
14. Enabling IBM Developer for Z to work
with COBOL
In this chapter we will explain how to use IDz and its COBOL-specific language-
sensitive-editor as an alternative to other editors mentioned in this book. We will
also cover how using the editor can help you develop COBOL source code in a
feature rich environment.
➢ 14.4 Summary
14.1 Introduction to IDz
This section introduces IDz - IBM's flagship Integrated Development
Environment for both today's production z/OS application work - tomorrow's
DevOps application work - and future work with modern architectures and
component-based systems.
Typical uses for IDz include but are not limited to:
➢ Access to Multiple Virtual Storage (MVS), z/OS Unix, Job Entry Subsystem
(JES) artifacts from an Eclipse based environment
o Eclipse is a modern GUI framework - widely used throughout the software
development world on new and existing enterprise applications.
➢ Issue z/OS commands directly - from within the Eclipse development
environment.
➢ Create new z/OS Datasets, members, Unix files and folders.
➢ Drag and drop files from one z/OS logical partition (LPAR) to another or
from workstation to z/OS and vice versa.
➢ Intelligent and advanced remote edit / save and compile.
https://developer.ibm.com/mainframe/products/downloads
/eclipse-tools/
To see a more detailed instruction on installing the client, visit Chapter 13,
Installing IBM Developer for Z.
➢ Remarks:
o COBOL Remarks are used to document your program's behavior, design,
purpose, etc. In CBL0001, Remarks (which start with an asterisk * in
column 7) are used to separate source lines making the program more
legible.
Figure 6. CBL0001 sample program
You can also reference COBOL keywords by entering the beginning of the
keyword and pressing Ctrl+Spacebar, displayed in Figure 12.
The action of launching a batch job has been described in greater detail previously
in this book. Below is a simple series of steps to illustrate an example of doing
such in IDz:
1. Obtain a "JCL file" that does the compile/link procedure, in our case this is
HELLO.jcl, displayed in Figure 14.
3. Submit the JCL to a z/OS subsystem called JES (Job Entry Subsystem) by
right clicking and selecting Submit from the menu that appears, as shown in
Figure 14.
Figure 14. Submitting a JCL file
4. After submitting the JCL, there will be a prompt to locate the job from a job
submission confirmation pop-up, see Figure 15. Here, you would select
Locate Job.
JCL = Job Control Language - A mainframe computing language that controls the running
of "batch" jobs. A JCL File consists of JCL statements.
JES = Job Entry Subsystem - An area in a mainframe that handles the running of "batch
jobs"
Batch Job - Work done on a mainframe in a non-interactive mode - overnight financial
processing, updates to online databases and systems, etc.
14.4 Summary
In this chapter, you have been able to go through some of the key editing features
of the IDz. These capabilities make editing COBOL, PL/I, JCL, Assembler, SQL
and several other z/OS software languages (Java, JavaScript, HTLM, JSON, etc.)
a little easier.
We've covered, in this chapter, less than 5% of what IDz has to offer for the z/OS
professional. To learn more:
➢ 15.5 Summary
15.1 Introduction to TSO/ISPF
This section introduces TSO/ISPF, IBM's central z/OS tooling, used in nearly
100% of the world's mainframe facilities to do application development and
systems administration.
If you've typed your TSO ID correctly, you will then be prompted for your TSO
password, which you must obtain from your company or from you class
instructor. See Figure 4.
Note: The TSO system messages may contain important information, such as the
disposition of a submitted job.
Note that the primary menu in Figure 6 shows 14 options - numbered 0 ➔ 11, SD
and U. There are also some PF Key assignments at the bottom of the screen.
These PF Key assignments are consistent throughout the product and are defined
as:
➢ F1 ➔ Help on the current screen (many ISPF professionals refer to these
screens as "dialogs")
➢ F2 ➔ Split the screen horizontally. This allows you to work in two different
areas simultaneously.
➢ F3 ➔ Exit or return from the prior tool menu.
➢ F7 ➔ Page backward
➢ F8 ➔ Page forward
➢ F9 ➔ Swap your cursor focus between split screens.
➢ F10 ➔ Actions bounces your cursor up to the Options at the top of the
screen.
➢ F12 ➔ Cancel returns you to the previous z/OS application. In this case, F12
logs you out of ISPF and puts you in "Native TSO mode", which is similar to
command line Unix and where you can enter commands to z/OS (the
mainframe OS), but you cannot use ISPF to do development work.
➢ SD ➔ SDSF (Systems Display and Search Facility) to view the status of
batch "jobs".
➢ U ➔ Unix access to the Unix subsystem running on z/OS.
Every shop will have some small variation on the ISPF primary menu, but for
now let's type the number two on the Option line and press Enter, as shown in
Figure 7.
If your cursor focus is not on the option line and you type, you will "freeze" the
screen. To get out of this situation:
➢ Click the tiny square at the bottom left corner of your 3270 screen.
➢ And press the Attn key, this will reset the screen for input allowing you to
continue, shown in Figure 8.
Figure 8. IDz 3270 control keys
There are numerous ways to specify a file to edit, but for now we're going to:
1. List all the program files in a library.
2. Select the program to edit from a list.
From Figure 9. :
➢ Type CBL on the Name . . . entry area
➢ Press Enter
This will bring up the PDS member selection screen (Figure 10. ). Note that you
did not have to enter: <TSOID>.CBL. This is because ISPF knows your TSO
logon and automatically prefixes it before file names on the dialog input lines, if
the file name isn't surrounded by apostrophes.
On the selection screen, hit the tab key three times and type an S next to
CBL0001, then press Enter. This will open CBL0001 with the ISPF screen
where we can edit the source, shown in Figure 12.
Figure 9. Edit (option 2) dialog (entry panel) - where you select a file to edit
Figure 10. The PDS member selection screen - where you select (S) the file you want to edit
When the file initially opens you will probably get some warning text, which can
be removed by typing res on the command line and pressing Enter, shown in
Figure 11.
Note that there are dozens of ISPF productivity techniques, but in this chapter, we
explore only a subset of them.
JCL = Job Control Language - A mainframe computing language that controls the running of
"batch" jobs. A JCL file consists of JCL statements.
JES = Job Entry Subsystem - An area in a mainframe that handles the running of "batch jobs".
Batch Job - Work done on a mainframe in a non-interactive mode - overnight financial
processing, updates to online databases and systems, etc.
15.5 Summary
In this chapter we have walked through some of the editing features using
TSO/ISPF and the ISPF editor. These capabilities ease editing COBOL, PL/I,
JCL, Assembler, SQL and several other z/OS software languages (REXX, CLIST,
etc.).
We've covered in this chapter less than 5% of what ISPF offers for the z/OS
professional. To learn more, there are several quality books on the subject and
videos available on YouTube.
➢ A link to an excellent instructional video on ISPF:
https://www.youtube.com/watch?v=vOiHiI7b9iY
16. Testing
In this chapter, we focus on the importance of thoroughly testing software to
ensure its quality. No language or program is exempt from the importance of
testing and automated testing, including programs written in COBOL. The
chapter explains how this can only be achieved in an effective and efficient way
by automating the testing as part of a continuous delivery pipeline and introduces
a framework that can enable such automation.
We will look at some of the background to software testing and the different types
of testing, the value to an enterprise of using a continuous integration/continuous
delivery pipeline, why automation is vital in CI/CD pipelines, and the risks of not
adopting automation.
There are several alarming examples of software defects and problems that could
have been avoided by applying the proper and sufficient testing.
Unit testing is important because the earlier defects can be found (or avoided), the
less resource is required to resolve them. A problem found early might be
corrected by simple editing in minutes, whereas the same problem found later
might require a lot of rewriting and re-testing. Unit testing also often takes
advantage of the developer's knowledge of the internals of the unit or units being
tested.
The unit tests that are created as part of unit testing can also be very important, if
they are designed in such a way that they can be run and re-run later in the
development cycle, to validate that the behavior of the software units is still
correct.
16.1.3 What is function/integration/system testing?
Beyond the realm of unit testing, which is carried out by the developer, are a
range of types of testing that typically fall into the realm of the tester. These
validate that when individual units of code are integrated together, or introduced
into an existing software system, the overall system both continues to work
correctly without any regressions and displays the new functionality that the new
code is intended to enable. There are a multitude of terms used to define these
different types of testing, and in most organizations, there will be a sequence of
test phases through which code will pass, each with their own names.
A useful approach to categorizing types of testing are the Agile Test Quadrants,
introduced by Brian Marick (http://www.exampler.com/old-
blog/2003/08/21.1.html#agile-testing-project-1). This looks
at tests in terms of distinguishing whether they are business facing or technology
facing, as well as whether they are used by or on behalf of programmers to
support programming or are intended to critique the product. This results in four
quadrants (see Figure 1):
Martin Fowler and Mike Kohn have discussed the concept of a Test Pyramid (see
’The Practical Test Pyramid’:
https://martinfowler.com/articles/practical-test-
pyramid.html), which emphasizes the importance of a wide base of many
small unit tests, then built upon that a set of equally important but less numerous
tests that Mike Cohn called 'Service Tests'. At the top of the pyramid are 'End to
End tests', which include user interface tests, and which test the entire system
from end to end. Service tests covers a similar scope of testing as Integration
Testing but is a term which has not gained much traction, and in our usage
Integration Testing covers all the pyramid above the unit tests.
This chapter is not going to attempt to provide definitive definitions of the various
types of testing but will use 'Integration Testing' as an umbrella term to cover
much of the testing that occurs after development and which lends itself to
automation. This is where individual units of software are tested together, as well
as being tested with other components including external parts of the system.
Such tests are usually run in an environment that matches some aspects of the
ultimate target environment for the software. Included within 'Integration Testing'
are regression testing, functional testing, system testing, U.I. testing, end-to-end
testing, user acceptance testing, performance testing.
A distinction should be made between types of testing and types of tests. Unit
tests for example can, and should, be run during later test phases, especially as
part of regression testing.
16.1.4 The role of exploratory testing
Exploratory testing was defined by Cem Kaner in 1984 (see
http://www.kaner.com/pdfs/QAIExploring.pdf) as, "a style of
software testing that emphasizes the personal freedom and responsibility of the
individual tester to continually optimize the quality of their work by treating test-
related learning, test design, test execution, and test result interpretation as
mutually supportive activities that run in parallel throughout the project."
Exploratory testing allows a tester to use their skills and experience to discover,
investigate and learn about the behavior of the software under test. In the spirit of
the Agile Manifesto, it emphasizes the "personal freedom and responsibility of
the individual tester" (https://www.guru99.com/exploratory-
testing.html).
In terms of the Agile Testing Quadrants, exploratory testing lies towards the side
that aims to 'critique the product', which is covered nicely in this post:
https://www.testingexcellence.com/exploratory-testing-
important-agile-projects/.
This type of testing makes the best use of the skills of the tester, but clearly by its
very nature does not lend itself to automation. The value of automation of testing
lies in freeing the tester from the need to manually carry out repetitive and un-
thinking testing.
Continuous Delivery (CD) progresses the code changes further around the
pipeline process, by automating the delivery of the changed software to a series of
environments for testing, and ultimately production. Some people distinguish
between Continuous Delivery, which ensures working and tested releases of
software are ready at any time, to production, but requires a manual decision
process prior to that final deployment, and continuous deployment which also
automates the releasing into production.
All of this requires Continuous Testing to ensure that quality software is being
made available at each stage, and ultimately delivered to production. To take this
further, there is also value in continuous monitoring of the software in production,
continuous feedback from stakeholders and users, and ultimately 'Continuous
Everything'.
In Figure 2, after planning for the next release, based on user input, and
potentially analyzing the code to understand where to introduce the changes, the
coding phase begins. The developer will write, build and unit test the code,
gradually adding in function and ensuring that it works as an individual unit as
intended, using their preferred IDE and preferred tools for source code
management, dependency resolution, etc. When the code is ready, it will be
delivered into the pipeline, which uses an artifact repository to manage the
process. The software now enters the testing phases, where the test environments
are provisioned (or might already exist), the code changes are deployed into the
environment to be tested, and tests are run. The tests might, themselves, drive the
provisioning and deployment, or this might be done separately. This phase of the
pipeline is an iterative process, moving through different levels of testing, often in
different environments. When failures occur, they need to be efficiently
diagnosed, and if needed, the code will be amended, rebuilt, and unit tested again.
Feedback from users will be sought during this phase, to ensure that what is being
delivered meets their needs. When the code change has successfully passed all
the required phases of testing, it will be released to production. The software
changes and the production environment will continue to be monitored and
planning for the next release can begin. Figure 2 illustrates some of the tools and
products that might be used to implement the various stages of the pipeline.
Some of these building blocks are probably in place at many enterprises, but it is
likely that most of the activities are carried out in a manual way and it is the lack
of automation of those steps that slows delivery.
This testing also needs to be carried out continuously, as each change is delivered.
'Continuous testing' has been described as being a process of "testing early,
testing often, testing everywhere, and automate"
(https://www.guru99.com/continuous-testing.html).
A key principle of the move to DevOps and a CI/CD pipeline is that as much of
the testing as possible needs to be automated. Also, it is not just the tests
themselves that need to be automated, but also the checking of whether the tests
have passed.
However, not all testing can or should be automated. Exploratory testing might
well follow different paths as a result of what is discovered during the process.
Penetration testing often relies on innovation and trying something new, which is
difficult to automate. User acceptance testing will often involve users interacting
with the system in a flexible way.
When we speak of testing in this chapter from this point on, we are referring to
what would more strictly be called checking, rather than testing.
The key point is that anything that lends itself to automation should be automated,
to allow time for these other activities where automation is genuinely not
appropriate. The fact that something is quite difficult to automate should not be
used as an excuse for failing to automate it.
The diagnostics that will reveal the cause of the failure should be collected in a
known location and made available in an easy way to the engineer who will
investigate the problem. The software change that caused the failure should be
easily identifiable, and its progress through the pipeline should be halted, or
reversed. Other software changes that have not caused the failure should be able
to continue unimpeded, unless they are only viable with the failing change, which
should also be something the pipeline can detect and act upon. Finally, it is
possible that the failure could be due to a problem with the test or the test
environment, and those possibilities must also be easy to detect and investigate.
This means that the estimates for any project that makes changes to an application
on z/OS, or for a new application, include a very large portion of effort allocated
to testing.
Surveys and user research carried out by the IBM CICS Transaction Server for
z/OS organization have shown that between 92 and 95% of testing on the
platform is entirely or mostly manual, which is in line with industry estimates that
place the percentage of manual testing at around 80% ("Even today, 80 percent of
enterprise testing is done manually." – Sandeep Johri, Tricentis CEO). The
manual testing can vary in nature from a test suite that just needs to be set up and
run manually, to typing in a sequence of steps that are described in a hardcopy
book of test cases.
Why is test automation such a challenge on z/OS? Some of the reasons are:
➢ Very large systems have been built up over the years; large both in terms of
the number and size of components making up each application, and in terms
of the environment in which the applications run. Finding a way to drive
these large systems as part of an automated test has proved challenging.
➢ There is a lack of test automation tools that understand the z/OS operating
system, its subsystems and file stores, to make it practical to adopt these tools.
➢ The data is tightly integrated with the applications which use it and is often
used by multiple applications. Providing suitable test data, which can be
isolated for use by each test run, and reset to known values, has been very
challenging.
➢ Many applications rely on components which were developed many years
ago, which means that testing needs to ensure these components will still run
without issues or regressions. As Rosalind Radcliffe put it, "The best thing
about the mainframe is a module compiled 40 years ago will still run. The
worst thing about the mainframe is a module compiled 40 years ago will still
run." [https://www.sonatype.com/an-innovators-journey-rosalind-radcliffe]
The difficulty in achieving this has resulted in falling back to manual processes
and checks, and as a result continuing to use waterfall processes. To quote
Sandeep Johri again, "If you move to Agile development but your testing cycle is
still 6 to 12 weeks due to manual testing, you’ll fall right back into a Waterfall
mode” (https://devops.com/devops-chat-continuous-
testing-w-sandeep-johri-ceo-tricentis/). If the testing cycle
takes a long time, then developers will be tempted to group together lots of
changes to get them tested all together, which is entirely counter to the idea of
continuous integration.
Even more damaging could be the impact of being unable to deliver function
rapidly into the marketplace, and missing opportunities as a result.