Bank
example of Chapter 6, "Programming OrbixWeb using Java" to raise a user-defined exception, show how to throw such exceptions in the server code and how to handle them in the client. We also describe OrbixWeb system-defined exceptions in detail.
Note that OrbixWeb does not require any special handling for exceptions. IDL exceptions are mapped to Java classes which inherit from
java.lang.Exception
. Therefore, exceptions thrown by a server can be handled by try
and catch
statements in the normal way.12.1 User-Defined Exceptions
In this section, we illustrate how to define exceptions in IDL and describe the OrbixWeb Java mapping for such user-defined exceptions.12.1.1 The IDL Definitions
Continuing with the Bank
example, we extend the interface Bank
so that the newAccount()
operation may raise an exception if the bank is unable or unwilling to create an Account
object.Reject
is defined within the Bank
interface and it defines a string member which will indicate the reason which caused the Bank
to reject the request.
// IDL interface Account { // Bank accounts. readonly attribute float balance; void makeDeposit(in float f); void makeWithdrawal(in float f); }; // A factory for bank accounts. interface Bank { exception Reject { string reason; }; Account newAccount(in string name) raises (Reject); // Delete an account. void deleteAccount(in Account a); };
idl -jP idl_demo bank.idlThe Java code produced by the IDL compiler will be generated within the
idl_demo
package.The Java class generated from the IDL exception definition is:
// Java // Automatically generated, // in file _Bank/Reject.java. package idl_demo._Bank; import IE.Iona.Orbix2._CORBA; public class Reject extends IE.Iona.Orbix2.CORBA.UserException implements IE.Iona.Orbix2.CORBA.IDLCloneable, IE.Iona.Orbix2.CORBA.Marshalable { public String reason; public Reject() { ... } public Reject(String reason) { ... } ... }Note that class
Reject
(in package idl_demo._Bank
) inherits from the OrbixWeb class UserException
(in package IE.Iona.Orbix2.CORBA
). This OrbixWeb class in turn inherits from CORBAException
, which is a direct subclass of java.lang.Exception
. It is this inheritance which allows Reject
to be thrown and handled as a Java exception.Since the
Reject
exception has one member (reason
, of type string
) a constructor is provided in the generated class, which allows this member to be initialised.The Java interface for
Account
is generated as follows:
// Java // Automatically generated, // in file _AccountRef.java. package idl_demo; public interface _AccountRef extends IE.Iona.Orbix2.CORBA._ObjectRef { public float balance() throws IE.Iona.Orbix2.CORBA.SystemException; public void makeDeposit(float f) throws IE.Iona.Orbix2.CORBA.SystemException; public void makeWithdrawal(float f) throws IE.Iona.Orbix2.CORBA.SystemException; }while the generated interface for
Bank
is:
// Java // Automatically generated, // in file _BankRef.java. package idl_demo; public interface _BankRef extends IE.Iona.Orbix2.CORBA._ObjectRef { public idl_demo._AccountRef newAccount( String name) throws idl_demo._Bank.Reject, IE.Iona.Orbix2.CORBA.SystemException; public void deleteAccount( idl_demo._AccountRef a) throws IE.Iona.Orbix2.CORBA.SystemException; }Note that the generated method for operation
newAccount()
includes a throws
clause for exception idl_demo.Bank.Reject
.
The system exceptions are implemented as a set of Java classes (in the package
IE.Iona.Orbix2.CORBA
), organised into a class hierarchy: each system exception is a derived class of SystemException
(which in turn is a derived class of CORBAException
). This allows all system exceptions to be caught in one single Java catch
clause. A client can also handle individual system exceptions in separate
catch
clauses, as described in section 12.3.1. Each system exception is implemented as a class of the following form:
// Java package IE.Iona.Orbix2.CORBA; public class <EXCEPTION TYPE> extends IE.Iona.Orbix2.CORBA.SystemException { public <EXCEPTION TYPE> (){ ... } public <EXCEPTION TYPE> (int minor, int compl_status) { ... } public <EXCEPTION TYPE> (int minor, int compl_status, String detail) { ... } }The full set of system exceptions defined by OrbixWeb are documented in Appendix B, "System Exceptions" of the OrbixWeb Reference Guide. This appendix provides a complete listing of the OrbixWeb system exception classes and gives a brief description of each.
12.3 The Client: Handling Exceptions
A client (or server) which calls an operation that may raise a user exception should handle that exception using an appropriate catch
statement. Naturally, a client should also provide handlers for potential system exceptions. Here we show an example client program:
// Java // In file Client.java. package idl_demo; import IE.Iona.Orbix2.CORBA.SystemException; public class Client { public static void main (String args[]) { _BankRef bRef; _AccountRef aRef; try { // Bind to bank with marker College_Green // in the BankSrv server. bRef = Bank._bind ("College_Green:BankSrv"); // Obtain a new bank account. aRef = bRef.newAccount("Joe"); } catch (_Bank.Reject re) { System.out.println ("Error on newAccount():"); System.out.println ("Account creation rejected " + "with reason: " + re.reason); return; } catch (SystemException se) { System.out.println ( "Unexpected system exception:"); System.out.println (se.toString ()); return; } // Continue here if no exception. ... } }The handler for the
idl_demo._Bank.Reject
exception outputs an error message and exits the program. The toString()
method defined on class SystemException
generates a text description of the individual system exception that was raised.
COMM_FAILURE
exception that might be raised from a call to _bind()
, the client could write code as follows:
// Java // In file Client.java. package idl_demo; import IE.Iona.Orbix2.CORBA.SystemException; import IE.Iona.Orbix2.CORBA.COMM_FAILURE; public class Client { public static void main (String args[]) { _BankRef bRef; try { // Bind to bank with marker College_Green // in the BankSrv server. bRef = Bank._bind ("College_Green:BankSrv"); } catch (COMM_FAILURE cfe) { System.out.println ("Unexpected comm failure exception:"); System.out.println (cfe.toString ()); return; } catch (SystemException se) { System.out.println ("Unexpected system exception:"); System.out.println (se.toString ()); return; } // Continue here if no exception. ... } }Note that the handler for a specific system exception must appear before the handler for
SystemException
. In Java, catch
clauses are attempted in the order specified, and the first matching handler is called. Thus, a handler for SystemException
would match all system exceptions because of implicit casting (since all system exception classes are derived classes of SystemException
).To handle individual system exceptions as shown in the code fragment above, it is necessary to import the required exceptions from the
IE.Iona.Orbix2.CORBA
package. As an alternative, the exception classes could be referenced by fully scoped names.Note that if the programmer simply wishes to know the type of exception that occurred, then the message output by
toString()
on class SystemException
is sufficient. A handler for an individual exception is only required when specific action is to be taken if that exception occurs.
CORBAException
, which in turn inherits from java.lang.Exception
. Consequently, the rules for throwing OrbixWeb exceptions follow those for throwing standard Java exceptions: a programmer simply throws an object of the exception class.For example, to throw an exception of IDL type
Bank::Reject
, a programmer could simply do the following:
// Java throw new idl_demo._Bank.Reject ("Some reason");We use the automatically generated constructor of class
Reject
to initialise exception object's reason
member with the string "Some reason".The implementation of the
newAccount()
operation can now be coded as follows:
// Java // In file BankImplementation.java, // in package idl_demo, // in class BankImplementation. public _AccountRef newAccount(String name) throws _Bank.Reject, SystemException { _AccountRef acc = null; // Ensure that we do not already have an Account // for the given name, and if we are happy that // the name is okay, then: if (happyToProceed) { try { acc = new AccountImplementation (0, name); } catch (SystemException se) { // Details omitted. } record (name, acc); return acc; } else { // Throw a Reject exception. throw new Bank.Reject ("Bank is unhappy."); } }
SystemException
includes the method completed()
, which may be of use in some applications. This method returns an int
value that indicates how far the operation or attribute call progressed before the exception was raised. The return value must be one of three values defined in the OrbixWeb class CompletionStatus
(in package IE.Iona.Orbix2.CORBA
). These values are as follows: