{"id":11,"date":"2003-09-03T21:36:49","date_gmt":"2003-09-04T02:36:49","guid":{"rendered":"http:\/\/coding.mu\/index.php\/archives\/2003\/09\/03\/ejb-exception-handling\/"},"modified":"2025-11-06T18:51:14","modified_gmt":"2025-11-06T18:51:14","slug":"ejb-exception-handling","status":"publish","type":"post","link":"https:\/\/priscimon.net\/coding\/2003\/09\/03\/ejb-exception-handling\/","title":{"rendered":"EJB Exception Handling"},"content":{"rendered":"\n<p>If you do a web search for the keywords &#8220;EJB&#8221; and &#8220;exception&#8221;, you&#8217;ll find the same handful of articles published at IBM DeveloperWorks. Those are, unfortunately, not suitable for beginners. This post is a simpler guide to handling exceptions in EJB.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Definitions<\/strong><\/h2>\n\n\n\n<p>A <em>checked exception<\/em> is derived from <strong>java.lang.Exception<\/strong> but is not a subclass of <strong>java.lang.RuntimeException<\/strong>.<\/p>\n\n\n\n<p>An <em>unchecked exception<\/em> is derived from <strong>java.lang.RuntimeException<\/strong> and is thrown by the Java Virtual Machine (JVM).<\/p>\n\n\n\n<p>A <em>system exception<\/em> 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.<\/p>\n\n\n\n<p>An <em>application exception<\/em> is specific to the application and is thrown to signal a business rule that is not satisfied. For example, an application exception is raised when the balance for a savings account becomes negative.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>System Exception<\/strong><\/h2>\n\n\n\n<p>A system exception is unchecked and is derived from <strong>java.lang.RuntimeException<\/strong>. Because it is unpredictable, it is typically not handled in application code and is handled instead by the EJB container.<\/p>\n\n\n\n<p>A container automatically wraps an <strong>EJBException<\/strong> in a <strong>RemoteException<\/strong> and throws it to the client. Although this causes some information to be lost, it is not a problem because a <strong>RemoteException<\/strong> is a system error from which the client cannot recover.<\/p>\n\n\n\n<p>Therefore, for an exception to be caught by the container and sent to the client, a developer must wrap it in an <strong>EJBException. <\/strong>The following code extract demonstrates this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\npublic String ejbCreate(String id, String username, String password) \n    throws CreateException {\n\n    try {\n        this.id = id;\n        this.username = username;\n        this.password = password;\n\n        insertRecord();\n    } catch (SQLException e) {\n        throw new EJBException(e); \/\/ swallow the SQLException\n    } catch (Exception e) {\n        throw new EJBException(e);\n    }\n    return id;\n}\n...<\/code><\/pre>\n\n\n\n<p>Since an <strong>EJBException<\/strong> is a system (and unchecked) exception, it does not\u00a0 have to be declared in the <code>throws<\/code> clause.<\/p>\n\n\n\n<p><code>create(...)<\/code> is a delegate method of the <em>Home<\/em> object created by the container, and if the method fails due to a system error, the container throws a <strong>RemoteException<\/strong>. Therefore, in the <em>Home<\/em> interface of the remote object, the <code>create(...)<\/code> method must throw <strong>RemoteException<\/strong>, like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\npublic UserAccount create(String id, String username, String password) \n    throws RemoteException;\n...<\/code><\/pre>\n\n\n\n<p>The client code then looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\ntry {\n    UserAccount userAccount = \n        userAccountHome.create(\"1001\", \"user\", \"password\");\n} catch (CreateException e) {\n    System.out.println(\"Object could not be created\");\n} catch (RemoteException e) {\n    System.out.println(\"EJB Error: \" + e.getMessage() );\n} catch (Exception e) {\n    e.printStackTrace();\n}\n...<\/code><\/pre>\n\n\n\n<p>In this example, the container notifies the client about a system exception by way of the <strong>RemoteException<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Application Exception<\/strong><\/h2>\n\n\n\n<p>An application exception is checked and, therefore, must be declared in a <code>throws<\/code> clause. It is thrown explicitly by code to indicate an error linked to the business rules. For example, debiting a sum of money that makes a savings account balance go negative triggers a <strong>SavingsAccountDebitException<\/strong>. An application exception is needed for a client to be alerted of an error, to determine what caused it, and to notify users. An EJB container does not intercept an application exception because it does not know how to handle it. Consequently, the container does not log an application exception be default.<\/p>\n\n\n\n<p>A developer does not need to wrap such an application exception in an <strong>EJBException<\/strong>. In fact, to prevent the container from <em>hi-jacking<\/em> the exception, a developer must not do this.<\/p>\n\n\n\n<p>Below is a code extract that shows a typical application exception handling.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\npublic void debit(double amount) \n    throws SavingsAccountDebitException {\n\n    if (this.balance == 0) {\n        throw new SavingsAccountDebitException(\n            \"Cannot make a debit\");\n    }\n\n    try {\n        balance -= amount;\n        updateRecord();\n    } catch (SQLException e) {\n        throw new EJBException(e);\n    } catch (Exception e) {\n        throw new EJBException(e);\n    }\n}\n...<\/code><\/pre>\n\n\n\n<p>Notice that when an <strong>EJBException<\/strong> is thrown, it can be left out in the <code>throws<\/code> clause. Also, this code does not demonstrate how transactions are rolled back, a topic which is covered later in this post.<\/p>\n\n\n\n<p>In the remote interface for the bean containing the above code, a throws clause declaring <strong>SavingsAccountDebitException<\/strong> is needed, as in the following.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\npublic void debit(double amount) \n    throws SavingsAccountDebitException;\n...<\/code><\/pre>\n\n\n\n<p>The client code using the remote interface could look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\ntry {\n    savingsAccount.debit(1000.00);\n} catch (SavingsAccountDebitException e) {\n    System.out.println(e.getMessage() );\n} catch (Exception e) {\n    e.printStackTrace();\n}\n...<\/code><\/pre>\n\n\n\n<p>Observe that the application exception is successfully propagated to the client and is ignored by the container. The client uses the information from the exception to notify users; in this example, it displays an error message.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Exceptions and Transactions<\/strong><\/h2>\n\n\n\n<p>How transactions are managed is affected by how exceptions are handled.<\/p>\n\n\n\n<p>A transaction managed by the container is automatically rolled back when a system exception occurs. This happens because the container intercepts system exceptions. However, when an application exception occurs, the container does not intercept it and, therefore, does not roll back a transaction.<\/p>\n\n\n\n<p>The following code extract illustrates this point.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\nEntityContext ctx;\n...\npublic void ejbRemove() \n    throws RemoteException {\n    try {\n        deleteRecord();\n    } catch (SavingsAccountDeleteException e) {\n        ctx.setRollbackOnly()\n        throw new RemoveException(e.getMessage() );\n    } catch (SQLException e) {\n        throw new EJBException(e);\n    } catch (Exception e) {\n        throw new EJBException(e);\n    }\n}\n...<\/code><\/pre>\n\n\n\n<p><strong>Conclusion<\/strong><\/p>\n\n\n\n<p>This post applies to <em>remote<\/em> EJB; when <em>local<\/em> EJB is used, <strong>RemoteException<\/strong> is never thrown.<\/p>\n\n\n\n<p>As shown, handling exceptions in EJB is different to how it 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 the post <a href=\"http:\/\/coding.moris.org\/archives\/000300.html\">Exception Handling Best Practice<\/a>.<\/p>\n\n\n\n<p>These are the four rules to follow for proper handling of exceptions in EJB:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If you cannot recover from a system exception, let the container handle it.<\/li>\n\n\n\n<li>If a business rule is violated, throw an application exception.<\/li>\n\n\n\n<li>Catch exceptions in the order in which you can handle them. Alternatively, catch them in descending order of likelihood of them occurring.<\/li>\n\n\n\n<li>Always catch a <strong>java.lang.Exception<\/strong> last.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>If you do a web search for the keywords &#8220;EJB&#8221; and &#8220;exception&#8221;, you&#8217;ll find the same handful of articles published at IBM DeveloperWorks. Those are, unfortunately, not suitable for beginners. This post is a simpler guide to handling exceptions in EJB. Definitions A checked exception is derived from java.lang.Exception but is not a subclass of [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-11","post","type-post","status-publish","format-standard","hentry","category-general"],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3I4g9-b","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/priscimon.net\/coding\/wp-json\/wp\/v2\/posts\/11","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/priscimon.net\/coding\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/priscimon.net\/coding\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/priscimon.net\/coding\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/priscimon.net\/coding\/wp-json\/wp\/v2\/comments?post=11"}],"version-history":[{"count":9,"href":"https:\/\/priscimon.net\/coding\/wp-json\/wp\/v2\/posts\/11\/revisions"}],"predecessor-version":[{"id":2018,"href":"https:\/\/priscimon.net\/coding\/wp-json\/wp\/v2\/posts\/11\/revisions\/2018"}],"wp:attachment":[{"href":"https:\/\/priscimon.net\/coding\/wp-json\/wp\/v2\/media?parent=11"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/priscimon.net\/coding\/wp-json\/wp\/v2\/categories?post=11"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/priscimon.net\/coding\/wp-json\/wp\/v2\/tags?post=11"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}