On Mar 27, 2007, at 11:07 AM, Prasad Kashyap wrote:
On 3/23/07, David Blevins <[EMAIL PROTECTED]> wrote:
On Mar 23, 2007, at 10:43 AM, Prasad Kashyap wrote:
> I have a bean with one of the methods annotated by a
> @ExcludeClassInterceptor.
>
> The bean itself has 2 class level interceptors, 1 defined as an
> annotation (ClassInterceptor) and 1 specified in the DD
> (DDInterceptor).
>
> With the default ordering, everything invokes as expected and the
> method gets excluded from interception.
>
> However, if an attempt is made to change the ordering of the class
> level interceptors, the @ExcludeClassInterceptor annotation
seems to
> be disregarded. The excluded method gets intercepted too.
>
> See dd snippet below. If the ordering is not changed (default
> ordering), the ClassInterceptor executes before the DDInterceptor.
>
> <interceptor-binding>
> <ejb-name>BasicStatelessIntercepted</ejb-name>
> <interceptor-order>
> <interceptor-class>
> org.apache.openejb.test.interceptor.DDInterceptor
> </interceptor-class>
> <interceptor-class>
> org.apache.openejb.test.interceptor.ClassInterceptor
> </interceptor-class>
> </interceptor-order>
> </interceptor-binding>
This one is a toughie without the full test case to look at. The
interceptor-order is supposed to trump all other bindings at that
same level or lower (low being package, high being method), but it
The spec I believe talks in terms of package being high and method
being low.
Sorry I flipped high and low around when I documented it in the code.
Using spec terms then with a visual layout:
Package: High / Up
Class:
Method1
Method2: Low / Down
I'll explain why I've broken methods into two categories.
For eg. in Section 12.8.2, it says, "The
exclude-default-interceptors element disables default interceptors for
the level at which it is specified and lower. That is,
exclude-default-interceptors when applied at the class-level disables
the application of default-interceptors for all methods of the class."
So an @Exclude when specified at the class level applies to it's lower
level, which is the method.
The paragraph quoted ends with this sentence:
"Explicitly listing an excluded higher-level interceptor at a
lower level causes it to be applied at that level and below."
Which means an @Exclude when specified at the class level applies to
it's lower level, which are the methods, *unless* any one method
chooses to list the interceptor explicitly (by norman means or via
interceptor-order) in which case the interceptor is then applied to
that level (the method for our example) and below (nothing is below
methods).
So the statement "@Exclude trumps ordering" is ambiguous as all this
is level based. Anything done at a higher level (more general level)
can be undone at the lower level (more specific level). The net is
the lowest rule *always* wins. Lower level bindings trump higher
level bindings.
I think the root of your confusion is where it mentions the class
binding affecting all methods of the class. In the absence of the
sentence saying an individual method can say otherwise, that can be
very confusing indeed leading to a backward perspective where rules
cascade in the wrong direction. To keep things straight, just
remember that interception ultimately only applies to methods,
specifying them at package and class level are just a convenience as
it would be a terrible pain to be forced to annotate each method
individually, and using the General to Specific perspective rather
than the High/Low and Up/Down makes for a much more intuitive world.
[most general]
Package - applies to methods in all classes in the archive
Class - applies to methods in the class
Method1 (no params specified in xml) - applies to methods in the
class with the specified name, i.e. overloaded.
Method2 (with params) - applies to that one specific method of the
class with the specified signature (name and parameters)
[most specific]
All bindings apply to methods, but if any General binding could trump
a more Specific binding in anyway you'd have a pretty useless
system. You'd be forced to remove class-level bindings if you wanted
to do things differently for a couple methods in that class. You'd
be forced to remove all package-level bindings to do things
differently in a couple classes. The net affect is you'd eventually
be right back to specifying everything at the method level again as
your only realistic way to do interception.
So now, total ordering vs exclude -- what happens when they're
specified at the *same* level? Total ordering wins. You can only
specify total ordering (via interceptor-order) in the xml, which as a
rule aways trumps annotations, and it was really meant to be an easy
out for not having to understand the rules and as a guaranteed way to
*explicitly* set the order with no subjectivity at all. Interceptor-
order (total ordering) is designed to be your way to have a
completely deterministic set and order of interceptors for that level
and more generally. If you slap an interceptor-order on a class, all
package level bindings and even other class level bindings are
ignored for that class, but more interceptors can still be added at
the method level. If you slap an interceptor-order on a specific
method, all other bindings are ignored for that method and there's no
other form of binding that can change it.
We sorely need documentation for this so I've tried to go above and
beyond a normal answer. Please, please, feel free to continue asking
questions as there's nothing but upside to it -- don't take the large
response as a "please be quiet". It's more a "that's a wonderful
question and thank you very much for making me answer it, people will
need this info. Keep 'em coming."
-David