Friday, July 29, 2011

Fin

To my few and loyal readers,

I will no longer be updating this blog. I have enjoyed writing and learning all about mainframes, but both the universe and IBM decided it was time for me to move onto bigger and better things. I, like many other IBMers, have been 'resource action-ed' (ie, laid off). Rather than get another job in the industry and thus expose myself to future resource actions, I have decided to go back to school and get my phd, with a focus on the social and ethical implications of the creation of artificial intelligence.

I truly hope this blog saves you some of the pain and trouble I experienced when learning about z/OS, and please feel free to post or contact me if you have questions about z.

cheers

David

Wednesday, April 27, 2011

HOW TO GET A WORKSTATION APPLICATION TO INTERFACE WITH Z/OS

I hope this post saves you some aggravation. If you are creating an application and need to interface with z/OS via TCP/IP, there IS an API for that. The book you want is called "IP Sockets Application Programming Interface Guide and Reference" and can be found here. Note - depending on the age of this post, you may want to find a more recent version of the pub. The link takes you to communication pubs for z/OS v1r12.

Tuesday, September 28, 2010

HOW TO SERIALIZE A JAVA TABLE THAT HAS ROWS OF VARIABLE HEIGHT

Not strictly a mainframe topic, I know, but this has been such a pain in the ass to figure out that I want to save others from the nonsense I had to go through to work this out.

-=THE SITUATION=-

You have a Java table with a custom renderer that allows for the text in cells to word-wrap, thus altering the height of some of the table rows. You want to serialize this table model and you get a java error regarding a sizeSequence.


-=WHAT'S GOING ON=-

Basically, the problem is that Java is dumb. When you execute the setRowHeight method for the table in question, it should be updating the SizeSequence (the thing that keeps track of where one row ends and another begins), but it's not. Not a problem until you try to serialize the table and Java freaks out because there is a discrepancy.


-=THE FIX=-

Put this line:

[table model].fireTableDataChanged();

just prior to your attempt to serialize. It'll force Java to do what it should've done in the first place, which is update SizeSequence, and allow you to serialize your table.

Sunday, August 29, 2010

HOW TO CLEAR THE SCREEN IN TSO, CLIST, OR REXX

I did some digging and found a forum thread with the answer. It seems that you can't do it from TSO. You can, however, write a simple assembler module that will do it for you.

here is the thread with the source for the asm module


here is a link to the IBM pub that describes the STLINENO macro

Thursday, August 12, 2010

HOW TO REMOVE SYSTEM MESSAGES FROM THE CONSOLE

You can use PF1 to remove them one at a time. Does someone know how to clear them all at once?

Thursday, August 5, 2010

HOW TO COMPILE AND LINK EDIT MULTIPLE ASSEMBLER MODULES AT THE SAME TIME

This is the best way I could come up with. If someone has something better (a way to do it from within the JCL perhaps?) please let me know. We are going to create three files:

1) a text file that contains the names and locations of the modules you are going to work with

2) JCL that will compile and link edit the modules

3) a REXX exec that will read data from the environment file, edit the JCL accordingly, then submit the JCL for each member in the environment file. Essentially, you are going to submit a job for each module you want compiled, and the REXX will do that for you automatically via the parameters you specify in the environment file.

Here is the environment file sample:

/*********************************************************************/
/* ASMCLENV - ENVIRIONMENT FILE USED BY ASMCLREX */
/* */
/* 04AUG10 */
/* */
/*********************************************************************/

*1
[location of source module to be compiled]
[where to put the compiled module]
[where to put the link edited load module]

*2
[same format as above]



The REXX exec is going to look for an '*' in column one as it reads this file to tell it where the data it's looking for is. Also, make sure to include the high-level qualifier in the data set name.


Here is the JCL:


//ASMCL JOB 'COMPILE AND BIND ASSY',MSGLEVEL=(1,1),
// NOTIFY=&SYSUID,MSGCLASS=H,CLASS=1
//*
//*** HLASMCL
//*
//* THIS PROCEDURE RUNS THE HIGH LEVEL ASSEMBLER
//* AND LINK-EDITS THE NEWLY ASSEMBLED PROGRAM
//*
//*********************************************************************
//* COMPILE STEP *
//*********************************************************************
//C EXEC PGM=ASMA90,PARM=(OBJECT,NODECK)
//SYSLIB DD DSN=SYS1.MACLIB,DISP=SHR
//*
//SYSUT1 DD DSN=&&SYSUT1,SPACE=(4096,(120,120),,,ROUND),UNIT=SYSDA,
// DCB=BUFNO=1
//*
//SYSIN DD DSN= LOCATION OF SOURCE ASSY PGM **
//*
//SYSLIN DD DSN= WHERE OBJECT MODULE SHOULD BE WRITTEN **
//*
//SYSPRINT DD SYSOUT=*
//*********************************************************************
//* LINK STEP *
//*********************************************************************
//L EXEC PGM=HEWL,COND=(8,LT,C),
// PARM='NOMAP,NOLET,NOLIST,NCAL'
//*
//SYSLIN DD DSN= LOCATION OF MODULE TO BE LINKED **
//*
//SYSLMOD DD DSN= WHERE LINKED MODULE SHOULD BE WRITTEN **
//*
//SYSUT1 DD DSN=&&SYSUT1,SPACE=(1024,(120,120),,,ROUND),UNIT=SYSDA,
// DCB=BUFNO=1
//*
//SYSPRINT DD SYSOUT=*



This you shouldn't have to do anything with, just cut and paste, but be careful! JCL is very picky about operands being in the correct row/column. Make sure the lines that are continuations (the part of the statement that is continued on the next line) begins in column 16 or you'll get a big fat error!


Here is the REXX that drives the whole thing:

/* REXX */
/*********************************************************************/
/* CREATED 04AUG10 */
/* */
/* THE PURPOSE OF THIS EXEC IS TO DRIVE ASMCL (JCL TO COMPILE AND */
/* LINK EDIT AN ASSEMBLER MODULE). ASMCLREX WILL READ ASMCLENV TO */
/* GET A LIST OF ASSEMBLER SOURCE FILES TO COMPILE AND LINK. IT WILL */
/* THEN UPDATE ASMCL WITH THE DATA FROM ASMCLENV, SUBMIT THE JOB, */
/* AND REPEAT FOR EACH ENTRY IN ASMCLENV. THIS WAY WE CAN COMPILE AND*/
/* LINK MULTIPLE SOURCE FILES AT A TIME. */
/* */
/*********************************************************************/

ADDRESS TSO


/*READ ENVIRONMENT DATA***********************************************/

"ALLOC DD (INDDENV) DA('LOCATION OF ENVIRONMENT FILE') SHR REUSE"
'EXECIO * DISKR INDDENV (STEM ENVDATA. FINIS'
"FREE DD(INDDENV)"
ENVSIZE = ENVDATA.0
SYSIN = "//SYSIN DD DSN="
SYSLIN = "//SYSLIN DD DSN="
SYSLMOD = "//SYSLMOD DD DSN="
DISP = ",DISP=SHR"


/*LOOP THROUGH ENVIRONMENT DATA TO PULL OUT RELEVANT INFORMATION*****/

DO I = 1 TO ENVSIZE

/*IF ENTRY MARKER IS FOUND, UPDATE ASMCL AND SUBMIT THE JOB**********/

IF(SUBSTR(ENVDATA.I,1,1)) = '*' THEN DO
"ALLOC DD (INDDACL) DA('LOCATION OF TEMPLATE JCL') SHR REUSE"
'EXECIO * DISKR INDDACL (STEM ACLDATA. FINIS'
"FREE DD(INDDACL)"

ACLSIZE = ACLDATA.0

K = I + 1
ENVDATA.K = STRIP(ENVDATA.K)
ACLDATA.18 = SYSIN || ENVDATA.K || DISP
K = K + 1
ENVDATA.K = STRIP(ENVDATA.K)
ACLDATA.20 = SYSLIN || ENVDATA.K || DISP
ACLDATA.29 = SYSLIN || ENVDATA.K || DISP
K = K + 1
ENVDATA.K = STRIP(ENVDATA.K)
ACLDATA.31 = SYSLMOD || ENVDATA.K || DISP

"ALLOC DD (OUTDD) DA('LOCATION OF TEMPLATE JCL') SHR REUSE"

'EXECIO * DISKW OUTDD (FINIS STEM ACLDATA.'
"FREE DD(OUTDD)"

"SUBMIT 'LOCATION OF TEMPLATE JCL'"

END

END

Friday, July 30, 2010

A QUICK WAY TO CREATE A MEMBER IN AN EMPTY DATASET

Normally, if you are working with a PDS that is populated with members, you can create a new member by going to ISPF option 3.4, entering the data set name, then typing S [new member name] and the command line. Unfortunately, this doesn't work if the PDS is empty. To get around this, go to ISPF option 2 (EDIT), and enter the data set name with the name of the member you want to create like this:
OTHER PARTITIONED OR SEQUENTIAL DATA SET:
DATA SET NAME ===> 'data.set.name(newmemb)'

I found this gem and some other neat ISPF tricks here.