[cdi-dev] [JBoss JIRA] (CDI-18) Global enablement of interceptors, decorators and alternatives

Pete Muir (JIRA) jira-events at lists.jboss.org
Wed Sep 5 09:22:33 EDT 2012


    [ https://issues.jboss.org/browse/CDI-18?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12715774#comment-12715774 ] 

Pete Muir edited comment on CDI-18 at 9/5/12 9:20 AM:
------------------------------------------------------

>From the CDI 1.1 EG meeting on 3rd Sept
----

We discussed the ordering and enablement issue, and how it intersects with bean archives.

We all agreed that the key issue to allowing default/global enablement of interceptors, decorators and alternatives was to provide a global ordering solution.

We discussed the three proposals:

(1) Relative ordering of individual interceptors, decorators and alternatives using either a name or an ordering qualifier
(2) Ordinal/magic number based ordering of individual interceptors, decorators and alternatives
(3) Ordinal/magic number based ordering of lists of interceptors, decorators and alternatives (i.e. the ability to specify an order of beans.xml, which themselves specify a partial ordering of interceptors, decorators and alternatives)

We discussed the merits of each. In general, we didn't feel any solution is excellent, however this is a problem we must solve, so we must pick the best, even if it isn't perfect.

Pete expressed concerns over the understandability of the merge of partial orders done in (3). Consider an application which has 10 libraries, each of which specify 10 interceptors in an order. There is some overlap between the lists. For a user to comprehend the overall order is not trivial in this case, it requires a tool to tell you the order.

We discussed (1) and Mark expressed concerns that you can't easily express some well know use cases using it, without explicitly specifying the interceptor by name. For example, consider a TransactionInterceptor, which needs to be "outside all". This must specify "outside all". However, any other interceptor which wants to be outside everything should specify "outside all, inside TransactionInterceptor". This gets complex quite quickly. Its a less complex algorithm to comprehend than (3), but still requires quite a bit of thought to understand the overall order.

Finally, we discussed (2). We agreed that it has some good precedents (e.g. httpd, SYS-V init) that have worked well for a long time. It's trivial to comprehend, and also quick to compute. It does require a knowledge of the position of other algorithms, but so do all other approaches considered.

We agreed to recommend approach (2).

A lower number indicates the interceptor or decorator should appear earlier in the call stack, a higher number indicates it should appear later in the call stack. A higher number alternative takes precedence over a lower number alternative (OPEN ISSUE: how does this interact with class hierarchies?). Two interceptors, decorators and alternatives with the same number have the same precedence, and their order is not defined.

We discussed that we should use recommended ranges for the magic numbers. For example:

1-100: System interceptors, decorators and alternatives (interceptors specified by CDI or the Java EE platform specs)
100 - 1000: Extension interceptors, decorators and alternatives (interceptors provided by extension libraries such as Deltaspike)
1000 - 2000: Application interceptors, decorators and alternatives (interceptors provided by an application or internal extension)
2000 - 3000: Extension interceptors, decorators and alternatives
3000 - 3100: System interceptors, decorators and alternatives

Note that we need to allow system interceptors to go before (e.g transaction) or after (e.g. validation). Using this "pyramid" of ranges allows for this.

Next, we discussed that this needs to be overridable by the SPI, and that the SPI should present a merged view of all interceptors, decorators and alternatives. This should be delivered once, for the whole application. The extension can mutate the list, to change which interceptors, decorators and alternatives are enabled, and the ordering. We looked at the events, and agreed that deferring it as late as possible is good, to allow extensions to have as much info as possible. AfterBeanDiscovery is as late as it can go, as we need this info to perform validation.

Next, we discussed where the ordinal number can be placed, and said that:

* A bean archive which declares an interceptor (alternative or decorator) can set the ordinal, by adding an entry in beans.xml like:

<beans>
   <interceptors>
       <class priority="1001">com.acme.FooInterceptor</class>
   </interceptors>
</beans>

OPEN ISSUE: Is priority the right attribute?

* The application can override the ordering, by specifying the interceptor class, and providing another ordinal. It can able disable an interceptor, decorator or alternative, by adding the enabled="false" attribute.

OPEN ISSUE: Can other libraries disable interceptors and change the precedence? If so, which one wins?

Finally, we decided to remove the ProcessModule event.
                
      was (Author: pmuir):
    From the CDI 1.1 EG meeting on 3rd Sept
----

We discussed the ordering and enablement issue, and how it intersects with bean archives.

We all agreed that the key issue to allowing default/global enablement of interceptors, decorators and alternatives was to provide a global ordering solution.

We discussed the three proposals:

(1) Relative ordering of individual interceptors, decorators and alternatives using either a name or an ordering qualifier
(2) Ordinal/magic number based ordering of individual interceptors, decorators and alternatives
(3) Ordinal/magic number based ordering of lists of interceptors, decorators and alternatives (i.e. the ability to specify an order of beans.xml, which themselves specify a partial ordering of interceptors, decorators and alternatives)

We discussed the merits of each. In general, we didn't feel any solution is excellent, however this is a problem we must solve, so we must pick the best, even if it isn't perfect.

Pete expressed concerns over the understandability of the merge of partial orders done in (3). Consider an application which has 10 libraries, each of which specify 10 interceptors in an order. There is some overlap between the lists. For a user to comprehend the overall order is not trivial in this case, it requires a tool to tell you the order.

We discussed (1) and Mark expressed concerns that you can't easily express some well know use cases using it, without explicitly specifying the interceptor by name. For example, consider a TransactionInterceptor, which needs to be "outside all". This must specify "outside all". However, any other interceptor which wants to be outside everything should specify "outside all, inside TransactionInterceptor". This gets complex quite quickly. Its a less complex algorithm to comprehend than (1), but still requires quite a bit of thought to understand the overall order.

Finally, we discussed (2). We agreed that it has some good precedents (e.g. httpd, SYS-V init) that have worked well for a long time. It's trivial to comprehend, and also quick to compute. It does require a knowledge of the position of other algorithms, but so do all other approaches considered.

We agreed to recommend approach (2).

A lower number indicates the interceptor or decorator should appear earlier in the call stack, a higher number indicates it should appear later in the call stack. A higher number alternative takes precedence over a lower number alternative (OPEN ISSUE: how does this interact with class hierarchies?). Two interceptors, decorators and alternatives with the same number have the same precedence, and their order is not defined.

We discussed that we should use recommended ranges for the magic numbers. For example:

1-100: System interceptors, decorators and alternatives (interceptors specified by CDI or the Java EE platform specs)
100 - 1000: Extension interceptors, decorators and alternatives (interceptors provided by extension libraries such as Deltaspike)
1000 - 2000: Application interceptors, decorators and alternatives (interceptors provided by an application or internal extension)
2000 - 3000: Extension interceptors, decorators and alternatives
3000 - 3100: System interceptors, decorators and alternatives

Note that we need to allow system interceptors to go before (e.g transaction) or after (e.g. validation). Using this "pyramid" of ranges allows for this.

Next, we discussed that this needs to be overridable by the SPI, and that the SPI should present a merged view of all interceptors, decorators and alternatives. This should be delivered once, for the whole application. The extension can mutate the list, to change which interceptors, decorators and alternatives are enabled, and the ordering. We looked at the events, and agreed that deferring it as late as possible is good, to allow extensions to have as much info as possible. AfterBeanDiscovery is as late as it can go, as we need this info to perform validation.

Next, we discussed where the ordinal number can be placed, and said that:

* A bean archive which declares an interceptor (alternative or decorator) can set the ordinal, by adding an entry in beans.xml like:

<beans>
   <interceptors>
       <class priority="1001">com.acme.FooInterceptor</class>
   </interceptors>
</beans>

OPEN ISSUE: Is priority the right attribute?

* The application can override the ordering, by specifying the interceptor class, and providing another ordinal. It can able disable an interceptor, decorator or alternative, by adding the enabled="false" attribute.

OPEN ISSUE: Can other libraries disable interceptors and change the precedence? If so, which one wins?

Finally, we decided to remove the ProcessModule event.
                  
> Global enablement of interceptors, decorators and alternatives
> --------------------------------------------------------------
>
>                 Key: CDI-18
>                 URL: https://issues.jboss.org/browse/CDI-18
>             Project: CDI Specification Issues
>          Issue Type: Feature Request
>          Components: Beans, Decorators, Interceptors, Packaging and Deployment
>    Affects Versions: 1.0
>            Reporter: Mark Struberg
>            Priority: Critical
>             Fix For: 1.1 (Proposed)
>
>
> Currently the spec defines that <interceptors>, <decorators> and <alternatives> affect only the Bean Archives where they are configured in (via beans.xml). 
> Thus if you e.g. enable an Alternative in a WEB-INF/beans.xml, it does NOT count for the jars in it's WEB-INF/lib folder!
> This is pretty unhandy because you would need to repackage all your jars in your WEB-INF/lib folder and add/expand the <alternatives> sections in their beans.xml.
> Needless to say that this is not only hard to do in a company build but is also impossibly to handle at deploy time in an OSGi environment!

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


More information about the cdi-dev mailing list