2 Replies Latest reply on Jan 30, 2020 11:02 PM by Jaikiran Pai

    Method calls on .class literal trigger invalid rule error

    Jaikiran Pai Master

      Consider this simple class:

       

      public class Foo {
          public static void main(final String[] args) throws Exception {
              System.out.println("Hello world");
          }
      }

       

      and a trivial Byteman rule for it:

       

      RULE simple test
      CLASS Foo
      METHOD main
      AT ENTRY
      IF TRUE
      DO System.out.println("Hello from " + Foo.class);
         System.out.println("Loaded by " + Foo.class.getClassLoader());    
      ENDRULE

      When the Java command is invoked:

       

      java -javaagent:byteman/byteman-4.0.7/lib/byteman.jar=script:/tmp/sample.btm,boot:byteman/byteman-4.0.7/lib/byteman.jar,prop:org.jboss.byteman.verbose=true,prop:org.jboss.byteman.transform.all=true Foo

       

      It ends up with an invalid rule exception:

       

      Setting org.jboss.byteman.verbose=true
      Setting org.jboss.byteman.transform.all=true
      AccessManager:init Initialising default AccessManager
      org.jboss.byteman.agent.Transformer : error parsing rule simple test
      org.jboss.byteman.rule.exception.ParseException: rule simple test
      /tmp/sample.btm line 7 : invalid expression
      org.jboss.byteman.rule.exception.ParseException: rule simple test
      /tmp/sample.btm line 7 : invalid expression
          at org.jboss.byteman.rule.Rule.(Rule.java:233)
          at org.jboss.byteman.rule.Rule.create(Rule.java:389)
          at org.jboss.byteman.agent.TransformContext.parseRule(TransformContext.java:178)
          at org.jboss.byteman.agent.TransformContext.transform(TransformContext.java:88)
          at org.jboss.byteman.agent.Transformer.transform(Transformer.java:757)
          at org.jboss.byteman.agent.Transformer.tryTransform(Transformer.java:824)
          at org.jboss.byteman.agent.Transformer.tryTransform(Transformer.java:796)
          at org.jboss.byteman.agent.Transformer.transform(Transformer.java:264)
          at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
          at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
          at java.lang.ClassLoader.defineClass1(Native Method)
          at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
          at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
          at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
          at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
          at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
          at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
          at java.security.AccessController.doPrivileged(Native Method)
          at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
          at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
          at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
          at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
          at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

      It looks like using any method invocations on a ".class" literal triggers this error. In this case the "Foo.class.getClassLoader()". Is this not allowed? I can't use $0 or even $this in this use case given that this is a static method. Neither can I use $CLASS here since it returns a string value.