Updated: 10/1/03; 11:34:42 AM.
BC4J Helper by Sung Im
Thoughts on how BC4J works, code samples, and other helpful techniques
        

Friday, September 26, 2003

Handling Exceptions in 2 Tier vs. 3 Tier

Question

I created a class that implements oracle.jbo.JboExceptionHandler and I used the method setExceptionHandler to bind it to my ApplicationModule.  But the exceptions that occur in the BC4J are never caught by the JboExceptionHandler (the method handleException is never called).  In opposition, the handleWarning works when I call the addWarning method of the ApplicationModule.  In the documentation of JDeveloper I read that the handleException only works in three-tier application. What does it exactly mean?  How should I deploy my application to make it work.  How should I throw the Exception to make them catch by the ExceptionHandler?

Answer

In BC4J, a part of your application may run as a part of the middle tier (MT) app and another part may run asclient code that uses this middle tier app.

Even for the client code, the client code (depending on the deployment mode) may run in the same JVM as the middle tier app or in a separate JVM. In the latter case, the MT part needs to be deployed as EJB Session Bean.

If a part of you app is running in the same JVM as MT, when an exception is thrown from BC4J app-server code, the exception is thrown as a normal Java exception. This means that JVM will throw that back to you and your code needs to catch that exception if you want to process it.

If the client part of the app is running in a separate JVM (we refer to this as 3 tier), an exception (obviously) cannot be thrown across JVMs. Hence, in this configuration, we (BC4) package up the exceptions in the app-server and carry them to the client side.

Also, in this 3 tier configuration, more than one exception may have been thrown and packaged. When the exception info reaches CLI, we cannot simply throw the exception because there may be more than one.

This is where JboExceptionHandler comes in. In this case (3 tier), we call handleException method of JboExceptionHandler, notifying the client app with each exception.

Thus,

  • When the code runs in the same JVM as the MT code that throws the exception, you simply catch the exception in the normal Java way and process it.
  • When the code runs in a different JVM (client code in 3 tier), you need to process exception through JboExceptionHandler and handleException.

For warnings, there is no throw-catch mechanism supported by JVM. Hence, JboExceptionHandler's handleWarning is called in all cases (regardless of the JVM configuration or 2 tier vs. 3 tier).

There are times when you would write a client app code that can run in either 2 tier (same JVM as MT) or 3 tier. If you want your app to run equivalently in both configs, you need to do both: catch block for the 2 tier case, and JboExceptionHandler for the 3 tier case.

================================
Sample code below.
 
First define a class that implements oracle.jbo.JboExceptionHandler.
For example,
 
   public class myClass implements oracle.jbo.JboExceptionHandler

This class must implement the following methods as declared in the interface.
 
   void handleException(Exception ex, boolean lastEntryInPiggyback);
   void handleWarning(JboWarning warn);
   void finishedProcessingPiggyback(Exception[] exArray);
Get the Application Module on which you want to install this exception handler.
For example,
 
   ApplicationModule myAM;
 
   ... initialize myAM ...
 
   myAM.setExceptionHandler(this);
In your client code, suppose you want to handle exception raised when you
call myMethod().  Then, you would write code like:
 
   try
   {
      ...
      myMethod();
   }
   catch(Exception ex)
   {
      ... error handling code ...
   }
 
If you want to catch specific exception class, you may specify that in your
catch declaration.
 
When the application is running in 2 tier, if an exception is thrown while
myMethod() is being serviced, then the catch block is reached and your
exception handling as written in the catch block will execute.
 
In 3 tier execution, here is what happens.
 
Suppose some action in CLI causes a visit to middle tier app-server (MT).
 
It services the request.  This may result in multiple exceptions.  A
"record" of things that happened in MT is sent back to CLI in one network
packet.  This packet may contain many method calls and exceptions.
 
When the packet comes to CLI, it is unpacked and each method call/exception
is played back in CLI.
 
While doing so, if an exception entry is found, BC4J's CLI library will call
 
   void handleException(Exception ex, boolean lastEntryInPiggyback);
 
The 'lastEntryInPiggyback' is a flag indicating whether the exception entry
is the last one in the packet.
 
When done with processing all entries in the packet, 
 
   void finishedProcessingPiggyback(Exception[] exArray);
is called to give the user code a chance to handle exceptions in mass.
 
What if you don't install any JboExceptionHandler and run the app in 3 tier?
 
In this case, BC4J handles exception entries in the packet in the following
way.
 
After the packet is completely processed, it looks at the array of exceptions
(just as if finishedProcessingPiggyback() was called on your custom 
JboExceptionHandler).  Then, it throws the last exception of the array.
 
For uniform handling of exceptions, I would recommend the following:
 
Put your exception handling logic in a separate helper method.
 
For 2 tier, add a call to this helper method in your catch block.
 
For 3 tier, install your JboExceptionHandler.  You have a choice to
handle exceptions as they occur (one by one).  For this, you would
add code to call the helper method in handleException().
 
Or, you can handle them all at once.  For this, you would put the
handling logic in finishedProcessingPiggyback().
 
If you go with the handleException() approach, however, you must
remember not to throw any exception from within handleException().
If you do that it may short-circuit processing of the packet and
the CLI side state may no longer be in sync with MT.
 
In contrast, finishedProcessingPiggyback() may throw an exception.
 

9:42:15 AM    comment []



© Copyright 2003 Sung Im.
 
September 2003
Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        
Jul   Oct


Click here to visit the Radio UserLand website.

Subscribe to "BC4J Helper by Sung Im" in Radio UserLand.

Click to see the XML version of this web page.

Click here to send an email to the editor of this weblog.