Description
Example of my business method:
@Asynchronous public Future<AttachmentWBean> convertToPDF(File file, String contentType) throws FileConverterException, OperationCancelledException { final ConversionResultWBean wsResult = invokeFileConverterWS(file, contentType); return new AsyncResult<>(wsResult.getResultFile()); }
FileConverterException is checked exception while OperationCancelledException class is unchecked and declared as ApplicationException:
@ApplicationException public class OperationCancelledException extends RuntimeException { //... }
The reason is that org.apache.openejb.async.AsynchronousPool.FutureAdapter#handleException method does not check whether exception is an unchecked ApplicationException and always wrapps it into EJBException. Only checked exceptions are returned directly:
private void handleException(Throwable e) throws ExecutionException { //unwarp the exception to find the root cause while (e.getCause() != null) { e = e.getCause(); } /* * StatefulContainer.obtainInstance(Object, ThreadContext, Method) * will return NoSuchObjectException instead of NoSuchEJBException * * when it can't obtain an instance. Actually, the async client * is expecting a NoSuchEJBException. Wrap it here as a workaround. */ if (e instanceof NoSuchObjectException) { e = new NoSuchEJBException(e.getMessage(), (Exception) e); } final boolean isExceptionUnchecked = e instanceof Error || e instanceof RuntimeException; // throw checked excpetion and EJBException directly. if (!isExceptionUnchecked || e instanceof EJBException) { throw new ExecutionException(e); } // wrap unchecked exception with EJBException before throwing. throw e instanceof Exception ? new ExecutionException(new EJBException((Exception) e)) : new ExecutionException(new EJBException(new Exception(e))); }