Understanding Orion Class Loading
September 29, 2003 on 1:38 pm | In Java | Add a commentThanks to an article on Atlassian describing how class-loading works in Orion application server, I was able to resolve a ClassNotFoundException error thrown by Class.forName(). As I found out, class-loading can present serious difficulties in a J2EE environment.
Technorati Tags: Atlassian, Orion, Application Server, Classloading, Java, J2EE
Related Posts:
- Java Artificial Neural Network
- EJB Exception Handling
- Character encoding in JSP/servlet
- The ridicule of web applications
On Failures and Exceptions
September 24, 2003 on 12:46 pm | In Java | Add a commentJames Gosling discusses failures and exceptions with Bill Venners on Artima. There is a lot of information to take away from the article, so do not miss it.
Technorati Tags: Java, James Gosling, Bill Venners, Artima, Failures, Exceptions
Related Posts:
- How to Handle Exceptions in EJB
- EJB Exception Handling
- Robust Java Exception Handling
- National Health Card Project in Brazil
Mac OS X 10.2.8
September 23, 2003 on 10:32 am | In Apple | Add a commentMac OS X 10.2.8 has been released. Read the release notes.
Technorati Tags: Mac OS X, Update, Release Notes
Related Posts:
- Gnome 2.6
- Apple releases Mac OS X 10.4.7 update
- Boot Camp for Mac OS X on Intel-based Macs
- NetBeans 4.1 Final Release available for download
EJB Exception Handling
September 3, 2003 on 9:36 pm | In Java | 23 commentsIntroduction
It is amazing that there are only so few resources [on the Internet] that show how to handle exceptions in EJB. A search on Google returns a large number of results, but almost all of these point to the same article on IBM DeveloperWorks. This shows how scarce information about this subject are. The alternative, of course, is to refer to the J2EE specifications, but the its sheer volume and jargon can be intimidating for someone wanting to learn the basics.
After foraging the Internet and reading various books, I managed to compile my own documentation that I present in this article.
Definitions
First, let us start with some basic definitions that will make it easier for the reader to understand the article.
A checked exception is one that is derived from java.lang.Exception, but is not a subclass of java.lang.RuntimeException.
An unchecked exception is one that is derived from java.lang.RuntimeException and is thrown by the Java Virtual Machine (JVM).
A system exception is one that is thrown by the system and is not recoverable. For example, an EJB container losing its connection to a database server causes a system exception. Similarly, a failed remote object method call causes a system exception.
An application exception is one that is specific to the application and is thrown due to a violation of the application business rules. therefore, an application exception must be determining for the client to know how to handle it. Such an exception is raised, for example, when the balance for a savings account becomes negative.
System Exception
System exceptions are unchecked and, by extension, are derived from java.lang.RuntimeException. Because it is nearly impossible for developers to predict their occurrences, the EJB container is the only one that is responsible for trapping system exceptions. The container automatically swallows (or wraps) an EJBException in a RemoteException that is subsequently thrown to the client. The wrapping process discards some information about the error, but the RemoteException remains sufficient since the client does not need to know about the specific erros that occurred (because they are system errors) and are unable to fix them anyway.
In addition to intercepting system exceptions, the container, depending on the implementation, may log errors.
From the above, it is now clear that if developers want system exceptions to be managed properly by the container and propagated to the client, they need to wrap them in EJBException that can be intercepted. The following code extract illustrates this point.
...
public String ejbCreate(String id, String username, String password)
throws CreateException {
try {
this.id = id;
this.username = username;
this.password = password;
insertRecord();
} catch (SQLException e) {
throw new EJBException(e); // swallow the SQLException
} catch (Exception e) {
throw new EJBException(e);
}
return id;
}
...
Note that since an EJBException is a system (and unchecked) exception, there is no need to declare it in the throws clause.
create(...) is a delegate method of the Home object created by the container. Also, the container will throw a RemoteException if the method fails due to a system error. Therefore, in the Home interface of our remote object, we declare that the create(...) method throws RemoteException, like this:
...
public UserAccount create(String id, String username, String password)
throws RemoteException;
...
The client code will then look like this:
...
try {
UserAccount userAccount =
userAccountHome.create("1001", "user", "password");
} catch (CreateException e) {
System.out.println("Object could not be created");
} catch (RemoteException e) {
System.out.println("EJB Error: " + e.getMessage() );
} catch (Exception e) {
e.printStackTrace();
}
...
In this example, the container notifies the client about a system exception by means of the RemoteException.
Application Exception
Application exceptions are checked and, therefore, need to be declared in a throws clause. They are thrown explicitly by code to indicate that a breach of the business rules has occurred. For example, trying to debit a sum of money that will make a savings account balance negative triggers a SavingsAccountDebitException. Because of their purpose, application exceptions are relied upon by the client to determine the cause of the error and send the proper notification to the end-user. Because the EJB container does not know how to process an application-specific exception, it does not intercept any. Also, application exceptions are not logged by the container.
Developers need not wrap such an exception in an EJBException. In fact, to prevent the container from hi-jacking the exception, developers SHOULD NOT write code to swallow the exception.
Below is a code extract that shows a typical application exception handling.
...
public void debit(double amount)
throws SavingsAccountDebitException {
if (this.balance == 0) {
throw new SavingsAccountDebitException(
"Cannot make a debit");
}
try {
balance -= amount;
updateRecord();
} catch (SQLException e) {
throw new EJBException(e);
} catch (Exception e) {
throw new EJBException(e);
}
}
...
Again, notice that even if an EJBException is thrown in the code, it needs not be declared in the throws clause. Also, this code does not demonstrate how transactions are rolled back, a topic which is covered further down in this article.
In the remote interface for the bean containing the above code, SavingsAccountDebitException must be declared, as in the following:
...
public void debit(double amount)
throws SavingsAccountDebitException;
...
The client code using the remote interface may then look like this:
...
try {
savingsAccount.debit(1000.00);
} catch (SavingsAccountDebitException e) {
System.out.println(e.getMessage() );
} catch (Exception e) {
e.printStackTrace();
}
...
As can be seen, the application exception has been successfully propagated to the client without being intercepted by the container. The client uses the information from the exception to notify the end-user; in this example, it simply displays the error message.
Exceptions and Transactions
The way that exceptions are handled affects the way transactions are managed
When a transaction is managed by the container, it is automatically rolled back by the latter when a system exception occurs. This is possible because the container can intercept this type of exceptions. However, when an application exception occurs, the container does not intercept it and, therefore, leaves it to the code to roll back the transaction.
The following code extract illustrates this point.
...
EntityContext ctx;
...
public void ejbRemove()
throws RemoveException {
try {
deleteRecord();
} catch (SavingsAccountDeleteException e) {
ctx.setRollbackOnly()
throw new RemoveException(e.getMessage() );
} catch (SQLException e) {
throw new EJBException(e);
} catch (Exception e) {
throw new EJBException(e);
}
}
...
Conclusion
I should point that the article mostly applies to remote EJB. When local EJB are used, RemoteException is never thrown.
As demonstrated, handling exceptions in EJB can be very different from what is done in standalone Java applications. In fact, the guidelines for dealing with each situation can be contradictory in some cases. For a comparison, please refer to my previous article, Exception Handling Best Practice.
To conclude, here are the four basic rules that, I believe, suffice to properly handle exceptions in EJB.
- If you cannot recover from a system exception, let the container handle it.
- If a business rule is violated, throw an application exception.
- Catch exceptions in the order in which you can handle them. Alternatively, catch them in descending order of likelihood of them occurring.
- Always catch a java.lang.Exception last.
Technorati Tags: Java, Exception+Handling
Related Posts:
- How to Handle Exceptions in EJB
- How to Format Dates for SQL in Java
- Exception handling or result code
- Robust Java Exception Handling
Arbitrary sort of selection options
September 2, 2003 on 8:45 pm | In General | Add a comment_Problem_
Very often, options that are displayed in a selection control (drop-down list or simple list) need to be sorted in a logical order that is relevant to the business domain rather than in alpha-numerical order.
Let us take the lookup values for the status of a sale as an example. Usually, they have to be sorted in the order in which the status changes, as shown below:
# Preparation
# Marketing
# Negotiation
# Closed
A _simplistic_ database table that is used to store these lookup values typically consists of only two fields: ID and Description. Suppose such a table, *StatusLookup*, has the following structure:
ID CHAR(4)
Description CHAR(25)
The *ID* field is of type _CHAR_ and is a foreign key (FK) in referencing records. The choice of datatype and size for this field is driven by the desire to have meaningful values in it. So, _PREP_ stands for _Preparation_ status, _MKTG_ for _Marketing_, NEGO for _Negotiation_ and _CLOS_ for _Closed_.
The *Description* field holds the caption for each option that will be displayed in the selection control.
As can be seen, sorting by either the id or the description does not yield the result we expect, that is, a logical order. One solution would be to replace the meaningful ids with values that would produce the order we wish to achieve when sorted by the *ID* field. Doing so, however, negates our effort to have values that can be easily identified.
_Solution_
The better solution is to add a new field to the table; it contains values that are arbiitrarily defined to produce the sort order we desire. So, our new table structure becomes:
ID CHAR(4)
Description CHAR(25)
Sequence INT
We fill in the *Sequence* field with integer values; when sorted by this field, the logical order should be the one we want to achieve. A typical table will be as follows:
|*ID*|*Description*|*Sequence*|
|CLOS|Closed|4|
|MKTG|Marketing|2|
|NEGO|Negotiation|3|
|PREP|Preparation|1|
The SQL statement or stored-procedure that we use to get the lookup values is as follows:
select ID, Description from StatusLookup order by Sequence
The recordset that contains the results returned from this query can be iterated through sequentially; the fields of each row are used to generate each option in the selection control. Thus, our goal to logically sort the lookup values is achieved.
Related Posts:
- Validating a Date Field with RIFE
- How to use multiple triggers in RIFE
- wxWidgets time control
- IM Online Status Indicators
Powered by blog.mu with Pool theme design by Borja Fernandez.

