Uploaded image for project: 'OpenEJB'
  1. OpenEJB
  2. OPENEJB-2111

Unchecked application exceptions, thrown in asynchronous business methods, are always wrapped in EJBException

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 4.7.1
    • 4.7.2
    • ejb31, tomee
    • None

    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)));
      
      }
      

      Attachments

        Activity

          People

            romain.manni-bucau Romain Manni-Bucau
            abyss Petras
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: