4 Replies Latest reply: Jan 4, 2012 12:54 PM by Bela Ban RSS

    Method matching with parameterized methods

    Bela Ban Master

      I have a class

       

       

      public class RingBuffer<T> implements Iterable<T> {

       

          public boolean add(long seqno, T element) {

                 return add(seqno, seqno, false);

          }

       

          public boolean add(long seqno, T element, boolean block) {

               ....

          } 

      }

       

      and I use it as follows:

       

      RingBuffer<Integer> buf=new RingBuffer<Integer>(...);

      buf.add(5, 5);

       

      My rule is as follows:

      RULE DelayAdd

      CLASS org.jgroups.util.RingBuffer

      METHOD add(long,Integer)

      IF true

      DO System.out.println("----> add(" + $1 + ")");

      ENDRULE

       

      However, neither "add(long,Integer)", "add(long,java.lang.Integer)" or "add(long,Integer,boolean" seems to match.

       

      The only way I get this to work is to just use "add" ! This is weird; and I've used matching with parameters before, so I know it works. Is this because of the use of generics above ?

      Cheers,

        • 1. Re: Method matching with parameterized methods
          Bela Ban Master

          OK, forget this ! Using -Dorg.jboss.byteman.verbose=true, I found out that I needed to write

          "METHOD add(long,java.lang.Object,boolean)" instead of "METHOD add(long,java.lang.Integer,boolean)" to get a match !

           

          I'll try to restrain myself in the future, asking stupid questions ! :-)

          • 2. Re: Method matching with parameterized methods
            Andrew Dinn Master

            Hi Bela,

            Bela Ban wrote:

             

            I have a class

             

            public class RingBuffer<T> implements Iterable<T> {

             

                public boolean add(long seqno, T element) {

                       return add(seqno, seqno, false);

                }

                public boolean add(long seqno, T element, boolean block) {

             

            . . .


            My rule is as follows:

            RULE DelayAdd

            CLASS org.jgroups.util.RingBuffer

            METHOD add(long,Integer)

            IF true

            DO System.out.println("----> add(" + $1 + ")");

            ENDRULE

             

            However, neither "add(long,Integer)", "add(long,java.lang.Integer)" or "add(long,Integer,boolean" seems to match.

             

            The only way I get this to work is to just use "add" ! This is weird; and I've used matching with parameters before, so I know it works. Is this because of the use of generics above ?

             

            Yes, Byteman does not know about generics -- or rather it does not currently weant to know about them. it works from the erased signatures. SO, in this case your class will look like this to Byteman:

             

            public class RingBuffer implements Iterable {

              add(long,Object)

              add(long, Object, boolean)

              . . .

             

            If you specify

             

            RULE DelayAdd

            CLASS org.jgroups.util.RingBuffer

            METHOD add(long,Object)

            . . .

             

            Byteman will inject the rule into the first method.

             

            If you specify

             

            RULE DelayAdd

            CLASS org.jgroups.util.RingBuffer

            METHOD add

            . . .

             

            Byteman will inject the rule into both methods.

             

            Also, in either of these two cases method parameter $1 will have type Object.

             

            n.b. Byteman can actually idenitfy that $1 is a typed using a type parameter.But it cannot deduce from that what type of Object might (or, indeed, ought) be presented when the method is called. This is why I have made no attempt to support type parameters in the CLASS/METHOD clauses (or in the BIND/IF/DO clauses). The same method will be called when call add() for a RingBuffer<Foo>, a RIngBuffer<Bar> where Bar extends Foo or a RingBuffer<Baz> where Baz does not extend Foo. I cannot really see any coherent way to inject code which takes account of parameter types where they do apply and bypasses the rule where they don't apply. It still seems to be a probelm even if you employ a runtime type test on the type-parameterised parameter value.

            • 3. Re: Method matching with parameterized methods
              Andrew Dinn Master

              Bela Ban wrote:

               

              OK, forget this ! Using -Dorg.jboss.byteman.verbose=true, I found out that I needed to write

              "METHOD add(long,java.lang.Object,boolean)" instead of "METHOD add(long,java.lang.Integer,boolean)" to get a match !

               

              I'll try to restrain myself in the future, asking stupid questions ! :-)

               

              Too late, I replied.

               

              Anyway a question is never stupid the first time you ask it. It magically acquires that property with repetition.

              • 4. Re: Method matching with parameterized methods
                Bela Ban Master

                Thanks for taking the time to answer anyway ! Next time I'll try to think before writing... :-)

                Cheers,