1 Reply Latest reply on Nov 20, 2010 1:13 AM by rick.dong

    FieldWriteInvocation.getValue does not reflecting changes made along interceptors

    rick.dong

      I have two field write interceptors A and B that is instrumented on a particular fileld. A gets invoked before B. Can someone please confirm whether the following should work?

       

      class A implements Interceptor
      {
           public final Object invoke(Invocation invocation) throws Throwable 
           {
                if (invocation instanceof FieldWriteInvocation)
                {
                     FieldWriteInvocation fwi = (FieldWriteInvocation)invocation;
      
                     Integer value = fwi.getValue(); //value here is 1 suppose
      
                     fwi.setValue(2); //change the value          
                }
      
                return invocation.invokeNext();
           }
      }
      
      
      

       

      after A is done, B is invoked

       

      {code:java}

      class B implements Interceptor

      {

           public final Object invoke(Invocation invocation) throws Throwable

           {

                if (invocation instanceof FieldWriteInvocation)

                {

                     FieldWriteInvocation fwi = (FieldWriteInvocation)invocation;

                     Integer value = fwi.getValue(); //value here should've been 2, but still is 1 (bug??)

                }

                return invocation.invokeNext();

           }

      }

      {code}

       

      I was trying to change the final value that gets set to a field by using the interceptors, but it seems never works. Also setting a breakpoint

      at getValue() seems never gets triggered. I've created an issue @ https://jira.jboss.org/browse/JBAOP-802.

       

      Thanks,

       

      rd

        • 1. Re: FieldWriteInvocation.getValue does not reflecting changes made along interceptors
          rick.dong

          digging into the code, it seems that this could be a bug

           

          private static class WriteBaseClassGenerator extends BaseClassGenerator
             {
                private static final String GET_VALUE = "getValue";
                private static final String SET_VALUE = "setValue";
               
               ....

           

                protected CtClass setupClass()throws NotFoundException, CannotCompileException
                {
                   CtClass setUp = super.setupClass();
                   CtField valueField = new CtField(getArgumentType(), TYPED_VALUE_FIELD, setUp);
                   jp.addField(valueField);
                   CtMethod oldGetValue = WRITE_INVOCATION_CT_TYPE.getDeclaredMethod(GET_VALUE);
                   CtMethod getValue = CtNewMethod.make(oldGetValue.getReturnType(),
                         GET_VALUE, oldGetValue.getParameterTypes(),
                         oldGetValue.getExceptionTypes(), "{return ($w)" + TYPED_VALUE_FIELD + ";}",
                         setUp);
                   setUp.addMethod(getValue);
                   CtMethod oldSetValue = WRITE_INVOCATION_CT_TYPE.getDeclaredMethod(SET_VALUE);
                   CtMethod setValue = CtNewMethod.make(oldSetValue.getReturnType(),
                         GET_VALUE, oldSetValue.getParameterTypes(),
                         oldSetValue.getExceptionTypes(), "{" + TYPED_VALUE_FIELD + " = " +
                         JavassistToReflect.castInvocationValueToTypeString(getArgumentType(),
                               "$1") + ";}", setUp);
                   setUp.addMethod(setValue);
                   return setUp;
                }

           

          Shouldn't the bolded part be SET_VALUE instead for the set to take effect?

           

          Message was edited by: Rick Dong