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

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 4.7.1
    • Fix Version/s: 4.7.2
    • Component/s: ejb31, tomee
    • Labels:
      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

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

              Dates

              • Created:
                Updated:
                Resolved: