I think whether you can throw an exception is not decided by the type of bean
the term "Application Exception" in EJB 3 means :
(1) "Checked Exception" (i.e subclass of Exception) may or may not defined using @ApplicationException
OR
(2) "Unchecked Exception" (i.e subclass of RuntimeException or Error) , only RuntimeException can be defined as an application exception using @ApplicationException (otherwise it is a system exception if not defined using @ApplicationException)
BUT cannot be subclass of java.rmi.RemoteException
================
whether you can throw an exception is decided by the basic rules of exception handling
Rules:
(1) Checked Exception
~ either declare it in the throws clause of your method or catch it in the body of your method
(2) RuntimeException which is defined as an application exception using @ApplicationException
~ either declare it in the throws clause of your method or catch it in the body of your method
(3) RuntimeException which is not defined as an application exception
~ is a normal RuntimeException which not need to be declare in throws clause or catch
(4) RemoteException
~ if your bean interface using @Remote without extends java.rmi.Remote interface, method define in the bean interface does not need to declare RemoteException in the throws clause. In this case, container throws EJBTransactionRollbackException or EJBException depends on the transaction context (refer to EJB Core spec 14.3)
~ if your bean interface extends java.rmi.Remote interface, method define in the bean interface MUST declare RemoteException in the throws clause. In this case container throws TransactionRollbackException or RemoteException depends on the transaction context (refer to EJB Core spec 14.3)
================
so what
you should not confuse is the mess between
(a) bean method can throw which exception ?
(b) container can throw which exception ?
================
The onMessage() method can throw only RuntimeExceptions therefore bean provider may throw an @ApplicationException which is the java.lang.RuntimeException.
I can confirm that onMessage() can throw Unchecked Exception (RuntimeException and Error) , since this type of exception does not need to be declare in throws clause of onMessage() and does not need to be catch
From my studying, if a RuntimeExceptions that is defined as application exception using @ApplicationException, that exception need to be either declare in the throws clause of the bean method or catch in the bean method. As referring to the rules of exception handling that "you cannot throw any checked Exceptions other than those declared in the method you are overriding", so in your bean class which override the onMessage() method cannot declare additional exception in the throws clause, so if inside the onMessage() method do receive a ducking application exception from the method invoked from onMessage() method, it need to be catch. Am I right ?