Due to preparation for the exam I refreshed the exception handling in EJBs and read the EJB2.0 specs. The spec makes a different between application and system exceptions. It states that a Bean Provider should use application exceptions only for business type of errors (e.g. limit exceeded) and not for system level problems (e.g. jndi, sql, io ... exceptions). Only system exceptions cause a rollback by the ejb container. BTW: this may break older code relying on all exceptions causing a rollback. Now I'm a little bit confused about how the exception handling should be implemented in your beans properly. Is it really the goal to catch all system like exceptions (SQLException, IOException, JMSException ...) and wrap them into your own Exception inherited from java.lang.RuntimeException or throw a javax.ejb.EJBException? Im thinking about how to inform an ebj client of what happened and what can happen by using an ejb. The system exceptions are java.lang.RuntimeExceptions and therefor unchecked and not declared in the remote interfaces. Is there a best practice of exception handling around? How are you implementing the exception handling in your beans? And there is always the issue about logging and preserving the full stacktrace. There have been some interesting discussions around about checked and unchecked exceptions. http://www.theserverside.com/home/thread.jsp?thread_id=19192&article_count=114 http://www.mindview.net/Etc/Discussions/CheckedExceptions Does this mean that SUN is turning to unchecked exceptions for technical exceptions? Are the checked exceptions of the lower level APIs (JMSException, SQLException, ...) a design mistake from the past? Ok, this questions is not really relevant to the SCBCD (you just learn whats in the specs), but I belive we shouldn't lose the implementation out of sight.
we catch checked exceptions within our code and 1.log it, 2.mark the transaction for rollback using setRollbackOnly(), 3.Wrap it in a generic Application Exception we have defined for the application and re-throw it back to the client. Since we use application exceptions they have to be declared in the throws clause. So the client knows about it. The client can extract the actual exception from the App exception. We dont do anything with the runtime exceptions. They just propogate as it is to the container. I guess even ejb spec recommends this. I think this is a commonly followed practice. The web tier handles such exceptions and displays a decent error message to the client.
1.log it, 2.mark the transaction for rollback using setRollbackOnly(), 3.Wrap it in a generic Application Exception we have defined for the application and re-throw it back to the client.
That's similar to that how we handle exceptions, but the spec says somethin else: Application Exceptions: "Enterprise bean business methods use application exceptions to inform the client of abnormal application- level conditions, such as unacceptable values of the input arguments to a business method. A client can typically recover from an application exception. Application exceptions are not intended for reporting system-level problems." System Exceptions: "Examples of such exceptions and errors are: failure to obtain a database connection, JNDI exceptions, unexpected RemoteException from invocation of other enterprise beans, unexpected RuntimeException, JVM errors, and so on." and "If the bean method performs an operation that results in a checked exception that the bean method cannot recover, the bean method should throw the javax.ejb.EJBException that wraps the original exception." (The EJBException is a subclass of RuntimeException and therefor unchecked.)
The last quote from the spec is what I'm curios about.