Highlighted
Super Contributor.
Super Contributor.
2780 views

File remains locked after managed COBOL returns to ASPX caller

Jump to solution
Our application is a collection of originally Unisys mainframe tasks (IBM jobs) that over the last 18 years we have converted to Object COBOL, then Net Express, and finally Visual COBOL 2.3 for VS 2013 Update 1. Each task consists of an .exe using a Screen Section and DISPLAY/ACCEPT to input run parameters calling a number of .dlls and passing the run parameters through a Linkage Section. Every task is executed from a single parameterized .bat file that, among other things, sets the console redirection switch and appends all program DISPLAY output to a log file. This gives us a record of everything that happens in a run. We are converting this application from native console/libraries to web-accessible ASPXs in #C (replacing the .exes) and managed COBOL (replacing the .dlls) The ASPX program starts the log file by writing some initial info and then closes the file. Each called COBOL program then opens the log file in EXTEND mode, writes (DISPLAYs have been converted to WRITEs)its messages as it processes, and closes the file before returning. The ASPX program appends some closing info after the last COBOL program returns. Our problem is when there is a Run Time error in a COBOL program ("file not found" for example). We are getting the error info back in the ASPX program, but the log file is still locked (by the terminated COBOL program?) and can't be opened to add the error info. The only way to unlock the file is to restart the application in IIS. Anybody got any ideas on another, programmable way by which we can get the log file unlocked? Or even better, how to guarantee any file open at the time of a Run Time Error will be closed/unlocked when the COBOL program has been left?
0 Likes
1 Solution

Accepted Solutions
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

Sorry, I misread your initial post and thought the error you were getting was missing program (173 on call) but it was really missing file.

You can get the behavior you desire by using the RunUnit class and then when control returns from the subprogram whether it be through an exception in the try catch block or by normal processing, you can invoke the StopRun method on the RunUnit. This will perform the normal cleanup that you desire such as closing open files.

It would look something like the following:

    RunUnit myRunUnit = new RunUnit();
    try
         {
       COBOLClassLibrary.myclass cobclass = new COBOLClassLibrary.myclass();
                myRunUnit.Add(cobclass);
       cobclass.startCOBOL(passparams as string);
    catch (Exception ex)
         {
       Console.WriteLine(ex.Message);
         }
    finally
         {
               myRunUnit.StopRun();
         }
       }

If each of your COBOL programs is a separate entity then you would need to execute one of these RunUnit blocks for each call. Instead of coding each one like this it may be better to just create a class that will handle this processing that can be used as a traffic cop. Your aspx program could pass in the name of the program to call and params and then call a method that would create the RunUnit etc.

Environment variables set in your aspx program will be picked up by the file handler within each rununit. You could set the environment variables within the RunUnit itself but it will inherit variables that are set at the time of the call.

To set an environment variable only at the RunUnit level you could do:

 myRunUnit.SetEnvironmentVariable("dd_NEW", "C:\\temp");

 

View solution in original post

0 Likes
10 Replies
Highlighted
Absent Member.
Absent Member.

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

One possible solution would be to add exception processing for certain errors that could be detected. In your example of "File Not Found" you could add that check and then if the file is not there go ahead and do any closing of files or other clean up before you return to the ASPX program. We have not yet started to work with the .NET environment, but you may want to look if it has a way do the exception processing under its umbrella of control.

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

As jholland states, you can add exception handling around the call statement using try/catch syntax so that you can close the file before the exception is passed back to the main program. In this scenario where you have a multi-threaded web application where all the programs and threads are writing to the same log file it might be a good idea to implement an open-->write-->close approach for each message being written so that the file is not kept in an open extend state.

Are you performing your COBOL programs within a RunUnit created by the C# .aspx program?

0 Likes
Highlighted
Super Contributor.
Super Contributor.

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

jholland's suggestion, as I understand it, would require adding FILE STATUS clauses to every SELECT statement in over 250 programs, plus logic code after every IO statement to test-and-branch.  We were hoping the conversion from native to managed wouldn't involve such a massive coding effort.

I don't understand Mr. Glazier's suggestion of "add exception handling around the call statement using try/catch syntax".  In the ASPX program?  That is what the programmer has already done, but by that time the COBOL program has exited and the log file is locked.  In the COBOL program?  What "call statement" is he referring to?

The "open-->write-->close" method has been debated, but we were (are?) hoping for another solution that would be more "automatic", such as the what happens in native code after a STOP RUN.

The non-COBOL programmer doing the actual work of replacing the COBOL .exe task programs with ASPX versions looked over the documentation and for reasons I don't understand (because I'm so new to VS and don't know hardly anything about .Net and ASPX?) has balked at using Run Units.  Something about "your calling a COBOL program in order to call a COBOL program when its all managed code and I don't see the point"?  Do I understand correctly that a Run Unit would have to be instantiated before every call to a managed COBOL .dll, and then terminated before the next call?

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

I was referring to adding a try catch block around the call statement that may cause the RTS 173 to occur or some other run-time error that occurs within the same program in which the file has been opened. This way you can trap the exception instead of allowing it to be propagated up to the aspx level. You could reraise the exception after you closed the file in order to pass it back to the aspx level.

          open output test-file
          try
            call next-prog
          catch ex as type Exception
             display ex::Message
             close test-file
        *> raise ex            
          end-try
          display "after call"

If you are calling COBOL programs within a multithreaded web app that uses a thread pool then you must use RunUnits or the programs will not be thread safe. Each thread will share the same data, database connections, files etc. Creating a RunUnit isolates these threads from each other. Evan if you are calling a COBOL object program, if you are using database connections, file hander or RTS system calls then you also need to place this within a RunUnit.

Only the top level program that is being called needs to be added to a rununit. Any programs that it calls will automatically be part of the same rununit. In this way multiple threads can each have their own copy of the program and its resources.

0 Likes
Highlighted
Super Contributor.
Super Contributor.

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

But all of the calls to COBOL programs occur at the aspx program level.  No COBOL program calls any other COBOL program.  The aspx programs are replacing native COBOL console .exe programs which themselves replaced JCL streams in the original mainframe batch environment.  Here's a pseudo code example of what we have so far:

task.aspx -

open output logfile

{write initial log stuff}

close logfile

try

call cblprgm1.dll

catch

open logfile

{write error message}

close logfile

exit run

end-try

[

try

call cblprgm2.dll

catch

open logfile

{write error message}

close logfile

exit run

end-try

.

.

.

]

open extend logfile

{write final log stuff}

close logfile

exit run

cblprgm1 -

open extend logfile *> added because no redirect

{process}

write log entry *> converted from DISPLAY UPON CONSOLE

{process}

write log entry *> converted from DISPLAY UPON CONSOLE

.

.

.

close logfile *> added because no redirect

exit program

cblprgm2 -

open extend logfile *> added because no redirect

{process}

write log entry *> converted from DISPLAY UPON CONSOLE

{process}

write log entry *> converted from DISPLAY UPON CONSOLE

.

.

.

close logfile *> added because no redirect

exit program

Each of our 60+ aspx tasks makes from 1-85 calls to COBOL programs.  Each COBOL program performs its function and returns to the calling aspx program.

In this situation, would we start a run unit for each call and terminate it after each return?

Would the dd_ environment variables set by the aspx program be accessible to the MF file handler inside the run unit?

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

Sorry, I misread your initial post and thought the error you were getting was missing program (173 on call) but it was really missing file.

You can get the behavior you desire by using the RunUnit class and then when control returns from the subprogram whether it be through an exception in the try catch block or by normal processing, you can invoke the StopRun method on the RunUnit. This will perform the normal cleanup that you desire such as closing open files.

It would look something like the following:

    RunUnit myRunUnit = new RunUnit();
    try
         {
       COBOLClassLibrary.myclass cobclass = new COBOLClassLibrary.myclass();
                myRunUnit.Add(cobclass);
       cobclass.startCOBOL(passparams as string);
    catch (Exception ex)
         {
       Console.WriteLine(ex.Message);
         }
    finally
         {
               myRunUnit.StopRun();
         }
       }

If each of your COBOL programs is a separate entity then you would need to execute one of these RunUnit blocks for each call. Instead of coding each one like this it may be better to just create a class that will handle this processing that can be used as a traffic cop. Your aspx program could pass in the name of the program to call and params and then call a method that would create the RunUnit etc.

Environment variables set in your aspx program will be picked up by the file handler within each rununit. You could set the environment variables within the RunUnit itself but it will inherit variables that are set at the time of the call.

To set an environment variable only at the RunUnit level you could do:

 myRunUnit.SetEnvironmentVariable("dd_NEW", "C:\\temp");

 

View solution in original post

0 Likes
Highlighted
Super Contributor.
Super Contributor.

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

So where is RunUnit?  The programmer is trying to instantiate a run unit using the same syntax as the first line in your last example and the the build is coming back with "can't find RunUnit".  Is it in a library other than in the run time system's?

0 Likes
Highlighted
Outstanding Contributor.
Outstanding Contributor.

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

MicroFocus.COBOL.RuntimeServices.RunUnit

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

If you wish to use the shortened name like I did then add a using statement to reference the namespace MicroFocus.COBOL.RuntimeServices in your C# program.

0 Likes
Highlighted
Super Contributor.
Super Contributor.

RE: File remains locked after managed COBOL returns to ASPX caller

Jump to solution

Thank you lanter and chris.

Sorry about that, I thought my co-worker had done due diligence before hollering.  He found it when he went looking through the other libraries (and after I had posted the "where").

I guess this answers all.

0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.