We've been trying to figure out how the new JTA transactional interceptor
support should interact with EJBs. Here's some options we've considered:
1. The new transaction annotations are not allowed to be used on EJBs.
This error would be detected at deployment time.
2. The new transaction annotations have no effect when used on EJBs.
This would likely be very surprising to users.
3. The EJB container does not understand the new transaction annotations
at all and behaves the same with regard to the exceptions that are thrown
as it would if the application were to throw the same exceptions in
an EJB that was not annotated with the new transaction annotations.
The exceptions the EJB container sees at point B above are handled
the same as they would be if CDI were removed from the picture.
The EJB container does exception wrapping and transaction rollback
based only on its existing rules, including use of the existing
EJB @ApplicationException annotation. At point A the application
sees exceptions that might be wrapped in the normal EJB way.
Note that the EJB container will be performing its normal CMT
behavior, including the default transaction attribute of REQUIRES
and the normal EJB exception wrapping behavior. If the EJB Bean
wants to use the new JTA transaction annotations it will likely want
to disable the EJB CMT support by specifying an EJB transaction
attribute of SUPPORTS (which means the EJB container will never
start a transaction itself and will pass through any existing
transaction context).
4. Like #3, but the EJB container understands both the existing
EJB @ApplicationException annotation as well as any new such
annotation defined by JTA. This changes which exceptions will
be wrapped before returning to the application, and what will
happen to any transaction that the EJB container might have started.
And like #3, the application will likely want to disable EJB CMT
by specifying an EJB transaction attribute of SUPPORTS.
5. Like #4, but the EJB container also detects the use of the new
JTA transaction annotations and changes the default CMT behavior
to SUPPORTS.
And like #4, the EJB container still does its normal exception wrapping.
6. Like #5, but the EJB container also changes the exception wrapping
rules to match those of a standalone CDI bean using the new JTA
transaction annotations (i.e., no exception wrapping at all).
In cases #5 and #6, it's TBD what should happen if the bean uses both
the EJB transaction annotations and the JTA transaction annotations.
Given a possible implementation (see appendix), you can predict the
effect, but it's almost certainly not what the user wants, and so
likely should be treated as an error, probably detected at deployment
time.
The current EJB exception wrapping behavior is somewhat arcane. You
could imagine a new EJB annotation @DontWrapExceptions that would
disable this behavior. This could be used explicitly in cases
#3 - #5 (it's implicit in case #6), or in other existing uses of EJB.
Note that remote EJBs would need to continue to follow the existing
rules for remote exceptions.
Which option above do you prefer?
--- Appendix (read only if you're confused)
For the options #3 - #6, it's helpful to think about how
this might be implemented. For example, consider an
implementation where the EJB container asks CDI to instantiate
the class that is the EJB bean. CDI performs injection on
the bean and returns a wrapper or subclass of the bean that
handles any interceptors declared for the bean. The EJB
container then invokes methods on the bean using this object
reference returned by CDI. The EJB container does no
interceptor handling of its own. This may or may not be a
reasonable or correct implementation approach, but for the
purposes of the following, let's consider it. Here's a picture:
app reference ----> EJB container ----> CDI ----> EJB bean
A B