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: