If you use the following code, you'll get a JBAS014356 EJBException because the method is not public (and the Java compiler doesn't complain because it's in the same package).
package example;
@Stateless
@LocalBean
public class MyEjb {
void foo() {
System.out.println("Hello");
}
}
package example;
@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
@EJB MyEJb ejb
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ejb.foo();
}
}
If the method is declared @Asynchronous, the exception is swallowed leaving you wondering why you EJB method is got getting called at all.
An EJB method declared @Asynchronous void is a "fire and forget" method so dropping exceptions makes sense, since the EJB method itself should be handling any errors. If you want exceptions from the method propagated, using Future<Void> as the return type would be better. I'm not sure that's the case for container created exceptions that get thrown before the EJB code even runs, should they be reported to the called?
The current situation happens because the interceptor from AsyncFutureInterceptorFactory runs before NotBusinessMethodInterceptor. Would it be possible to move the latter earlier in the chain so it's reported, or would that break other things?