You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by st...@apache.org on 2013/01/06 01:57:25 UTC

svn commit: r1429448 - in /openwebbeans/trunk/webbeans-impl/src: main/java/org/apache/webbeans/proxy/ test/java/org/apache/webbeans/newtests/interceptors/factory/ test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ test/java/org/apache/w...

Author: struberg
Date: Sun Jan  6 00:57:24 2013
New Revision: 1429448

URL: http://svn.apache.org/viewvc?rev=1429448&view=rev
Log:
OWB-344 create ASM proxy for NormalScoped beans

Added:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/NormalScopeProxyFactoryTest.java
Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ClassInterceptedClass.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/resolution/InterceptorResolutionTest.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java?rev=1429448&r1=1429447&r2=1429448&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java Sun Jan  6 00:57:24 2013
@@ -32,7 +32,15 @@ import org.objectweb.asm.Type;
  */
 public abstract class AbstractProxyFactory
 {
+    /**
+     * @return the marker interface which should be used for this proxy.
+     * TODO this must be a list and for NormalScopeProxy we need add Serializable
+     */
+    protected abstract Class getMarkerInterface();
 
+    /**
+     * generate the bytecode for creating the instance variables of the class
+     */
     protected abstract void createInstanceVariables(ClassWriter cw, Class<?> classToProxy, String classFileName);
 
     /**
@@ -47,9 +55,15 @@ public abstract class AbstractProxyFacto
     protected abstract void createConstructor(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, String classFileName)
             throws ProxyGenerationException;
 
+    /**
+     * generate the bytecode for invoking all intercepted methods
+     */
     protected abstract void delegateInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, Method[] interceptedMethods)
             throws ProxyGenerationException;
 
+    /**
+     * generate the bytecode for invoking all non-intercepted methods
+     */
     protected abstract void delegateNonInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, Method[] noninterceptedMethods)
             throws ProxyGenerationException;
 
@@ -82,7 +96,7 @@ public abstract class AbstractProxyFacto
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
         String classFileName = classToProxy.getName().replace('.', '/');
 
-        String[] interfaceNames = new String[]{Type.getInternalName(OwbInterceptorProxy.class)};
+        String[] interfaceNames = new String[]{Type.getInternalName(getMarkerInterface())};
 
         cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER + Opcodes.ACC_SYNTHETIC, proxyClassFileName, null, classFileName, interfaceNames);
         cw.visitSource(classFileName + ".java", null);
@@ -107,6 +121,7 @@ public abstract class AbstractProxyFacto
 
 
 
+
     /**
      * The 'defineClass' method on the ClassLoader is protected, thus we need to invoke it via reflection.
      * @return the Class which got loaded in the classloader
@@ -373,4 +388,55 @@ public abstract class AbstractProxyFacto
             return Type.getInternalName(returnType);
         }
     }
+
+    /**
+     * Returns the name of the Java method to call to get the primitive value from an Object - e.g. intValue for java.lang.Integer
+     *
+     * @param type Type whose primitive method we want to lookup
+     * @return The name of the method to use
+     */
+    protected String getPrimitiveMethod(final Class<?> type)
+    {
+        if (Integer.TYPE.equals(type))
+        {
+            return "intValue";
+        }
+        else if (Boolean.TYPE.equals(type))
+        {
+            return "booleanValue";
+        }
+        else if (Character.TYPE.equals(type))
+        {
+            return "charValue";
+        }
+        else if (Byte.TYPE.equals(type))
+        {
+            return "byteValue";
+        }
+        else if (Short.TYPE.equals(type))
+        {
+            return "shortValue";
+        }
+        else if (Float.TYPE.equals(type))
+        {
+            return "floatValue";
+        }
+        else if (Long.TYPE.equals(type))
+        {
+            return "longValue";
+        }
+        else if (Double.TYPE.equals(type))
+        {
+            return "doubleValue";
+        }
+
+        throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
+    }
+
+    protected void generateReturn(MethodVisitor mv, Method delegatedMethod)
+    {
+        final Class<?> returnType = delegatedMethod.getReturnType();
+        mv.visitInsn(getReturnInsn(returnType));
+    }
+
 }

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java?rev=1429448&r1=1429447&r2=1429448&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java Sun Jan  6 00:57:24 2013
@@ -58,9 +58,6 @@ public class InterceptorDecoratorProxyFa
     //X TODO add caching of created proxy classes. This is needed to prevent class loading clashes.
     //X a generated proxy cannot easily get redefined later!
 
-    public InterceptorDecoratorProxyFactory()
-    {
-    }
 
     public <T> T createProxyInstance(Class<T> proxyClass, T instance, InterceptorHandler interceptorDecoratorStack)
             throws ProxyGenerationException
@@ -163,7 +160,11 @@ public class InterceptorDecoratorProxyFa
         return clazz;
     }
 
-
+    @Override
+    protected Class getMarkerInterface()
+    {
+        return OwbInterceptorProxy.class;
+    }
 
     protected void createInstanceVariables(ClassWriter cw, Class<?> classToProxy, String classFileName)
     {
@@ -499,57 +500,6 @@ public class InterceptorDecoratorProxyFa
         mv.visitEnd();
     }
 
-    /**
-     * Returns the name of the Java method to call to get the primitive value from an Object - e.g. intValue for java.lang.Integer
-     *
-     * @param type Type whose primitive method we want to lookup
-     * @return The name of the method to use
-     */
-    private String getPrimitiveMethod(final Class<?> type)
-    {
-        if (Integer.TYPE.equals(type))
-        {
-            return "intValue";
-        }
-        else if (Boolean.TYPE.equals(type))
-        {
-            return "booleanValue";
-        }
-        else if (Character.TYPE.equals(type))
-        {
-            return "charValue";
-        }
-        else if (Byte.TYPE.equals(type))
-        {
-            return "byteValue";
-        }
-        else if (Short.TYPE.equals(type))
-        {
-            return "shortValue";
-        }
-        else if (Float.TYPE.equals(type))
-        {
-            return "floatValue";
-        }
-        else if (Long.TYPE.equals(type))
-        {
-            return "longValue";
-        }
-        else if (Double.TYPE.equals(type))
-        {
-            return "doubleValue";
-        }
-
-        throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
-    }
-
-
-
-    private void generateReturn(MethodVisitor mv, Method delegatedMethod)
-    {
-        final Class<?> returnType = delegatedMethod.getReturnType();
-        mv.visitInsn(getReturnInsn(returnType));
-    }
 
     /**
      * pushes an array of the specified size to the method visitor. The generated bytecode will leave

Added: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java?rev=1429448&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java Sun Jan  6 00:57:24 2013
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.webbeans.proxy;
+
+import javax.inject.Provider;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * This factory creates proxies which delegate the
+ * method invocations 1:1 to an instance which gets
+ * resolved via a {@link javax.inject.Provider}.
+ */
+public class NormalScopeProxyFactory extends AbstractProxyFactory
+{
+    /** the name of the field which stores the {@link Provider} for the Contextual Instance */
+    public static final String FIELD_INSTANCE_PROVIDER = "owbContextualInstanceProvider";
+
+
+    @Override
+    protected Class getMarkerInterface()
+    {
+        return OwbNormalScopeProxy.class;
+    }
+
+    /**
+     * @param classLoader to use for creating the class in
+     * @param classToProxy the class for which a subclass will get generated
+     * @param nonInterceptedMethods all methods which are <b>not</b> intercepted nor decorated and shall get delegated directly
+     * @param <T>
+     * @return the proxy class
+     */
+    public synchronized <T> Class<T> createProxyClass(ClassLoader classLoader, Class<T> classToProxy,
+                                                      Method[] nonInterceptedMethods)
+            throws ProxyGenerationException
+    {
+        String proxyClassName = classToProxy.getName() + "$OwbNormalScopeProxy";
+
+        Class<T> clazz = createProxyClass(classLoader, proxyClassName, classToProxy, null, nonInterceptedMethods);
+
+        return clazz;
+    }
+
+    public <T> T createProxyInstance(Class<T> proxyClass, Provider provider)
+            throws ProxyGenerationException
+    {
+        try
+        {
+            T proxy = proxyClass.newInstance();
+
+            Field delegateField = proxy.getClass().getDeclaredField(FIELD_INSTANCE_PROVIDER);
+            delegateField.setAccessible(true);
+            delegateField.set(proxy, provider);
+
+            return proxy;
+        }
+        catch (InstantiationException e)
+        {
+            throw new ProxyGenerationException(e);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new ProxyGenerationException(e);
+        }
+        catch (NoSuchFieldException e)
+        {
+            throw new ProxyGenerationException(e);
+        }
+    }
+
+
+    @Override
+    protected void createConstructor(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, String classFileName) throws ProxyGenerationException
+    {
+        try
+        {
+            Constructor superDefaultCt = classToProxy.getConstructor(null);
+
+            final String descriptor = Type.getConstructorDescriptor(superDefaultCt);
+            final MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", descriptor, null, null);
+            mv.visitCode();
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, classFileName, "<init>", descriptor);
+
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitInsn(Opcodes.ACONST_NULL);
+            mv.visitFieldInsn(Opcodes.PUTFIELD, proxyClassFileName, FIELD_INSTANCE_PROVIDER, Type.getDescriptor(Provider.class));
+
+            mv.visitInsn(Opcodes.RETURN);
+            mv.visitMaxs(-1, -1);
+            mv.visitEnd();
+        }
+        catch (NoSuchMethodException e)
+        {
+            throw new ProxyGenerationException(e);
+        }
+    }
+
+    @Override
+    protected void createInstanceVariables(ClassWriter cw, Class<?> classToProxy, String classFileName)
+    {
+        // variable #1, the Provider<?> for the Contextual Instance
+        cw.visitField(Opcodes.ACC_PRIVATE,
+                FIELD_INSTANCE_PROVIDER, Type.getDescriptor(Provider.class), null, null).visitEnd();
+    }
+
+    @Override
+    protected void delegateInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, Method[] interceptedMethods) throws ProxyGenerationException
+    {
+        // nothing to do ;)
+    }
+
+    @Override
+    protected void delegateNonInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, Method[] noninterceptedMethods) throws ProxyGenerationException
+    {
+        for (Method delegatedMethod : noninterceptedMethods)
+        {
+            if (unproxyableMethod(delegatedMethod))
+            {
+                continue;
+            }
+
+            String methodDescriptor = Type.getMethodDescriptor(delegatedMethod);
+
+            //X TODO handle generic exception types?
+            Class[] exceptionTypes = delegatedMethod.getExceptionTypes();
+            String[] exceptionTypeNames = new String[exceptionTypes.length];
+            for (int i = 0; i < exceptionTypes.length; i++)
+            {
+                exceptionTypeNames[i] = Type.getType(exceptionTypes[i]).getInternalName();
+            }
+
+            int targetModifiers = delegatedMethod.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC);
+
+            MethodVisitor mv = cw.visitMethod(targetModifiers, delegatedMethod.getName(), methodDescriptor, null, exceptionTypeNames);
+
+            // fill method body
+            mv.visitCode();
+
+            // load the contextual instance Provider
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitFieldInsn(Opcodes.GETFIELD, proxyClassFileName, FIELD_INSTANCE_PROVIDER, Type.getDescriptor(Provider.class));
+
+            // invoke the get() method on the Provider
+            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Provider.class), "get", "()Ljava/lang/Object;");
+
+            // and convert the Object to the target class type
+            mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(classToProxy));
+
+
+            // now calculate the parameters
+            int offset = 1;
+            for (Class<?> aClass : delegatedMethod.getParameterTypes())
+            {
+                final Type type = Type.getType(aClass);
+                mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), offset);
+                offset += type.getSize();
+            }
+
+            // and finally invoke the target method on the provided Contextual Instance
+            final Type declaringClass = Type.getType(delegatedMethod.getDeclaringClass());
+            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, declaringClass.getInternalName(), delegatedMethod.getName(), methodDescriptor);
+
+//X            mv.visitInsn(Opcodes.POP);
+
+            generateReturn(mv, delegatedMethod);
+
+            mv.visitMaxs(-1, -1);
+
+            mv.visitEnd();
+        }
+    }
+}

Added: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/NormalScopeProxyFactoryTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/NormalScopeProxyFactoryTest.java?rev=1429448&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/NormalScopeProxyFactoryTest.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/NormalScopeProxyFactoryTest.java Sun Jan  6 00:57:24 2013
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.webbeans.newtests.interceptors.factory;
+
+import javax.inject.Provider;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
+
+import org.apache.webbeans.newtests.AbstractUnitTest;
+import org.apache.webbeans.newtests.interceptors.factory.beans.ClassInterceptedClass;
+import org.apache.webbeans.proxy.NormalScopeProxyFactory;
+import org.apache.webbeans.util.ClassUtil;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for the {@link NormalScopeProxyFactory}
+ */
+public class NormalScopeProxyFactoryTest extends AbstractUnitTest
+{
+
+    @Test
+    public void textSimpleProxyCreation() throws Exception
+    {
+        NormalScopeProxyFactory pf = new NormalScopeProxyFactory();
+
+        // we take a fresh URLClassLoader to not blur the test classpath with synthetic classes.
+        ClassLoader classLoader = new URLClassLoader(new URL[0]);
+
+        List<Method> methods = ClassUtil.getNonPrivateMethods(ClassInterceptedClass.class);
+
+        Method[] nonInterceptedMethods = methods.toArray(new Method[methods.size()]);;
+        //X Method[] nonInterceptedMethods = new Method[]{methods.get(0)};
+
+        Class<ClassInterceptedClass> proxyClass = pf.createProxyClass(classLoader, ClassInterceptedClass.class, nonInterceptedMethods);
+        Assert.assertNotNull(proxyClass);
+
+        ClassInterceptedClass internalInstance = new ClassInterceptedClass();
+        internalInstance.init();
+
+        TestContextualInstanceProvider provider = new TestContextualInstanceProvider(internalInstance);
+
+        ClassInterceptedClass proxy = pf.createProxyInstance(proxyClass, provider);
+
+        Assert.assertEquals(42, proxy.getMeaningOfLife());
+        Assert.assertTrue(provider.gotInvoked());
+
+        Assert.assertEquals(internalInstance.getFloat(), proxy.getFloat(), 0f);
+        Assert.assertTrue(provider.gotInvoked());
+
+        Assert.assertEquals('c', proxy.getChar());
+        Assert.assertTrue(provider.gotInvoked());
+
+        Assert.assertEquals(internalInstance, proxy.getSelf());
+        Assert.assertTrue(provider.gotInvoked());
+
+        try
+        {
+            proxy.doThaBlowup();
+            Assert.fail("NumberFormatException expected!");
+        }
+        catch (NumberFormatException nfe)
+        {
+            Assert.assertEquals("should fit", nfe.getMessage());
+        }
+
+    }
+
+
+    public static class TestContextualInstanceProvider<T> implements Provider<T>
+    {
+        private T instance;
+        private boolean gotInvoked = false;
+
+        public TestContextualInstanceProvider(T instance)
+        {
+            this.instance = instance;
+        }
+
+        public boolean gotInvoked()
+        {
+            boolean invoked = gotInvoked;
+            gotInvoked = false;
+
+            return invoked;
+        }
+
+        @Override
+        public T get()
+        {
+            System.out.println("TestContextualInstanceProvider#get() got invoked!");
+            gotInvoked = true;
+
+            return instance;
+        }
+    }
+}

Modified: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ClassInterceptedClass.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ClassInterceptedClass.java?rev=1429448&r1=1429447&r2=1429448&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ClassInterceptedClass.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/ClassInterceptedClass.java Sun Jan  6 00:57:24 2013
@@ -56,9 +56,10 @@ public class ClassInterceptedClass
     {
         f = 2.4f;
         c = 'c';
+        meaningOfLife = 42;
     }
 
-    public int getMeaningOfLife()
+    public int getMeaningOfLife() throws NumberFormatException
     {
         System.out.println("answering the question about life, the universe and everything!");
         System.out.println("and being in " + this.getClass());
@@ -85,4 +86,9 @@ public class ClassInterceptedClass
         return c;
     }
 
+    public String doThaBlowup() throws NumberFormatException
+    {
+        throw new NumberFormatException("should fit");
+    }
+
 }

Modified: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/resolution/InterceptorResolutionTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/resolution/InterceptorResolutionTest.java?rev=1429448&r1=1429447&r2=1429448&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/resolution/InterceptorResolutionTest.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/resolution/InterceptorResolutionTest.java Sun Jan  6 00:57:24 2013
@@ -74,7 +74,7 @@ public class InterceptorResolutionTest  
 
         Map<Method, InterceptorResolution.MethodInterceptorInfo> methodInterceptorInfos = interceptorInfo.getBusinessMethodsInfo();
         Assert.assertNotNull(methodInterceptorInfos);
-        Assert.assertEquals(6, methodInterceptorInfos.size());
+        Assert.assertEquals(7, methodInterceptorInfos.size());
 
         for (InterceptorResolution.MethodInterceptorInfo mi : methodInterceptorInfos.values())
         {