CICS exception handling in JCICS programs
CICS conditions and exceptions are integrated into the Java™ exception-handling architecture to handle problems that occur in CICS. You can use a set of Java exceptions and methods to handle CICS® error conditions, and abend or roll back CICS tasks.
Class hierarchy of JCICS exceptions
The JCICS API classes contain checked exceptions and unchecked exceptions. CICS checked exceptions extend the CicsException class. They correspond to the response codes of
error conditions returned from the underlying EXEC CICS commands and need to be handled by your program. CICS unchecked exceptions extend the CicsRuntimeException class and represent failures within CICS or ABENDs.
For more information about each class, see JCICS Javadoc reference.
Catching checked exceptions
In Java, checked exceptions are used when you want the user of your API to design how to
handle the exceptional situation. They must either be caught or declared as part of the method
signature using the throws keyword. Any Java code that calls a method declared as throwing a checked exception must either provide logic to catch the checked exception, or add the exception to its own method signature, to propagate the exception further up the stack. The constraints on checked exceptions are enforced at compile time, and failure to adhere to the specification will result in a compilation error.
PGMIDERR) to the application using the data area supplied in the
RESP parameter of the CICS command. This enables the application to handle or ignore errors on a call-by-call basis.EXEC CICS LINK PROGRAM('ECIPROG') RESP(RESP)
END-EXEC
IF RESP = DFHRESP(INVREQ)
.......
END-IFIn JCICS, things are similar because almost all JCICS commands can throw sub-classes of the
checked CICSConditionException, which represent error response codes from the
underlying EXEC CICS commands. The full list of Java exception classes and the CICS error conditions they map to can be found at Mapping between CICS conditions and JCICS exceptions.
INVREQ response code maps to an
InvalidRequestException class. The class hierarchy looks like
this:java.lang.Exception
com.ibm.cics.server.CicsException
com.ibm.cics.server.CicsConditionException
com.ibm.cics.server.CicsResponseConditionException
com.ibm.cics.server.InvalidRequestExceptionThe following example shows how the InvalidRequestException class, which maps
into the INVREQ response code, can be used in a Program.link()
call. Each sub-class of CicsConditionException, including
InvalidRequestException, can be individually caught so specific errors can be
caught or ignored.
Order is important, a compilation error is displayed if a catch clause for a more generic
exception appears before a catch clause for a more specific one (that is, for one of its
sub-classes). This example logs a message for the InvalidRequestException and carries on processing. This means the transaction will continue normal processing and thus potentially commit any recoverable data, so make sure you don’t do this for fatal errors. The example then catches all other CICS errors (catch(CicsConditionException cce)) and
throws them up the stack using a new RuntimeException class to drive subsequent error handling, which by default will abend the CICS task and rollback the transaction.
task task = Task.getTask();
task.out.println("Hello world");
try
{
Program prog = new Program();
prog.setName(PROG_NAME);
prog.setSyncOnReturn(false);
byte[] ca = new byte[CA_LEN];
prog.link(ca);
}
catch (InvalidRequestException ire)
{
task.out.println("Invalid request on link - INVREQ");
}
catch (CicsConditionException cce)
{
throw new RuntimeException(cce);
}
Catching unchecked exceptions
In Java, unexpected error conditions are represented by Java classes that extend the RuntimeException class and are known as unchecked exceptions.
Unchecked exceptions are not subject to the compile time checking mandated for checked exceptions,
although they can be caught if required. In the JCICS API, all the unchecked exceptions extend the
CICSRuntimeException class.
All of the unchecked exceptions that extend the CICSRuntimeException class represent conditions within CICS that are generally not handled by an application, to avoid interrupting the Java applications. They can include CICS ABENDs or some internal CICS events, such as program termination. Java code running in CICS must not catch these exceptions without re-throwing them, either explicitly in a catch block, or implicitly by catching a superclass of these exceptions such as Exception or Throwable as follows:
try
{
...
}
catch ( Exception e )
{
...
}
Instead, they need to be allowed to propagate out of the Java environment and back to CICS, where the task will abend. Included in this list is the AbendException class, which represents an ABEND of a CICS task. These ABENDs typically occur during sync point processing. The AbendException class must only be caught if you want to develop your own Java abend handling routine and re-throw the exception. If a Java exception such as a null pointer exception is allowed to propagate out of the Java code and back to the JVM server runtime, this is generally surfaced as one of the CICS ABENDs prefixed with AJ. Most commonly, an uncaught
exception will result in an AJ04 abend, and the transaction will be rolled back.
Task.abend() after catching an AbendException. If Task.abend() is called, CICS issues the message DFHSJ1007, and disables and restarts the JVMSERVER.Abending and rolling back CICS tasks
It is also possible for a Java application to abend or roll back the CICS task directly. This can be achieved using the Task.abend() or Task.rollback() methods in
the Task class, as shown in the LinkServEC01 sample. Abending the CICS task is similar in concept to the throwing of Java exception because it allows a CICS ABEND handler written in COBOL (or another language) to take control of error processing.
The various forms of the Task.abend() method allow an application to optionally
specify an abend code or whether a dump is required. The forceAbend() methods
provide the same options as the equivalent abend methods, but are equivalent to specifying the
CANCEL keyword on the EXEC CICS ABEND command. Invoking a
forceAbend() method always terminates the task abnormally, and overrides any existing CICS abend handlers that have been established for the task.
Task.rollback() method of the Task class as
follows:try
{
Task.getTask().rollback();
}
catch (InvalidRequestException ire)
{
.....
} LinkServEC01 contains a full sample where
Task.rollback() is used to roll back the CICS task.
Note that when accessing resources that are controlled by the Liberty transaction manager, such
as a remote Db2® database
using JDBC type 4 connectivity, it is necessary to use the Java transaction API (JTA) to create a Java transaction to control the global transaction scope, including the subordinate CICS unit-of-work. In this case it is not possible to use the Task.rollback() method and instead the JTA API needs to be used.