public static Class<?>[] getCheckedExceptions(Method method,
                                                  boolean isRmiRemote,
                                                  DeploymentTarget target,
                                                  EJBWrapperType wrapperType,
                                                  boolean declaredUncheckedAreSystemExceptions,
                                                  boolean declaredRemoteAreApplicationExceptions)
                    throws EJBConfigurationException
    {
        boolean throwsRemoteException = false;
        Class<?>[] exceptions = method.getExceptionTypes();
        int numExceptions = exceptions.length;
        ArrayList<Class<?>> checkedExceptions = new ArrayList<Class<?>>(numExceptions);

        for (Class<?> exception : exceptions)
        {
            // --------------------------------------------------------------------
            // Only Remote interfaces that implement java.rmi.Remote may throw
            // java.rmi.RemoteException.
            // --------------------------------------------------------------------
            if (exception == RemoteException.class)
            {
                if (!isRmiRemote)
                {
                    // This is only a warning since the spec says 'should' and not
                    // must... but let them know it is a bad idea.            d450525
                    Tr.warning(tc, "JIT_INVALID_THROW_REMOTE_CNTR5101W",
                               new Object[] { method.getName(),
                                             method.getDeclaringClass().getName() });
                }
                throwsRemoteException = true;
                continue; // skip - remote allowed, but not 'checked' exception
            }

            // --------------------------------------------------------------------
            // Application exceptions must not subclass RemoteException.
            // --------------------------------------------------------------------
            else if ((RemoteException.class).isAssignableFrom(exception))
            {
                // Tolerate for stubs since the server EJB might allow.    RTC116527
                if (target == DeploymentTarget.STUB)
                {
                    // Keep the exception.
                }
                // For tie/wrapper, only allow if a custom property is specified and
                // only then for business interfaces.                      RTC116527
                else if (declaredRemoteAreApplicationExceptions &&
                         (wrapperType == null ||
                          wrapperType == EJBWrapperType.BUSINESS_REMOTE ||
                         wrapperType == EJBWrapperType.BUSINESS_LOCAL))
                {
                    // Keep the exception.
                }
                else
                {
                    // Log the error and throw meaningful exception.             d450525
                    String className = method.getDeclaringClass().getName();
                    Tr.error(tc, "JIT_INVALID_SUBCLASS_REMOTE_EX_CNTR5102E",
                             new Object[] { exception.getName(),
                                           method.getName(),
                                           className });
                    throw new EJBConfigurationException("Application exception " + exception.getName() +
                                                        " defined on method " + method.getName() + " of interface " +
                                                        className + " must not subclass java.rmi.RemoteException.");
                }
            }

            // --------------------------------------------------------------------
            // Per the spec, unchecked exceptions (RuntimeException and Error)
            // should not be considered application.  They are also ignored by
            // rmic when generating stubs and ties.                         d660332
            // --------------------------------------------------------------------
            else if (RuntimeException.class.isAssignableFrom(exception) ||
                     Error.class.isAssignableFrom(exception)) // 651626.1
            {
                // For stubs, we keep unchecked exceptions so that they can handle
                // IDL strings from ties generated by previous releases where
                // unchecked exceptions were not filtered.
                if (target == DeploymentTarget.STUB)
                {
                    // Keep the exception.
                }
                // For wrappers, we keep unchecked exceptions if the user has
                // indicated that unchecked exceptions should be considered
                // application exceptions.
                else if (target == DeploymentTarget.WRAPPER &&
                         !declaredUncheckedAreSystemExceptions)
                {
                    // Keep the exception.
                }
                else
                {
                    // Remove the exception.
                    continue;
                }
            }
            else if (!Exception.class.isAssignableFrom(exception)) // d608631
            {
                String className = method.getDeclaringClass().getName();
                Tr.error(tc, "JIT_INVALID_NOT_EXCEPTION_SUBCLASS_CNTR5107E",
                         new Object[] { exception.getName(),
                                       method.getName(),
                                       className });

                throw new EJBConfigurationException("The " + exception.getName() +
                                                    " application exception defined on the " + method.getName() +
                                                    " method of the " + className +
                                                    " class must be defined as a subclass of the java.lang.Exception class.");
            }

            // --------------------------------------------------------------------
            // Exception is a valid application exception... but it cannot just
            // be added to the end of the list, since it may be a subclass of
            // other exceptions on the throws clause, which could result in
            // 'unreachable' code when adding 'catch' blocks.
            //
            // Instead, do one of two things:
            // 1 - Remove any exceptions that are subclasses of other exceptions.
            //     This is useful when a catch block is being added for each
            //     checked exception, and the processing done in the parent
            //     exception would be the same as any subclasses.  For example,
            //     in a generated wrapper, catch blocks for all checked exceptions
            //     just call 'setCheckedException'... so no need to duplicate that
            //     for all subclass exceptions.
            // 2 - Insert the current exception ahead of the first exception
            //     already in the list that is a parent.  This eliminates the
            //     'unreachable' code problem, and also ends up with the
            //     exceptions in the original order if there are no subclasses.
            // --------------------------------------------------------------------

            if (target == DeploymentTarget.WRAPPER) // d660332
            {
                // -----------------------------------------------------------------
                // Remove any already added exceptions that are subclasses of the
                // current exception.  Ignore the current exception if a superclass
                // has already been added.                                 RTC116527
                // -----------------------------------------------------------------
                boolean add = true;
                for (Iterator<Class<?>> iter = checkedExceptions.iterator(); iter.hasNext();)
                {
                    Class<?> checkedEx = iter.next();
                    if (exception.isAssignableFrom(checkedEx))
                    {
                        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                            Tr.debug(tc, "getCheckedExceptions: ignoring " +
                                         checkedEx.getName() + ", subclass of " +
                                         exception.getName());
                        iter.remove();
                    }
                    else if (checkedEx.isAssignableFrom(exception))
                    {
                        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                            Tr.debug(tc, "getCheckedExceptions: ignoring " +
                                         exception.getName() + ", subclass of " +
                                         checkedEx.getName());
                        add = false;
                        break;
                    }
                }

                if (add)
                {
                    checkedExceptions.add(exception);
                }
            }
            else
            {
                // -----------------------------------------------------------------
                // Sort exceptions, so that subclasses are ahead of parents
                // -----------------------------------------------------------------
                int j;
                int numChecked = checkedExceptions.size();
                for (j = 0; j < numChecked; ++j)
                {
                    Class<?> checkedEx = checkedExceptions.get(j);
                    if (checkedEx.isAssignableFrom(exception))
                        break;
                }

                checkedExceptions.add(j, exception);
            }
        }

        // -----------------------------------------------------------------------
        // After all exceptions have been processed, make sure that a
        // RemoteException was present if the interface implements java.rmi.Remote
        // -----------------------------------------------------------------------
        if (isRmiRemote && !throwsRemoteException)
        {
            // Log the error and throw meaningful exception.                d450525
            String className = method.getDeclaringClass().getName();
            Tr.error(tc, "JIT_MISSING_REMOTE_EX_CNTR5104E",
                     new Object[] { method.getName(), className });
            throw new EJBConfigurationException("Method " + method.getName() + " of interface " + className +
                                                " must throw java.rmi.RemoteException");
        }

        return checkedExceptions.toArray(new Class[checkedExceptions.size()]);
    }
public static Class < ? > [ ] getCheckedExceptions ( Method method , boolean isRmiRemote , DeploymentTarget target , EJBWrapperType wrapperType , boolean declaredUncheckedAreSystemExceptions , boolean declaredRemoteAreApplicationExceptions ) throws EJBConfigurationException { boolean throwsRemoteException = false ; Class < ? > [ ] exceptions = method . getExceptionTypes ( ) ; int numExceptions = exceptions . length ; ArrayList < Class < ? > > checkedExceptions = new ArrayList < Class < ? > > ( numExceptions ) ; for ( Class < ? > exception : exceptions ) { if ( exception == RemoteException . class ) { if ( ! isRmiRemote ) { Tr . warning ( tc , "JIT_INVALID_THROW_REMOTE_CNTR5101W" , new Object [ ] { method . getName ( ) , method . getDeclaringClass ( ) . getName ( ) } ) ; } throwsRemoteException = true ; continue ; } else if ( ( RemoteException . class ) . isAssignableFrom ( exception ) ) { if ( target == DeploymentTarget . STUB ) { } else if ( declaredRemoteAreApplicationExceptions && ( wrapperType == null || wrapperType == EJBWrapperType . BUSINESS_REMOTE || wrapperType == EJBWrapperType . BUSINESS_LOCAL ) ) { } else { String className = method . getDeclaringClass ( ) . getName ( ) ; Tr . error ( tc , "JIT_INVALID_SUBCLASS_REMOTE_EX_CNTR5102E" , new Object [ ] { exception . getName ( ) , method . getName ( ) , className } ) ; throw new EJBConfigurationException ( "Application exception " + exception . getName ( ) + " defined on method " + method . getName ( ) + " of interface " + className + " must not subclass java.rmi.RemoteException." ) ; } } else if ( RuntimeException . class . isAssignableFrom ( exception ) || Error . class . isAssignableFrom ( exception ) ) { if ( target == DeploymentTarget . STUB ) { } else if ( target == DeploymentTarget . WRAPPER && ! declaredUncheckedAreSystemExceptions ) { } else { continue ; } } else if ( ! Exception . class . isAssignableFrom ( exception ) ) { String className = method . getDeclaringClass ( ) . getName ( ) ; Tr . error ( tc , "JIT_INVALID_NOT_EXCEPTION_SUBCLASS_CNTR5107E" , new Object [ ] { exception . getName ( ) , method . getName ( ) , className } ) ; throw new EJBConfigurationException ( "The " + exception . getName ( ) + " application exception defined on the " + method . getName ( ) + " method of the " + className + " class must be defined as a subclass of the java.lang.Exception class." ) ; } if ( target == DeploymentTarget . WRAPPER ) { boolean add = true ; for ( Iterator < Class < ? > > iter = checkedExceptions . iterator ( ) ; iter . hasNext ( ) ; ) { Class < ? > checkedEx = iter . next ( ) ; if ( exception . isAssignableFrom ( checkedEx ) ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) Tr . debug ( tc , "getCheckedExceptions: ignoring " + checkedEx . getName ( ) + ", subclass of " + exception . getName ( ) ) ; iter . remove ( ) ; } else if ( checkedEx . isAssignableFrom ( exception ) ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) Tr . debug ( tc , "getCheckedExceptions: ignoring " + exception . getName ( ) + ", subclass of " + checkedEx . getName ( ) ) ; add = false ; break ; } } if ( add ) { checkedExceptions . add ( exception ) ; } } else { int j ; int numChecked = checkedExceptions . size ( ) ; for ( j = 0 ; j < numChecked ; ++ j ) { Class < ? > checkedEx = checkedExceptions . get ( j ) ; if ( checkedEx . isAssignableFrom ( exception ) ) break ; } checkedExceptions . add ( j , exception ) ; } } if ( isRmiRemote && ! throwsRemoteException ) { String className = method . getDeclaringClass ( ) . getName ( ) ; Tr . error ( tc , "JIT_MISSING_REMOTE_EX_CNTR5104E" , new Object [ ] { method . getName ( ) , className } ) ; throw new EJBConfigurationException ( "Method " + method . getName ( ) + " of interface " + className + " must throw java.rmi.RemoteException" ) ; } return checkedExceptions . toArray ( new Class [ checkedExceptions . size ( ) ] ) ; }
d413752.1 d413752.2