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

Reply via email to