0
votes

I am submitting a JCL job to allocate a VB dataset in Mainframe. After submitting the job, the dataset gets created successfully.

Then I am running a java program in omvs region of mainframe, to open the file and write some contents into it. When I try to write the data into the file I am getting the below error.

//DD:SYS00011 : fwrite() failed. EDC5024I An attempt was made to close a file that had been opened by another thread.; errno=24 errno2=0xc0640021 last_op=0 errorCode=0x0.

JCL submitted to allocate the dataset:

//USERNAME JOB ABC,,NOTIFY=&SYSUID,CLASS=F,MSGLEVEL=(1,1),MSGCLASS=X 
//STEP1 EXEC PGM=IEFBR14 
//STEP DD DSN=ASD00T.SM.ULRL, 
// DISP=(NEW,CATLG,DELETE), 
// UNIT=SYSDA,SPACE=(1,(10,60),RLSE),AVGREC=M, 
// DCB=(RECFM=VB), 
// DSORG=PS

code to write the file:

zFileIn = new ZFile("//'ASD00T.INPUT.ULRL'", "rb,type=record,noseek");
if (zFileIn.getDsorg() != ZFile.DSORG_PS) {
throw new IllegalStateException("Input dataset must be DSORG=PS");
 }
zFileOut = new ZFile("//'ASD00T.SM.ULRL'", "wb,type=record,noseek, recfm="+ zFileIn.getRecfm()+ ", lrecl="+ zFileIn.getLrecl());
long count = 0;
byte[] recBuf = new byte[zFileIn.getLrecl()];
int nRead;
while((nRead = zFileIn.read(recBuf)) >= 0) {
zFileOut.write(recBuf, 0, nRead);
count++;
}
1
@valerie-r please let me know if you have encountered this issue? - Vel
Can you post the code for it? It will impossible to debug otherwise, it sounds like the file is either in use, or wasn't opened properly. We can't really tell without seeing how the file was opened. - SaggingRufus
We need to see the JCL, which will resolve what you mean about allocate (which means something) and created (which means something else). Also the minimum Java code from your program which shows the problem. Also, how are you doing the timing? You manually execute the Java after you know the z/OS JOB has completed? - Bill Woodger
You have some sort of multi-tasking occuring; the message implies that one thread opened a file and another thread is trying to close it, which is forbidden. How are you invoking the Java program: JZOS, BPXBATCH, TSO OMVS, tty? Is the Java program home-grown or part of a package? - zarchasmpgmr
@zarchasmpgmr I am submitting the jcl job manually to allocate the dataset. once it its successfull i am triggering the java jar file manually. I am running the java program from tso omvs....i am using zfile class provided by ibmjzos.jar.... - Vel

1 Answers

1
votes

The heart of your problem is that you need to invoke the ZFile.close() method after you're done writing. Doing so will guarantee that the open, writes and close all happen under the same thread and you should be fine. This is a side-effect of using conventional datasets instead of USS files.

The reason for this is complicated, but it has to do with the fact that in z/OS, "conventional" QSAM/BSAM/VSAM datasets behave slightly differently than do UNIX filesystem files.

If you were writing to a UNIX file (HFS, ZFS, NFS, etc) instead of a conventional dataset, what you're doing would work perfectly fine...this is because USS treats resource ownership differently - file handles are owned at a process level, not a thread. When you open a USS file, that file handle can be used or closed by any thread in the process...this is mandated by the various UNIX standards, so z/OS has no choice but to work this way.

Conventional datasets are a bit different. When you open a conventional dataset, the operating system structures that define the open file are stored in memory anchored to the thread where the file was opened. There's enough information in the file handle that you can do I/O from other threads, but closing the file needs to happen from the thread where the file was opened.

Now, since you don't seem to have a close() in your code, the file stays open until your Java thread ends. When your Java thread ends, the system runtime gets control in order to clean up any resources you might have allocated. It sees the lingering open file and tries to close it, but now it's not running under the thread that opened the file, so you get the failure you're seeing.

Normally, UNIX files and z/OS datasets work almost exactly the same, but this issue is one of the slight differences. IBM gets away with it from a standards compliance perspective since z/OS datasets aren't part of any standard, and generally, the way they can be used interchangeably is a great feature.

By the way, all of this is spelled out in the fine print of the LE (Language Environment) and C Runtime references.