First, I created my exceptions that extended RuntimeException. This resulted in all EJB methods that throw any unchecked exception wrapping the underlying exception in a EJBException, leading to lots and lots of ugly ejb.getCausedByException() calls, which I found to be flaky at best.
Finally, I found documentation on the @ApplicationException annotation in EJB 3 and figured this would be my savior. No such luck, they were still being wrapped in the base EJBException. After much head-scratching and googling, I came across a JBoss bug report saying that @ApplicationException is ignored in the cases where you build your EJB components into a separate jar file (which is about 98% of the time). Their solution was to add an ejb-jar.xml file with application-exceptions defined in them. So, trying this in Weblogic, still no worky. Grrr... One last thing, not sure why I did it, but out of pure stubbornness and inability to reconcile with those awful getCausedByException() calls, I made my exceptions extend EJBException instead of RuntimeException. Presto! No more wrapping.
So, in summary, to create an unchecked exception that will NOT be wrapped in an EJBException, do the following:
1) Create your exception class that extends EJBException.
2) Create an ejb-jar.xml file that looks somewhat like this to declare your application exceptions that you do not want to be wrapped in an EBException:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee | |
http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0"> | |
<assembly-descriptor> | |
<application-exception> | |
<exception-class> | |
com.blogspot.andrewshouldhave.UnwrappableUncheckedException | |
</exception-class> | |
<rollback>true</rollback> | |
</application-exception> | |
</assembly-descriptor> | |
</ejb-jar> |
And there you have it.