Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

EJB3 shortcomings  RSS feed

 
Jesus Angeles
Ranch Hand
Posts: 2069
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Do you see anything negative on the EJB 3, architecture-wise, technical, or other point of view? (that may or may not be a part of future changes)
 
Kai Witte
Ranch Hand
Posts: 356
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hello Jesus,

there are a couple of things, yes:

Do I understand it correctly that an @AroundInvoke method must declare to throw Exception (EJB 3.0 Proposed Final Draft, 11.3)? That's bad for obvious reasons: It forces clients of that method to catch Exception, which would also affect RuntimeExceptions. The phrasing is a bit unfortunate:

AroundInvoke methods have the following signature. ...
Object <METHOD>(InvocationContext) throws Exception

The declared exception is not part of the signature in terms of the JLS or the VMS.

It is also bad that InvocationContext#proceed throws Exception: It forces clients of that method to catch Exception, which would also affect RuntimeExceptions.

Kai
[ October 23, 2006: Message edited by: Kai Witte ]
 
Mike Keith
author
Ranch Hand
Posts: 304
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Kai Witte:
Do I understand it correctly that an @AroundInvoke method must declare to throw Exception (EJB 3.0 Proposed Final Draft, 11.3)? That's bad for obvious reasons: It forces clients of that method to catch Exception, which would also affect RuntimeExceptions. The phrasing is a bit unfortunate:

The declared exception is not part of the signature in terms of the JLS or the VMS.

It is also bad that InvocationContext#proceed throws Exception: It forces clients of that method to catch Exception, which would also affect RuntimeExceptions.


Hi,

Nobody seems to have corrected this statement so I will. :-)

Sounds like a bit of a misunderstanding about what an AroundInvoke method is. It is not a client method but an interception method so there are never any clients that call it. The fact that the interceptor method and IC.proceed() call throw Exception is actually a good thing because without it you would never be able to intercept a method that threw a checked application exception. This would be a severe restriction for many applications.
The only time that you would ever even need to use a try catch block is when calling proceed() in the implementation of an interceptor method.

Hope this clears things up.

-Mike
 
Kai Witte
Ranch Hand
Posts: 356
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hello,

thanks for the reply. The misunderstanding is not on my side, though: With "client of that method" I meant a client of that method, not a J2EE client or anything like that. You are right that this will usually be an EJB container and rarely anything else, though. It is not better to use inappropriate exception handling in the implementation of an EJB container than to use it anywhere else.

The alternative for the proceed()-method would be to throw a checked ProceedException which would wrap the Exception (RuntimeException or checked Exception) of the intercepted method.

The problem with this suggestion is that in the concrete, most likely case - the client of the InvocationContext interface being an interception method - my way could be less convenient. A typical interception method might want to catch a specific application exception and do something with it, while ignoring other possible exceptions of the intercepted method. If that exception would be wrapped into a ProceedException this would look messy. This would be a severe disadvantage of the design I suggested. In the current design of the EJB 3.0 API one can simply wrap the proceed()-call into a try-block, catch those exceptions only that are supposed to get special treatment, and implicitly throw the rest.

The method annotated with @AroundInvoke would throw a ProceedException as well.

Despite the severe disadvantages of the alternative I suggested I don't see
a justification to violate fundamental principles of exception handling in an exposed API.

Kai
 
Mike Keith
author
Ranch Hand
Posts: 304
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, but I'm having trouble making sense out of your argument. On the one hand you are agreeing that throwing Exception is the much better approach, and then say that it violates some "fundamental principles of exception handling in an exposed API". The fact is that we made it this way because it is:
a) more flexible - business methods can throw checked or unchecked exceptions
b) more intuitive - Exception includes checked and unchecked exceptions so WYSIWYG
c) more performant - there is no wrapping by the container and then subsequent unwrapping by the interceptor at every single interceptor point
d) more convenient - interceptors do not need to have to do write unwrapping code unique to EJB 3 to handle any exception and developers of interceptors do not have to understand the container implementation in order to write their interception code

I don't know which "fundamental principle" you are referring to, but even if one existed interceptors don't have an "exposed API". Interceptors are special methods that must be implemented according to the interception contract offered by the container. They have no API for callers/clients.

-Mike
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Has anyone considered passing a "continuation" instead?
Instead of method(args) throws Exception, give:

and then change to method(args, Exceptional).
This also means that you must still have a definite point of return for the "non-exceptional" condition - which you might resolve by passing yet another "continutation".

I think it is generally accepted that declaring to throw java.lang.Exception is poor practice and that any justification is flawed. Not necessarily advocating CPS (continutations), but you could consider some of the existing alternatives (InvocationTargetException - while sucky - is at least, better).
 
Sudd Ghosh
Ranch Hand
Posts: 191
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"I think it is generally accepted that declaring to throw java.lang.Exception is poor practice and that any justification is flawed."
I don't agree with this. The above is true only if one is required to handle that checked exception (like in the case of JDBC), or pass it on to the caller and the caller is required to handle that exception. But in the case of @AroundInvoke, the exception is thrown to the EJB container and the container knows exactly how to handle that. In this situation, what is the problem in declaring that it throws Exception, and moreover since this is needed if it is required to intercept a method that throws a checked exception?
Thanks, Sudd
 
Kai Witte
Ranch Hand
Posts: 356
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hello Mike,

and thanks for your answer. The reasons for design decisions are interesting to me.

Originally posted by Mike Keith:
On the one hand you are agreeing that throwing Exception is the much better approach

That doesn't sound like me at all. Can you quote me on that?
Originally posted by Mike Keith:
I don't know which "fundamental principle" you are referring to

Originally posted by Tony Morris:
I think it is generally accepted that declaring to throw java.lang.Exception is poor practice and that any justification is flawed.

Apparently this is not generally accepted, Tony, so let me summarize: Exception should not be caught. One of the many reasons for this principle is that by doing so any RuntimeException in the corresponding try block would also be caught. It should not be thrown, because that would force clients of the method to catch Exception.

In this case the damage is less severe than in other situations, and there is actually a gain. The one typical piece of software that has to do the dirty work with the thrown Exception is every EJB 3.0 container implementation. I cannot imagine a container implementation which deals with AroundInvoke methods in a clean way.

The introduction of the AroundInvoke annotation was a good choice. For the exception handling there are several options. All of them appear to have severe disadvantages and have to be weighted carefully. Mike, I have the impression that by merely stating arguments for the option that would not have been my design choice I irritated you a lot (see top of this post), and you appear to defend the current design quite one-sided. This gives me the impression that an objective comparison of different approaches did not take place in this part of the API / specification.

Kai
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Sudd Ghosh:
"I think it is generally accepted that declaring to throw java.lang.Exception is poor practice and that any justification is flawed."
I don't agree with this.

Perhaps then I should say "unfortunately, it is not generally accepted...". I am currently writing on this topic - which is not actually related to Java as much as it is related to Intersection Typing. I might consider elaborating if coaxed, but otherwise, I reserve a verbose explanation until then.
 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!