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.
Contents |
---|
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 information.
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, in order 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-IF
In 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.InvalidRequestException
The 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.