1 Reply Latest reply on Feb 11, 2015 10:38 AM by Andrew Dinn

    Rule Helper Lifecycle Method

    Vinod Patil Newbie

      Hi,

       

      1. Suppose i am using byteman with my own defined Helper class with extends "org.jboss.byteman.rule.helper.Helper". I defined method "void startThread()". How can i call this method directly without submitting the RULE to trigger the helper method.
      2. How can i use "Rule Helper Lifecycle Methods" (e.g. void uninstalled(String ruleName) ) from Helper class.

       

      Thanks in advance.

        • 1. Re: Rule Helper Lifecycle Method
          Andrew Dinn Master

          Hi Vinod,

           

          Suppose i am using byteman with my own defined Helper class with extends "org.jboss.byteman.rule.helper.Helper". I defined method "void startThread()".

          • How can i call this method directly without submitting the RULE to trigger the helper method?
          • How can i use "Rule Helper Lifecycle Methods" (e.g. void uninstalled(String ruleName) ) from Helper class?

           

          Ok, so let's look at the first question first ;-). You cannot have your helper method startThread() executed by Byteman without installing a rule. Byteman will only execute code in two circumstances:

          • when rules are installed or uninstalled
          • when rules are triggered by a call to the method(s) identified by the rule hitting the trigger point

          Obviously, triggering can only happen after a rule is installed.

           

          So, if you want to start a thread which does things while your other rules are running then there are two choices

          • add a special rule to create the thread and make sure it gets triggered by some one-off application event
          • use the rule life-cycle methods to create the thread before any rules are fired

          Obviously the first case may be tricky to arrange. The second case is not so tricky but it is less straight forward than it seems, as I will explain next.

           

          Life cycle methods are just static methods of your helper class with specific names and signatures. So, if you want you can call them directly from your rules. However, that is not how they are normally expected to be used and it would be better to rely on Byteman to call them.

           

          If you install a rule which uses its own helper class (i.e. your rule script includes a line like HELPER org.my.FooHelper) then Byteman will check that class for static methods with the following names and signatures:

          • activated()
          • deacivated()
          • installed(org.jboss.byteman.agent.rule.Rule)
          • installed(String)
          • deinstalled(org.jboss.byteman.agent.rule.Rule)
          • deinstalled(String)

          If it finds any such methods then it will call them when rules using the helper class are added or removed. activated and deactivated are called for the first rule is installed and the last rule uninstalled, respectively. installed and deinstalled for each rule (including the first one).

           

          So, if you want your thread to be started before any of your rules get run you can do this

           

          class FooHelper extends Helper
          {
              . . .
              void activated() {
                  startThread()
              }
              void deactivated() {
                  stopThread()
              }
          }
          

           

          After you submit the first rule that uses FooHelper the activated method gets run. Just before Byteman unloads the last rule that uses FooHelper as its helper the deactivated method gets run.

           

          Now, here is where it gets slightly more tricky. Byteman does not call activated() immediately after the rule is loaded. Nor, indeed, does it make the call when it gets injected into a class. Byteman actually has to wait for the first of any of the rules using the helper to be triggered before it can run the activated method. That's a shame because it would be much better if the activate happened at the point where a rule was injected or, even, loaded. Unfortunately, it is necessary to postpone the activate call to a trigger point -- for reasons I won't bother to go into (unless you really want to know :-).