Brian's Waste of Time

Mon, 05 Jan 2004

Intercepts Has Mixins

Bo requested mixin support for Yet-Another-Intercept-Library (YAIL) so I just checked in support.

The mixin support is completely orthogonal to the interceptor support, and works like:


    public void testMixer()
    {
        Mixer mixer = new Mixer();
        mixer.addMixin(Map.class, new HashMap());
        Object base = new Object();
        Object mixed = mixer.mix(base);
        assertTrue(mixed instanceof Map);
    }

It works fine with the interception library as well:


    public void testInterceptMixins()
    {
        InterceptionBroker broker = new InterceptionBroker();
        MockInterceptor mock = new MockInterceptor();
        broker.addInterceptor(mock, new ClassSignature(Map.class));

        Mixer mixer = new Mixer();
        mixer.addMixin(Map.class, new HashMap());
        Object base = new Object();
        Object mixed = mixer.mix(base);

        Map wrapped = (Map) broker.wrap(mixed);
        wrapped.put("1", "2");
        assertTrue(mock.value);
    }

The mixin support is little more than a thin veneer around cglib's mixins. Adding additional utility to the Mixer class will probably happen once I actually use mixins. I can see places where it will be awfully convenient for passing information down interceptor stacks though.

Finally, unrelated, YAIL and Nanning are getting pretty similar, which bugs me. Jon mentioned that he is considering adding cglib support back into Nanning for people who don't mind aspected classes being non-serializable. This seems like silly duplication, but ah well, is all fun. On a side note I implemeneted a quick-and-dirty Nanning backend to the InterceptionBroker and it worked pretty transparently. None of the unit tests passed though as I tend to use HashMap for the base object, and nanning cannot intercept classes, just interfaces.

Pushed another development snbapshot with this.

0 writebacks [/src/java/commons-intercept] permanent link

More Interception Goodness

Over the holidays I spent some time looking at the other interception frameworks available for the JVM directly (ie, AspectJ and AspecktWerkz are out because they require special compilation or classloaders). As Intercepts-Without-A-Name (IWAN) grows I want to try to avoid reinventing wheels, after all.

Nanning I particularly like. It does a little more than interception, also supporting interface based mixins, but is primarily an interception tool. It is purely DynamicProxy based so it only intercepts calls against interfaces, and it requires finer grained setup than the broker in IWAN, but it is perty nice. Big kudos for not having any dependencies!

The Spring Framework is busy re-implementing a better designed J2EE stack without the EJB's and includes an AOP type thingie. It is a DynamicProxy provides a DyanmicProxy based interceptor facility as well. It works via the AOP Alliance interfaces. Dependencies on the AOP Alliance specification jar, and commons-logging. Not too bad, but commons-logging dependency is annoying.

Both of these libraries are designed to play nicely with IoC containers, Pico and Spring respectively. The more I play with interception the more I conclude that interception and IoC go hand in hand -- half of the standard interceptors I have done use type 2 IoC to configure the interceptor at execution time, not to mention the factory aspect of building intercepted objects.

In comparison both of these libraries are a little bit more limited (intercept interfaces only), and underperform IWAN by a factor of 3-5 times before we even get baking working. Spring is being actively developed, Nanning is in maintenance mode. Both have an IoC container associated with them to build tools with to get the beautiful IoC+Interception synergy.

All of that said, I think that IWAN (which I will never call it after this post as I hate the acronym, we need a real name) is worth continueing to persue. It offers a couple key features over these other two -- mainly that it is code generation based instead of dyanmic proxy based so is a lot more flexible and performant. The more I do (the security and transaction stuff, for instance) the more I realize that to really get full benefit I need to provide factory hooks. I hate to tie it to any given container, so maybe I will just try to provide factories alongside interceptors that make use of them that play nicely with generic type 2 and 3 containers (what I have been doing thus far).

On the other hand, the mixin stuff that nanning does would be pretty easy to add to IWAN, but I don't think I want to add it to the core as I want to keep the focus on interception. Ah, fun fun stuff.

5 writebacks [/src/java/commons-intercept] permanent link