2 Replies Latest reply on Aug 19, 2015 4:41 PM by radek.koubsky

    AT INVOKE location specifier does not match method descriptor

    radek.koubsky

      Hello,

      I am using AT INVOKE location specifier and it does no work in following examples:

      Environment:

      Byteman 3.0.1

      wildfly-8.2.0.Final,

      resteasy version 3.0.10.Final:

      source code: byteman-wildfly-log/rest.btm at master · RadekKoubsky/byteman-wildfly-log · GitHub

       

      1)

      Here is my rule:

       

      RULE logMethodInjectorImpl.invoke.validateAllParams

      CLASS org.jboss.resteasy.core.MethodInjectorImpl

      METHOD invoke(HttpRequest, HttpResponse, Object)

      AT INVOKE org.jboss.resteasy.spi.validation.GeneralValidator.validateAllParameters(HttpRequest, Object, Method, Object[], Class<?>[])

      IF true

      DO log($CLASS, "DEBUG", "(Method invoke) Start validating all parameters of resource method, params: " + java.util.Arrays.toString($args))

      ENDRULE

       

      which should trigger at line 116 in this MethodInjectorImpl class:

      GC: MethodInjectorImpl - org.jboss.resteasy.core.MethodInjectorImpl (.java) - GrepCode Class Source

       

      Here is the target method for AT INVOKE:

      public abstract void validateAllParameters(HttpRequest request, Object object, Method method, Object[] parameterValues, Class<?>... groups);

       

      NOTE:

      I replaced last parameter type Class<?>... with Class<?>[], which should work as I am using same construction for:

       

      java.lang.reflect.Method.invoke(Object obj, Object... args) used in AT INVOVE like this:

       

      AT INVOKE java.lang.reflect.Method.invoke(Object, Object[]) which works properly in another rule in same script.

       

      NOTE2:

      The rule above works if I use only name of the method in AT INVOKE location specifier:

      AT INVOKE org.jboss.resteasy.spi.validation.GeneralValidator.validateAllParameters

       

       

      However, I get exception after running bmsubmit.sh:

       

      RULE logMethodInjectorImpl.invoke.validateAllParams

      CLASS org.jboss.resteasy.core.MethodInjectorImpl

      METHOD invoke(HttpRequest, HttpResponse, Object)

      HELPER org.jboss.byteman.koubsky.LogHelper

      AT INVOKE org.jboss.resteasy.spi.validation.GeneralValidator.validateAllParameters(HttpRequest,Object,Method,Object[],Class<?>[])

      IF true

      DO log($CLASS, "DEBUG", "(Method invoke) Start validating all parameters of resource method, params: " + java.util.Arrays.toString($args))

      ENDRULE

      Transformed in:

      loader: ModuleClassLoader for Module "org.jboss.resteasy.resteasy-jaxrs:main" from local module loader @4ac5af5c (finder: local module finder @787be75d (roots: /home/koubsky/Wildfly8/wildfly-8.2.0.Final/modules,/home/koubsky/Wildfly8/wildfly-8.2.0.Final/modules/system/layers/base))

      trigger method: org.jboss.resteasy.core.MethodInjectorImpl.invoke(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse,java.lang.Object) java.lang.Object

      threw org.jboss.byteman.rule.exception.TypeWarningException: no matching injection point for method invoke(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse,java.lang.Object) java.lang.Object

      org.jboss.byteman.rule.exception.TypeWarningException: no matching injection point for method invoke(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse,java.lang.Object) java.lang.Object

      at org.jboss.byteman.agent.TransformContext.warn(TransformContext.java:243)

      at org.jboss.byteman.agent.adapter.RuleCheckMethodAdapter.checkBindings(RuleCheckMethodAdapter.java:71)

      at org.jboss.byteman.agent.adapter.RuleCheckMethodAdapter.visitEnd(RuleCheckMethodAdapter.java:212)

      at org.jboss.byteman.objectweb.asm.ClassReader.b(Unknown Source)

      at org.jboss.byteman.objectweb.asm.ClassReader.accept(Unknown Source)

      at org.jboss.byteman.objectweb.asm.ClassReader.accept(Unknown Source)

      at org.jboss.byteman.agent.TransformContext.transform(TransformContext.java:121)

      at org.jboss.byteman.agent.Transformer.transform(Transformer.java:746)

      at org.jboss.byteman.agent.Transformer.tryTransform(Transformer.java:814)

      at org.jboss.byteman.agent.Transformer.tryTransform(Transformer.java:785)

      at org.jboss.byteman.agent.Transformer.transform(Transformer.java:257)

      at sun.instrument.TransformerManager.transform(TransformerManager.java:188)

      at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)

      at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)

      at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)

      at org.jboss.byteman.agent.Retransformer.installScript(Retransformer.java:144)

      at org.jboss.byteman.agent.TransformListener.handleScripts(TransformListener.java:349)

      at org.jboss.byteman.agent.TransformListener.loadScripts(TransformListener.java:272)

      at org.jboss.byteman.agent.TransformListener.handleConnection(TransformListener.java:225)

      at org.jboss.byteman.agent.TransformListener.run(TransformListener.java:158)

      Transformed in:

      loader: ModuleClassLoader for Module "org.jboss.resteasy.resteasy-jaxrs:main" from local module loader @4ac5af5c (finder: local module finder @787be75d (roots: /home/koubsky/Wildfly8/wildfly-8.2.0.Final/modules,/home/koubsky/Wildfly8/wildfly-8.2.0.Final/modules/system/layers/base))

      trigger class: org.jboss.resteasy.core.MethodInjectorImpl

      threw org.jboss.byteman.rule.exception.TypeWarningException: failed to find any matching trigger method in class org.jboss.resteasy.core.MethodInjectorImpl

      org.jboss.byteman.rule.exception.TypeWarningException: failed to find any matching trigger method in class org.jboss.resteasy.core.MethodInjectorImpl

      at org.jboss.byteman.agent.TransformContext.notifyRules(TransformContext.java:326)

      at org.jboss.byteman.agent.TransformContext.transform(TransformContext.java:169)

      at org.jboss.byteman.agent.Transformer.transform(Transformer.java:746)

      at org.jboss.byteman.agent.Transformer.tryTransform(Transformer.java:814)

      at org.jboss.byteman.agent.Transformer.tryTransform(Transformer.java:785)

      at org.jboss.byteman.agent.Transformer.transform(Transformer.java:257)

      at sun.instrument.TransformerManager.transform(TransformerManager.java:188)

      at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)

      at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)

      at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)

      at org.jboss.byteman.agent.Retransformer.installScript(Retransformer.java:144)

      at org.jboss.byteman.agent.TransformListener.handleScripts(TransformListener.java:349)

      at org.jboss.byteman.agent.TransformListener.loadScripts(TransformListener.java:272)

      at org.jboss.byteman.agent.TransformListener.handleConnection(TransformListener.java:225)

      at org.jboss.byteman.agent.TransformListener.run(TransformListener.java:158)

       

       

      2)

      Similar problem when <init> is used in AT INVOKE. In this example, I don't know if I can use <init> in that way.

       

      Rule:

       

      RULE logResourceMethodInvoker.invokeOnTarget.newBuildResponse

      CLASS org.jboss.resteasy.core.ResourceMethodInvoker

      METHOD invokeOnTarget(HttpRequest, HttpResponse, Object)

      AT INVOKE org.jboss.resteasy.specimpl.BuiltResponse.BuiltResponse<init>

      IF true

      DO log($CLASS, "DEBUG", "(Method invokeOnTarget) Response is not instanceof BuiltResponse, creating new BuiltResponse from current response.")

      ENDRULE

       

      Stacktrace from bmsubmit.sh:

       

      RULE logResourceMethodInvoker.invokeOnTarget.newBuildResponse

      CLASS org.jboss.resteasy.core.ResourceMethodInvoker

      METHOD invokeOnTarget(HttpRequest, HttpResponse, Object)

      HELPER org.jboss.byteman.koubsky.LogHelper

      AT INVOKE org.jboss.resteasy.specimpl.BuiltResponse.BuiltResponse<init>

      IF true

      DO log($CLASS, "DEBUG", "(Method invokeOnTarget) Response is not instanceof BuiltResponse, creating new BuiltResponse from current response.")

      ENDRULE

      Transformed in:

      loader: ModuleClassLoader for Module "org.jboss.resteasy.resteasy-jaxrs:main" from local module loader @4ac5af5c (finder: local module finder @787be75d (roots: /home/koubsky/Wildfly8/wildfly-8.2.0.Final/modules,/home/koubsky/Wildfly8/wildfly-8.2.0.Final/modules/system/layers/base))

      trigger method: org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse,java.lang.Object) org.jboss.resteasy.specimpl.BuiltResponse

      threw org.jboss.byteman.rule.exception.TypeWarningException: no matching injection point for method invokeOnTarget(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse,java.lang.Object) org.jboss.resteasy.specimpl.BuiltResponse

      org.jboss.byteman.rule.exception.TypeWarningException: no matching injection point for method invokeOnTarget(org.jboss.resteasy.spi.HttpRequest,org.jboss.resteasy.spi.HttpResponse,java.lang.Object) org.jboss.resteasy.specimpl.BuiltResponse

      at org.jboss.byteman.agent.TransformContext.warn(TransformContext.java:243)

      at org.jboss.byteman.agent.adapter.RuleCheckMethodAdapter.checkBindings(RuleCheckMethodAdapter.java:71)

      at org.jboss.byteman.agent.adapter.RuleCheckMethodAdapter.visitEnd(RuleCheckMethodAdapter.java:212)

      at org.jboss.byteman.objectweb.asm.ClassReader.b(Unknown Source)

      at org.jboss.byteman.objectweb.asm.ClassReader.accept(Unknown Source)

      at org.jboss.byteman.objectweb.asm.ClassReader.accept(Unknown Source)

      at org.jboss.byteman.agent.TransformContext.transform(TransformContext.java:121)

      at org.jboss.byteman.agent.Transformer.transform(Transformer.java:746)

      at org.jboss.byteman.agent.Transformer.tryTransform(Transformer.java:814)

      at org.jboss.byteman.agent.Transformer.tryTransform(Transformer.java:785)

      at org.jboss.byteman.agent.Transformer.transform(Transformer.java:257)

      at sun.instrument.TransformerManager.transform(TransformerManager.java:188)

      at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)

      at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)

      at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)

      at org.jboss.byteman.agent.Retransformer.installScript(Retransformer.java:144)

      at org.jboss.byteman.agent.TransformListener.handleScripts(TransformListener.java:349)

      at org.jboss.byteman.agent.TransformListener.loadScripts(TransformListener.java:272)

      at org.jboss.byteman.agent.TransformListener.handleConnection(TransformListener.java:225)

      at org.jboss.byteman.agent.TransformListener.run(TransformListener.java:158)

      Transformed in:

      loader: ModuleClassLoader for Module "org.jboss.resteasy.resteasy-jaxrs:main" from local module loader @4ac5af5c (finder: local module finder @787be75d (roots: /home/koubsky/Wildfly8/wildfly-8.2.0.Final/modules,/home/koubsky/Wildfly8/wildfly-8.2.0.Final/modules/system/layers/base))

      trigger class: org.jboss.resteasy.core.ResourceMethodInvoker

      threw org.jboss.byteman.rule.exception.TypeWarningException: failed to find any matching trigger method in class org.jboss.resteasy.core.ResourceMethodInvoker

      org.jboss.byteman.rule.exception.TypeWarningException: failed to find any matching trigger method in class org.jboss.resteasy.core.ResourceMethodInvoker

      at org.jboss.byteman.agent.TransformContext.notifyRules(TransformContext.java:326)

      at org.jboss.byteman.agent.TransformContext.transform(TransformContext.java:169)

      at org.jboss.byteman.agent.Transformer.transform(Transformer.java:746)

      at org.jboss.byteman.agent.Transformer.tryTransform(Transformer.java:814)

      at org.jboss.byteman.agent.Transformer.tryTransform(Transformer.java:785)

      at org.jboss.byteman.agent.Transformer.transform(Transformer.java:257)

      at sun.instrument.TransformerManager.transform(TransformerManager.java:188)

      at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)

      at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)

      at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)

      at org.jboss.byteman.agent.Retransformer.installScript(Retransformer.java:144)

      at org.jboss.byteman.agent.TransformListener.handleScripts(TransformListener.java:349)

      at org.jboss.byteman.agent.TransformListener.loadScripts(TransformListener.java:272)

      at org.jboss.byteman.agent.TransformListener.handleConnection(TransformListener.java:225)

      at org.jboss.byteman.agent.TransformListener.run(TransformListener.java:158)

       

      Thank you for help.

        • 1. Re: AT INVOKE location specifier does not match method descriptor
          adinn

          Hi Radek,

           

          Rule 1:

           

          The failing signatrure in the location clause is

           

          AT INVOKE org.jboss.resteasy.spi.validation.GeneralValidator.validateAllParameters(HttpRequest, Object, Method, Object[], Class<?>[])
          

           

          I believe it will work as expected if you change the class array type to remove the match-all type signature <?> and instead just specify a raw Class array:

           

          AT INVOKE org.jboss.resteasy.spi.validation.GeneralValidator.validateAllParameters(HttpRequest, Object, Method, Object[], Class[])
          

           

          Remember that Byteman is looking at bytecode, not source code, so it only sees raw (erased) types.

           

          Rule 2:

           

          The failing signatrure in the location clause is

           

          AT INVOKE org.jboss.resteasy.specimpl.BuiltResponse.BuiltResponse<init>
          

           

          I believe this wil work if you avoid the doubled occurence of the class name BuiltResponse and just use <init> for the method name

           

          AT INVOKE org.jboss.resteasy.specimpl.BuiltResponse.<init>
          

           

          The Java name for the constructor is

           

          org.jboss.resteasy.specimpl.BuiltResponse.BuiltResponse
          

           

          or, with the signature inlcuded

           

          org.jboss.resteasy.specimpl.BuiltResponse.BuiltResponse()
          

           

          In bytecode the method name is

           

          org.jboss.resteasy.specimpl.BuiltResponse.<init>
          

           

          or, with the signatrure attached

           

          org.jboss.resteasy.specimpl.BuiltResponse.<init>()V
          

           

          Try these alternatives and see what happens :-)

           

          regards,

           

           

          Andrew Dinn

          • 2. Re: AT INVOKE location specifier does not match method descriptor
            radek.koubsky

            Hi Andrew,

            thanks again for your solution, I tried it and it worked well.

             

            Specially this

            "Remember that Byteman is looking at bytecode, not source code, so it only sees raw (erased) types."

            was my light-bulb moment.

             

            So this is the correct implementation of rules discussed above:

             

            Rule 1:

            RULE logMethodInjectorImpl.invoke.validateAllParams
            CLASS org.jboss.resteasy.core.MethodInjectorImpl
            METHOD invoke(HttpRequest, HttpResponse, Object)
            AT INVOKE org.jboss.resteasy.spi.validation.GeneralValidator.validateAllParameters(HttpRequest, Object, Method, Object[], Class[])
            IF true
            DO log($CLASS, "DEBUG", "(Method invoke) Start validating all parameters of resource method, params: " + java.util.Arrays.toString($args))
            ENDRULE
            
            

             

            Rule2:

            Now I see it, I missed the doubled occurence of BuiltResponse.

            RULE logResourceMethodInvoker.invokeOnTarget.newBuildResponse
            CLASS org.jboss.resteasy.core.ResourceMethodInvoker
            METHOD invokeOnTarget(HttpRequest, HttpResponse, Object)
            AT INVOKE org.jboss.resteasy.specimpl.BuiltResponse.<init>
            IF true
            DO log($CLASS, "DEBUG", "(Method invokeOnTarget) Response is not instanceof BuiltResponse, creating new BuiltResponse from current response.")
            ENDRULE