Hello,
I am trying to submit a JCL from JZOS. 99% of the time, it works great. Once in a while I see this error. Could this be happening because the the java application spawns too many JCL's back to back? If so, are there any work arounds?
IKJ56246I SYSOUT DATA SET NOT ALLOCATED, FILE IN USE
com.ibm.jzos.RcException: bpxwdyn failed RC=68157440 (0x4100000)
at com.ibm.jzos.ZFile.bpxwdyn(Native Method)
at package1.Classname0o.printPDF(Dpj01o.java:34)
at package1.Classname0z.createPDF(Dpj01z.java:132)
at package1.Classname0z.main(Dpj01z.java:39)
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:618)
at com.ibm.cics.server.Wrapper.call_main(Wrapper.java:592)
at com.ibm.cics.server.Wrapper.callUserClass(Wrapper.java:721)
at com.ibm.cics.server.Wrapper.main(Wrapper.java:1200)
at com.ibm.cics.server.Wrapper.WrapperEntry(Wrapper.java:972)
Thanks for your time
SYSOUT Allocation error/bpxwdyn failed
What DDNAME are you using? If you are using a constant name, then you might get two request simultaneously and get this error.
Best to use ZFile.allocDummyDDName() to get a "SYSnnnnn" ddname to use. When you use this ddname in your bpxwdyn allocation, you will need to add the "reuse" keyword, since the ddname is already allocated to "DUMMY". And make sure that you close the file free the ddname, in a "finally" block so that you don't have any leaks.
Best to use ZFile.allocDummyDDName() to get a "SYSnnnnn" ddname to use. When you use this ddname in your bpxwdyn allocation, you will need to add the "reuse" keyword, since the ddname is already allocated to "DUMMY". And make sure that you close the file free the ddname, in a "finally" block so that you don't have any leaks.
Thanks. These are the SYSOUT references I have in the JCL that is being spawned by the Java application.
//SYSUT2 DD SYSOUT=A,DEST=PRINTERID1,COPIES=1,
// DCB=(RECFM=FB,LRECL=80,DSORG=PS)
//SYSPRINT DD SYSOUT=*
But are you talking about this line in my java application where I refer to SYSOUT
ZFile.bpxwdyn("alloc fi(JCL) sysout writer(intrdr) recfm(f) lrecl(80) msg(2)");
Thanks.
//SYSUT2 DD SYSOUT=A,DEST=PRINTERID1,COPIES=1,
// DCB=(RECFM=FB,LRECL=80,DSORG=PS)
//SYSPRINT DD SYSOUT=*
But are you talking about this line in my java application where I refer to SYSOUT
ZFile.bpxwdyn("alloc fi(JCL) sysout writer(intrdr) recfm(f) lrecl(80) msg(2)");
Thanks.
I was referring to your ZFile.bpxwdyn() call. There are a couple of ways that you could get a "file in use" error when you open:
- there are two simultaneous requests - are you running in a web container like Tomcat?
- for some reason you didn't free the DD on an earlier request.
To fix the first problem, use ZFile.allocDummyDDname() and then use this dd rather than "JCL".
For the second problem, make sure that you have "finally" handlers so that you close the file and free the DD, even if an error occurs. This should be done in all cases.
- there are two simultaneous requests - are you running in a web container like Tomcat?
- for some reason you didn't free the DD on an earlier request.
To fix the first problem, use ZFile.allocDummyDDname() and then use this dd rather than "JCL".
For the second problem, make sure that you have "finally" handlers so that you close the file and free the DD, even if an error occurs. This should be done in all cases.
No, I am not running under Tomcat. I am running under CICS, but it's possible that it got hit by simultaneous requests. I did have the free statement when I put this together last year.
This is the latest version of the code and I would really appreciate it, if you could spare a minute to look at it and let me know if I got it right. Thanks for your time again!
String ddname = ZFile.allocDummyDDName();
ZFile.bpxwdyn("alloc fi(" + ddname + ") sysout writer(intrdr) recfm(f) lrecl(80) msg(2)");
BufferedWriter wtr = null;
String lpar = Region.getAPPLID();
try {
wtr = FileFactory.newBufferedWriter("//DD:" + ddname);
wtr.write("//PRINT001 JOB (XXXXXXX),'YYYYY',MSGLEVEL=(1,1), \n");
wtr.write("// CLASS=" + lpar.charAt(4) + ",MSGCLASS=H \n");
wtr.write("//STEP010 EXEC PGM=IEBGENER \n");
wtr.write("//SYSUT1 DD PATH='" + filename + "', \n");
wtr.write("// RECFM=FB,LRECL=80,BLKSIZE=800,FILEDATA=BINARY \n");
wtr.write("//SYSUT2 DD SYSOUT=A,DEST=" + PrinterID + ",COPIES=" + copies + ", \n");
wtr.write("// DCB=(RECFM=FB,LRECL=80,DSORG=PS) \n");
wtr.write("//SYSPRINT DD SYSOUT=* \n");
wtr.write("//SYSIN DD DUMMY \n");
wtr.write("// \n");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (wtr != null)
try {
wtr.flush();
wtr.close();
} catch (IOException ignore) {
}
ZFile.bpxwdyn("free fi(" + ddname + ") msg(2)");
}
}
This is the latest version of the code and I would really appreciate it, if you could spare a minute to look at it and let me know if I got it right. Thanks for your time again!
String ddname = ZFile.allocDummyDDName();
ZFile.bpxwdyn("alloc fi(" + ddname + ") sysout writer(intrdr) recfm(f) lrecl(80) msg(2)");
BufferedWriter wtr = null;
String lpar = Region.getAPPLID();
try {
wtr = FileFactory.newBufferedWriter("//DD:" + ddname);
wtr.write("//PRINT001 JOB (XXXXXXX),'YYYYY',MSGLEVEL=(1,1), \n");
wtr.write("// CLASS=" + lpar.charAt(4) + ",MSGCLASS=H \n");
wtr.write("//STEP010 EXEC PGM=IEBGENER \n");
wtr.write("//SYSUT1 DD PATH='" + filename + "', \n");
wtr.write("// RECFM=FB,LRECL=80,BLKSIZE=800,FILEDATA=BINARY \n");
wtr.write("//SYSUT2 DD SYSOUT=A,DEST=" + PrinterID + ",COPIES=" + copies + ", \n");
wtr.write("// DCB=(RECFM=FB,LRECL=80,DSORG=PS) \n");
wtr.write("//SYSPRINT DD SYSOUT=* \n");
wtr.write("//SYSIN DD DUMMY \n");
wtr.write("// \n");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (wtr != null)
try {
wtr.flush();
wtr.close();
} catch (IOException ignore) {
}
ZFile.bpxwdyn("free fi(" + ddname + ") msg(2)");
}
}
This looks pretty good, except for a couple of things:
1) In your bpxwdyn() call, add the keyword "reuse". This is required as the ddname is already allocated to "dummy".
2) In your finally block, you may want to wrap the flush() and close() in separate try/ignore blocks. This would avoid the problem where flush() gets an IO error and prevents close() from being called. Alternatively, just remove flush(), since close() will do a flush implicitly.
1) In your bpxwdyn() call, add the keyword "reuse". This is required as the ddname is already allocated to "dummy".
2) In your finally block, you may want to wrap the flush() and close() in separate try/ignore blocks. This would avoid the problem where flush() gets an IO error and prevents close() from being called. Alternatively, just remove flush(), since close() will do a flush implicitly.