Introduction to Jazz

This initial chapter of the Jazz Users’ Guide provides an introduction to the basic concepts of Jazz, and shows you how to create a simple Jazz program that will read data from an input file and print it on a report. You may like to start by viewing this 5-minute introductory video.


Introduction to Jazz. 1

What is Jazz?. 1

Installing and Configuring the Jazz Workbench. 3

Writing your first Jazz program.. 3

Comments. 3

Statements. 4

The PROGRAM Statement 4

Data Definitions. 4

External definitions: the COPY statement 5

General form of DEFINE statements. 5

Definition Name. 6

Definition Type. 6

Field definitions. 6

Imperative Statements – Doing Something. 7

The PROCESS Statement 7

The GET statement 8

The PRINT Statement 8

Conclusion. 10

What is Jazz?

MANASYS-Jazz is a revolutionary programming system for Mainframe (IBM z/OS) (and later Midrange and Windows) computers that makes the programming of simple tasks vastly simpler than it would be with COBOL or similar tools, without making complex tasks more complex. Jazz itself operates in the Windows environment, with objects like COBOL programs, BMS maps, Database definitions, Web Service Descriptions (WSDL) etc being passed to/from the target environment.  Jazz will also interact with other development tools like Eclipse and VS (Microsoft’s Visual Studio) to create and coordinate web services, allowing you to build systems in which functions are distributed across the web and across a range of technologies.


For example, here is a simple report program written with the Jazz Workbench: -



Click [Process] and Jazz will generate the equivalent 553 line COBOL program, submit it to z/OS where it will be compiled and run, and the results (including the report) returned back to the workbench.


The Jazz Workbench

Jazz is written using the Jazz Workbench, a Windows™ program that interprets your program.  If you open a Jazz program with a basic editor like Notepad you’ll see something like this: -

*# Last Updated by robertb at 30/11/2013 10:24:19 a.m.




PROCESS IN1 WHERE (IN1.Region > 5) ORDER(IN1.Region, IN1.District, IN1.Name);

GET FR WHERE (FR.Region = IN1.Region);

PRINT(IN1.Region, Fr.Name, IN1.SalesThisMonth SUM, IN1.SalesYTD SUM)

BREAK(IN1.Region, IN1.District);



When you open it with the Jazz Workbench you see this:-

*# Last Updated by IBMUSER at 7/12/2015 5:15:40 p.m.




PROCESS IN1 WHERE (IN1.Region > 5) ORDER(IN1.Region, IN1.District, IN1.Name)  INDEX;

    #082 W Default name 'JZ-INDEX' used for INDEX option

    GET FR WHERE (FR.Region = in1.region) ;

    PRINT (JZ.JZ-INDEX, in1.region, FR.Name, in1.district, IN1.Name, in1.district, IN1.BillingCycle,

        IN1.SalesThisMonth SUM,IN1.SalesYTD SUM)

        BREAK(in1.region, in1.district);


Keywords and fields have been identified by colour, and the code has been indented to show its logical structure.  Also, when your program is checked Jazz will produce information, warning, error, and severe error messages when various situations are found: -

IN1.SalesThisMonth = IN1.Name + 5;

#168 E Operator invalid for preceding item

#031 E "+" is invalid here

When you write unqualified references like “SalesThisMonth” and “Name” Jazz will find the fields and qualify the references for you, providing visual confirmation that the field exists and a helpful hint enabling you to check that you have the field that you want.  “?” can be used to get selection lists: for example PRINT(IN1.?) produces a list of the fields defined in record IN1: -

Installing and Configuring the Jazz Workbench

To install the Jazz Workbench you need only visit the JazzSoftware web site,, register, and obtain a trial or full licence. You then install the workbench by clicking the [Run Jazz] button on the web page. This downloads and starts the workbench as a Microsoft ClickOnce program: it runs in its own environment and cannot interfere with your other Windows programs.


Once installed, for first use you’ll need to configure the workbench with your own preferences, such as the names of folders in your Windows system that will contain your Jazz programs, the names of the libraries in the z/OS environment that will hold your COBOL source, your JCL, and so on. Just click the workbench’s [Configure] button and follow the dialogs.  Initial set-up and configuration is described in more detail here.

Writing your first Jazz program

You can write batch programs to produce reports and update records in VSAM or SQL databases. You can write classical (3270-type) CICS transactions: simple and complex enquiries, and update programs.  You can write mainframe programs that invoke web services, and you can write web services that can be invoked from Web or Windows programs through the internet. You can define data, 3270-type screen layouts, and you can import existing COBOL record definitions and SQL table definitions into Jazz.  All these activities follow basic Jazz principles, so let’s start by looking at the program above to see the structure and rules of all Jazz programs.


You’ll see that the program starts with a comment: -

*# Last Updated by robertb at 25/07/2013 6:12:24 p.m.

This comment is automatically inserted by Jazz, but we can write our own comments anywhere we like. Jazz will colour all comments green[1].  Any line starting with “*” is a comment. Also we can write a comment on a normal line anywhere where a blank would be valid by enclosing the comment text in [ and ], or [ to the end of a line. Thus all the green text here is comment: -

*# Last Updated by robertb at 25/07/2013 6:12:24 p.m.

PROGRAM AAnExmpl BATCH;  [Our first example program

DEFINE IN1 [main input file] TYPE(VB) DATA(           


Comments that start with *# are automatic comments. Don’t start your own comments with “*#”: if you do you might find Jazz attempting to replace or edit them. Apart from that, you can write whatever you like in a comment.

Getting Started: the [New] Dialog

When we click [New] or take the New option from the File menu the Jazz workbench responds with a dialog like this: -

Click [+] to expand the nodes until we find the one we want, then click this. This time we’ll select “New Batch Program”, and the dialog will ask us for the program name and create the PROGRAM statement for us.

Writing Jazz

We show Jazz programs and data definitions here in colour, indented, and with statement keywords highlighted. This formatting is inserted by the Jazz workbench. For example, here we are starting to write a Jazz record definition: -


When we click [Check] Jazz formats it for us: -


If we make mistakes Jazz will produce error messages: -


Very often one error will lead to many error messages, and sometimes an “error cascade” where Jazz can’t interpret the following statements correctly. If you get errors, correct them from the top, and don’t worry about the errors that you don’t understand: they may well disappear.  By the way, help is only a right-click away:-

Getting Help

You can get help by right-clicking part of the workbench: -

·         Right-click on any statement except COPY and the relevant page of the language reference manual will open. For example, with the cursor positioned on the PROCESS statement a right-click produces this.

·         Right-click with the cursor positioned on an error message and an explanation of the error is given: -

·         Right-click on a COPY statement and another workbench opens, displaying the imported definition and allowing you to edit it.  For example, clicking on
      COPY In1;
displays: -


Just in case you want to see the definition of a COPY statement these 2nd-level workbench sessions have a button [Show COPY Help].  Click [Exit] to return to the parent session.  If the COPY code includes further COPY statements then you may open further levels of workbench session.

·         In many situations you can write a question mark, and the workbench will respond with a data list from which you can select the fields that you want. For example, writing
      PRINT ?;
here: -


causes this window to be displayed when you click [Check]: -


You can expand the nodes for the records IN1 or FR and click on the fields that you want to print.  As you select them they are added to the data list: when you are through, click [Finish] to return to the program.


Ignoring comments, you can see that the program contains several statements. Almost every statement starts with a keyword like PROGRAM, DEFINE, PROCESS, etc., and ends with a semicolon.  Jazz has coloured the statement keyword blue and used BOLD type. Other keywords are also blue, but are not bold. A statement may extend over several lines. For example, the DEFINE statement starts with

DEFINE IN1 VB DATA(           

and finishes several lines later with

        DateCommenced CHAR(10));


Jazz indents the text to emphasise the logical relationship of various lines.


There is one kind of statement that does not start with a keyword, the assignment statement, which assigns (moves or computes) one value to another. It simply starts with a field (or record or group) name: -

    R1.B = R1.C;

There are no assignment statements in the program above.


Just as Jazz coloured keywords blue, references to fields are coloured turquoise.

The PROGRAM Statement

The first statement above is: -


The point of this is to:

1.                  Tell Jazz that this is a program. Alternative first statements might be SUBPROGRAM, or DEFINE, creating different kinds of objects

2.                  Give the program a name: AAnExmpl in this case

3.                  Tell Jazz what kind of program this is. Currently the types available are BATCH, CICS, or WEBSERVICE.


The program name follows the rules of Jazz External Names, which are names that are known by the operating system as well as within your program.  These rules are: -

1.                  It cannot be longer than 8 characters

2.                  It must start with a letter, and contain only letters and numbers

3.                  If may not contain a hyphen

4.                  It must not be a COBOL reserved word

5.                  If must also follow the general rules for Jazz Names, which means that it may not start with “JZ” or “$”.


Click here for a full description of the PROGRAM statement.

Data Definitions

Data definitions are a very important part of Jazz, so we’ll spend some time looking at the DEFINE statements in the example program.  Our COPY statements brought in these definitions: -

DEFINE IN1 VB DATA(           

        Region DECIMAL(3),           

        District DECIMAL(3),         

        Name CHAR(15),               

        SalesThisMonth MONEY(7,2),   

        SalesYTD MONEY(7,2),         

        Cardholder CHAR(1),          

        DateCommenced CHAR(10));


        Region PIC '999' KEY,

        Name CHAR(30) Value('No Record found') HEADING 'Region Name',

        Fill CHAR(47));

External definitions: the COPY statement

DEFINE statements supply Jazz with the information it needs about the data used in a program. Obviously if one program creates a record and another uses it the two programs must use the same description; if the first program has NAME defined as 30 characters long, and the second defines it as 20 characters the two programs will have trouble sharing the file. It therefore makes good sense to write definitions separately, then use COPY to include this definition in each programs.  The advantages are obvious: you only write this once and EVERY program using it has the same definition and so will be consistent.


COPY is obviously very similar to COBOL’s COPY statement, although there are some differences making it more flexible.  The most important of these: COPY xxx; is harmlessly discarded if there is a preceding COPY xxx; in the program.  This makes it easy to write definitions that depend on other definitions like this: -

COPY CustRec;

COPY Order;


    LastCustID LIKE Custrec.Custid,

    LastOrder LIKE Order.*);


Now it doesn’t matter if the program already includes COPY CustRec or COPY Order: the second COPY statement is simply ignored.  Click here to see more about the COPY statement.

Converting COBOL Definitions to Jazz.

Often we will be writing Jazz programs using files that have already been defined for pre-existing COBOL programs. A very quick way of creating the Jazz definitions that we want is to convert these to Jazz, and then add the extra Jazz features like validation rules, file type, and DSName: -

1.            Select the option “Import from COBOL”.  Jazz will access the mainframe copy library that you defined when you configured Jazz, and show you a list of members in it.

2.            Select the definition that you want to download.  Here I’ve selected PROGINFO.  This is downloaded as PROGINFO.CBL, and the [Convert] button becomes active: -

3.            Click the [Convert] button and this is converted to Jazz as Proginfo.jzc, and the downloaded PROGINFO.CBL is deleted unless we unchecked the option “Delete Downloaded COBOL”  This does not affect the mainframe library of course.  Now we see the converted definition: -

There may be messages produced (as here) if Jazz detects errors.  The conversion expects to be given a data definition starting with an 01 name, but there may be several records, and in fact this could be a complete COBOL program.  Any statements other than data-division statements starting with a level number will be ignored.

4.            You can now edit the Jazz definition to add validation and display options like HEADING and CODES, define the file type, and add a DSNAME option.

General form of DEFINE statements

DEFINE statements have this general form: -

DEFINE name type DATA(




        last field);

Each field is

        FieldName  Format [Other attributes]

Definition Name

Here we have defined two records, IN1 and FR. Definition names must be unique, so that it would have been an error if either of these definitions had the same name as the program, or if the second were also called “IN1”.  Definitions with TYPE(VB) or TYPE(VSAM) are also external names,like the program name AAnExmpl, so must follow the rules above.


If there is no TYPE option, or if it has another TYPE, then the definition name follows the general Jazz name rules: -

1.                  The name may be up to 25 characters long

2.                  It must start with a letter

3.                  It may not start with “JZ” or “$”

4.                  It may contain letters, numbers, and hyphens

5.                  The last character of the name may not be a hyphen


Note that these rules DO NOT say that you may not use Jazz keywords, or COBOL reserved words, although it is recommended that you avoid them if you can.


By the way, don’t bother learning these rules. Jazz will tell you when you break them.

Definition Type

IN1 has been defined with type VB. This means that it is “Variable Blocked”, which is one of 5 types of “Physical Sequential” files. Others are F, FB, V, and U, meaning Fixed, Fixed Blocked, Variable, and Undefined. A Physical Sequential file can only be read in sequence (front to back), you cannot use direct access to read a record with a particular key value. In Jazz you can only use these files with a PROCESS statement in BATCH programs.


FR has type VSAM (Virtual Storage Access Method), which is an organization that allows us to read the records both sequentially and by key. Just as with a Physical Sequential file we could use a PROCESS statement to read some or all of the records sequentially, but we can also use GET statements to read particular records. VSAM files can be used in both BATCH and CICS programs.


If there is no type then WORK is assumed. This means that the record defines some working data in our program which is not read from or written to files. Since all data in Jazz must be defined within a record, many programs will contain a DEFINE statement like


        field , …

defining a record WD containing some of the program’s working data.


There are also other definition types, which we will meet as we need them. Click here for a full description of the TYPE option.

Field definitions

Fields in IN1 are: -

        Region DECIMAL(3),           

        District DECIMAL(3),         

        Name CHAR(15),               

        SalesThisMonth MONEY(7,2),   

        SalesYTD MONEY(7,2),         

        Cardholder CHAR(1),          

        DateCommenced CHAR(10)


Each field definition gives the field name, which follows the general Jazz name rules,  and then give the field format – DECIMAL(3),  CHAR(15), MONEY(7,2), and so on.


DECIMAL and MONEY are called “Packed” or “COMP-3” in COBOL, Fixed Decimal in PL/I, and are a format that is designed to hold decimal numbers. Thus DECIMAL(3) holds values from +999 to -999, while MONEY(7,2) holds values from +99999.99 to -99999.99. The only difference between DECIMAL and MONEY is that MONEY will display with currency symbols on screens and reports.  DECIMAL and MONEY are numeric formats so you can calculate with them.  Other numeric formats are the integer formats TINYINT, SMALLINT, INTEGER, and BIGINT, floating point formats FLOAT and LONG, and PIC which is numeric data held in character format. You can assign data from one numeric format to another.


CHAR fields hold character string values, and are equivalent to PIC X(length) in COBOL. Jazz also provides VARCHAR format. You can assign between CHAR and VARCHAR fields, but not to/from numeric variables


Fields defined in FR are: -

        Region PIC '999' KEY,

        Name CHAR(30) Value('No Record found') HEADING 'Region Name',

        Fill CHAR(47)


Region and Name show examples of optional field properties:  Region is described with KEY, while Name is given a default VALUE and a HEADING. As mentioned above, it is always better to give this sort of information in DEFINE statements, rather than coding it into the logic of particular programs. By putting it in a definition which you COPY you ensure consistency, but you create no overhead as the details are ignored when they are irrelevant.

Defining your own data types

A powerful way of using flexibility of COPY and DEFINE statements is to define your own data types for fields that are used in standard ways within your application.  Start by writing DEFINE xxx TYPE(SYSTEM) DATA(


Then define your special data types: -


    State CHAR(2) CODES (AL:Alabama,AK:Alaska,AR:Arkansa,AZ:Arizona ...),

    PhoneNbr GROUP,

        AreaCode DECIMAL (3),

        Number DECIMAL (7),

        END GROUP,

    Customer GROUP,

        Title CHAR(5) VALIDVALUES ('Mr', 'Mrs', 'Ms', 'Miss', 'Dr' ...),

        GivenName CHAR(20),

        FamilyName CHAR(20),

        Gender CODES(Male, Female),

        Address1 CHAR(30),

        Address2 CHAR(30),

        CustState LIKE mytypes.State,

        CustPhoneNbr LIKE mytypes.PhoneNbr,

        END GROUP);    


Now records can be defined like this: -

COPY MyTypes;


    Custid INTEGER KEY,

    Customer like MyTypes.Customer,

    CurrentSales MONEY(7,2),



Duplicate COPY Mytypes; cause no problem, and DEFINE MyTypes; creates no overhead as it is only used to define other fields.  So, without any overhead, we’ve ensured consistency, made our programs more robust, and made them easier to change.


Note the strong principle in Jazz: give as much information as possible in the data definition, as this reduces what you need to write in individual programs.  Putting this information into the definition has many advantages.  CODES fields in particular are efficient and precise: -

·         In appropriate circumstances such as accepting data from an input screen Jazz will validate the input value, and produce error messages if its value is invalid,

·         If we display it, either on a screen or printed in a report, it will be displayed as “Enquiry” etc,

·         Within our Jazz programs we refer to the interpreted value, not the code. Thus we write
      IF Function = Enquiry


      IF Function = 'E' … .

·         Jazz will not allow us to assign a value to Function that could be invalid.


·         However there is no overhead from this: for example although you wrote
      IF Function = Enquiry

in the generated program this tests the code value, 'E', directly.

·         A field like Gender, defined with CODES but no format code, is carried as a one-byte hexadecimal character.

            Gender CODES(Male, Female),
      Value x’01’ means “Male” and x’02’ means “Female”.


Note also the use of LIKE to define SaveArea. Here we wanted a program area to save a value of the Order record. By using LIKE we not only save work but we avoid future errors because Jazz now ensures that Savearea and the Order record are defined the same way. Should we change the definition of Order, for example adding another field then when we regenerate the program containing SaveArea  its definition will automatically change to match the new format of Order.


Another example: FR.Name has HEADING 'Region Name' which only applies if you PRINT FR.Name, or drag the field on to a screen. By making this part of the definition you again guarantee consistency at no cost. You’ll see more examples later.


Click here for a full description of field definitions and the Data option.

Imperative Statements – Doing Something

So far with PROGRAM and DEFINE we’ve set the scene, but we haven’t actually given any orders to do anything. But now comes the last five lines of our program, starting with the first of our imperative statements, PROCESS: -


PROCESS IN1 WHERE (IN1.Region > 5) ORDER(IN1.Region, IN1.District, IN1.Name);

    GET FR WHERE (FR.Region = IN1.Region);

    PRINT(IN1.Region, Fr.Name, IN1.SalesThisMonth SUM, IN1.SalesYTD SUM)

            BREAK(IN1.Region, IN1.District);


The PROCESS Statement

PROCESS statements form the heart of BATCH programs. There may be a little bit of logic that is done at the beginning before you start, and there may be a little bit of logic at the end, but most of the program logic is between PROCESS file …; and the corresponding END PROCESS file;


PROCESS statements create an I/O loop.  Thus




reads each record in turn from file IN1.  If the record meets the WHERE criteria, then the record is passed to the statements between PROCESS and END PROCESS for further action. Here IN1 is defined with type VB. It could have been defined, like FR, with VSAM, or if it had been a table in a DB2 database it would have been defined as SQL. The PROCESS statement is basically the same whatever the data organization, although with SQL there are some additional options.


In this case the statement includes the WHERE option

PROCESS IN1 WHERE (IN1.Region > 5)

As each record is read it is tested to see if IN1.Region is greater than 5. If not, the record is discarded and the next one read.  When all records have been read then the statements after END PROCESS IN1 would be executed, if there were any. We could, for example, write



PRINT('End of Report');

to have this print after all the selected records have been printed. However since Jazz does this for us anyway there’s little point in having it printed twice.


File IN1 was defined with VB so the records are in no particular order. If we want to produce a report with subtotals then we need to ensure that the file is in the correct sequence, so we add an ORDER option to our PROCESS statement: -

PROCESS IN1 WHERE (IN1.Region > 5) ORDER(IN1.Region, IN1.District, IN1.Name);


This ensures that we process all the records for IN1.Region = 1 before IN1.Region = 2, and so on. Within one Region, District will be in ascending order, and within one Region and District, Name will be in ascending order.  Even when we believe that the records are already in the correct order we should ensure that this is so with an ORDER option.


If we want to count the returned records we can add an INDEX option to the PROCSS statement.

The GET statement

The next statement is: -

GET FR WHERE (FR.Region = IN1.Region);


GET reads a particular record. The file must have an organization type that supports direct access: it must have type VSAM or SQL.


What if the record you want can’t be found?  For example one of the input records in my test file has value IN1.Region = 9, but there is no record in FR with  FR.Region = 9.  Jazz creates a dummy record for you in memory: it will have value FR.Region = 9, other fields in FR will be blank or zero unless they have a VALUE clause in their definition. Because Name was defined

        Name CHAR(30) Value('No Record found')…

then its value will be set to 'No Record found' if Jazz has to create a dummy record.


With default values like this there is usually no need to test for absent records, but if necessary you can test $Found with logic like this: -

IF FR.$Found = False THEN



Click here for more information about GET, and here for more information about IF.

The PRINT Statement

We’re now at the point in the program where we’re processing a wanted record from IN1, having ensured that we’re reading the records in ascending order of Region, District, and Name, and we have matched this with a corresponding record from FR so that we have a region name in field Fr.Name.  Now we have this PRINT statement: -

    PRINT(IN1.Region, Fr.Name, IN1.SalesThisMonth SUM, IN1.SalesYTD SUM)

            BREAK(IN1.Region, IN1.District);


The PRINT statement starts by giving a list of fields, with SUM added to the fields that we want totalled. BREAK(IN1.Region, IN1.District) specifies the control breaks to trigger subtotal printing. BREAK must name all or a left subset of the fields of the ORDER option of the PROCESS Statement. For more about PRINT statements, click here.


Our program is completed with the END PROCESS IN1; statement.

Generating and Testing our Program

Here is our completed program: -


Clicking the [Process] button causes the Jazz workbench to check our program, generate COBOL, generate JCL to compile the program, and submit the program.  As the workbench waits for the results various messages appear at the bottom showing the progress of the job: when it is finished the button [Job Results] is highlighted and it can be clicked to display the job output.


Here is the COBOL program generated from this brief Jazz program, and here is [part of] the report that this produces: -


Printed at 24 Apr 2016, 20:01:18                                    Report1                                    Page   1            


JZ-INDEX Region *--------Region Name---------* District *----Name-----* District BillingCycle SalesThisMonth *SalesYTD*            


       1      6 France                                1 CustomerName168        1    February          516.95   4,157.15            

       2      6 France                                1 CustomerName19         1    May               926.25   1,035.45             

       3      6 France                                1 CustomerName78         1    August            559.74   5,144.27            

District Subtotals                                                                                  2,002.94  10,336.87            


       4      6 France                                2 CustomerName198        2    *********         279.54   5,009.66            

       5      6 France                                2 CustomerName213        2    July              709.14   6,298.00            

       6      6 France                                2 CustomerName84         2    *********         596.41   4,295.36            


Several lines removed


      29      6 France                                9 CustomerName159        9    August            682.09   1,052.56            

      30      6 France                                9 CustomerName197        9    *********         280.00   4,510.51            

      31      6 France                                9 CustomerName208        9    *********         664.82   5,174.51            

      32      6 France                                9 CustomerName42         9    May                93.42     942.60            

      33      6 France                                9 CustomerName80         9    *********           8.26     985.95            

District Subtotals                                                                                  1,728.59  12,666.13            


      34      6 France                               10 CustomerName88        10    June              194.34     390.98            

District Subtotals                                                                                    194.34     390.98            

Region Subtotals                                                                                   16,003.34  20,161.57    


Here we’ve introduced the key concepts of Jazz.

·         Jazz is a programming tool that operates in the Windows™ environment, creating programs and other objects for other environments, particular zOS™.

·         The Jazz workbench analyses the program that you write, reporting errors, colouring it and indenting it to emphasis the way the syntax has been interpreted.

·         An objective is to describe the business problem to solve as simply as possible, without the need to state implementation details that are implied by the problem statement. Jazz gets closer to this ideal than other programming systems.

·         Jazz data definitions provide a powerful tool to reduce redundancy, increase consistency, and increase productivity. An objective is “Say it once”, so a definition may give information like validation criteria and display formats that may be ignored in one program (and hence cause no overhead) but are vital in another. In the next chapter of this users’ guide you’ll see that they are used to define interfaces with subprograms, and later you’ll see their use to define interfaces with web services. You can define one field, group, or record LIKE another, again ensuring consistency.

·         Jazz functions by creating COBOL, but users don’t normally need to work with the COBOL any more than COBOL programmers need to work with the Assembler Language that their COBOL program may provide. 


Now return to the Jazz Users Guide Table of Contents to learn more about Jazz.




[1] Actually you can set these colours to whatever you like.