Class RuleScript

java.lang.Object
org.jboss.byteman.agent.RuleScript

public class RuleScript extends Object
details of a single rule obtained from a rule file. RuleScript instances are stored in the script repository attached to the transformer. They are used to generate Rule instances at transform time. The RuleScript contains a list of Transforms which detail failed or successful transforms performed using the script.
  • Field Details

    • nextId

      private static int nextId
      a counter used to ensure rule identifiers are unique
    • name

      private String name
      the name of the rule from which this script is derived
    • targetClass

      private String targetClass
      the name supplied in the CLASS or INTERFACE clause of the rule identifying which class(es) triggers should be injected into
    • isInterface

      private boolean isInterface
      true if the target is an interface or false if the target is a class, in the former case the rule should be injected into methods of classes which implement the interface.
    • targetMethod

      private String targetMethod
      the name of the method of the target class or interface into which the rule should be injected
    • isOverride

      private boolean isOverride
      true if the rule should be injected into overriding implementations of the target method false if it should only be injected into the implementation defined by the target class or, in the case of an interface rule, by the class directly implementing the target interface
    • targetHelper

      private String targetHelper
      the name of a class whose public instance methods define the built-in methods available for use in the rule body
    • imports

      private String[] imports
      the details of the IMPORT lines
    • targetLocation

      private Location targetLocation
      identifies the location in the method if the trigger point at which the rule code should be injected. note that for an AT EXIT rule there may be multiple trigger points.
    • ruleText

      private String ruleText
      the text of the rule's BIND IF and DO clauses which are parsed using a grammar based parser
    • deleted

      private boolean deleted
      this is set to true if the rule is dynamically deleted or updated so as to inhibit execution of trigger code between the delete/update and recompilation/reinstatement of the affected bytecode.
    • line

      private int line
      the line number at which the rule text starts
    • file

      private String file
      the name of the file from which the rule has been loaded, if defined, or some suitable dummy string if it was noti obtained from a file
    • compileToBytecode

      private final boolean compileToBytecode
      true if this rule should be compiled to bytecode otherwise false
    • keySet

      private final HashMap<String,String> keySet
      hash map used to lookup a key used at injection time to identify a rule cloned from this script for injection into a specific trigger method. the map translates a string constructed from the trigger class name, method name, method descriptor and class loader hash to a unique key based on the rule name. This ensures that concurrent attempts to inject the rule into the same trigger method will employ the same key and hence perform exactly the same transformation. That way it does not matter which of the transformations are accepted or dropped by the JVM when defining a newly loaded class. Any transform result for a given key is as valid as any other.
    • key_base

      private final String key_base
      base string from which to construct rule injection keys
    • transformSets

      private List<TransformSet> transformSets
      a list of records identifying transforms associated with a specific class. each set is identified by the name of a trigger class and the class's associated loader i.e. it corresponds with an attempt to transform a unique class using this rule script. A transform set may contain more than one transform because the rule's METHOD clause may omit a descriptor, leading to injection into multiple methods. Each transform references the specific method it applies to with a name and and descriptor string. Also, not all transforms record successful injections. Entries are added to record parse errors or warnings, including failure to inject a rule at all. There is at most one successful Transform for a given class+method, at most one failure or, possibly, one or more warnings.
  • Constructor Details

    • RuleScript

      public RuleScript(String name, String targetClass, boolean isInterface, boolean isOverride, String targetMethod, String targetHelper, String[] imports, Location targetLocation, String ruleText, int line, String file, boolean compileToBytecode)
      standard constructor for a rule
      Parameters:
      name - the name of the rule
      targetClass - the name of the class or interface to which the rule applies
      isInterface - true if the ruel applies to an interface false if it appies ot a class
      isOverride - true if the rule should inject down class hierarchies false if it should inly inject into direct implementations
      targetMethod - the name of the method to which the rule applies
      targetHelper - the name of the helper class to be used
      imports - the list of imports for the module system
      targetLocation - description of where the rule should be injected
      ruleText - the body of the rule as text including the BIND, IF and DO clasue
      line - the line at which the rule starts in it's rule script
      file - the path to the file containing the rule
      compileToBytecode - true if the rule should be compiled otherwise false
  • Method Details

    • nextId

      private static int nextId()
      a method to return the next available counter for use in constructing a key for a rule
      Returns:
      the next id
    • getName

      public String getName()
    • getTargetClass

      public String getTargetClass()
    • isInterface

      public boolean isInterface()
    • getTargetHelper

      public String getTargetHelper()
    • getImports

      public String[] getImports()
    • getTargetMethod

      public String getTargetMethod()
    • isOverride

      public boolean isOverride()
    • getTargetLocation

      public Location getTargetLocation()
    • getRuleText

      public String getRuleText()
    • getLine

      public int getLine()
    • getFile

      public String getFile()
    • isCompileToBytecode

      public boolean isCompileToBytecode()
    • getRuleKey

      public String getRuleKey(String triggerClassName, String triggerMethodName, String triggerMethodDescriptor, ClassLoader loader)
    • getTransformSets

      public List<TransformSet> getTransformSets()
      getter for list of transforms applied for this script. must be called synchronized on the script.
      Returns:
      the list of transforms
    • getTransformSetsCount

      public int getTransformSetsCount()
      return a count of the number of transforms applied for this script. must be called synchronized on the script.
      Returns:
      the size of the list of transforms
    • allTransforms

      public List<Transform> allTransforms()
    • setDeleted

      public boolean setDeleted()
      invoked by the scriptmanager when a rule is redefined to inhibit further transformations via this script
      Returns:
      the previous setting of deleted
    • isDeleted

      public boolean isDeleted()
      called when indexing a script to ensure that it has not already been deleted. it must only be called when synchronized on the script. This avoids a race where a script can be added by thread A, deleted by thread B, unindexed -- unsuccessfully -- by thread B then indexed by thread A
      Returns:
      the previous setting of deleted
    • recordFailedTransform

      public boolean recordFailedTransform(ClassLoader loader, String internalClassName, Throwable th)
      record the fact that an error was thrown when attempting to transform a given class using this rule script
      Parameters:
      loader - the loader of the class for which injection was attempted
      internalClassName - the internal Java name of the class
      th - the Throwable reocrding details of the failure
      Returns:
      true if the failure was recorded false if not
    • recordTransform

      public boolean recordTransform(ClassLoader loader, String internalClassName, String triggerMethodName, String desc, Rule rule, Throwable th)
      record the fact that a trigger call has succeeded or else failed to install into bytecode associated with a specific class and loader
      Parameters:
      loader - the loader of the class for which injection was attempted
      internalClassName - the internal Java name of the class
      triggerMethodName - the name of the method injected into
      desc - the descriptor of the method injected into
      rule - the rule which was injected
      th - throwable generated during the attempt to parse the rule text or inject code at the trigger point
      Returns:
      true if the successful injection was recorded false if not
    • hasTransform

      public boolean hasTransform(Class<?> clazz)
      check whether a rule has been used to transform a specific class. this can be used when rules are redefined to decide whether or not a class needs to be retransformed. Note that it must only be called after the script has been deleted by calling setDeleted.
      Parameters:
      clazz - the class for which a transform is being sought.
      Returns:
      true if the class has been transformed using this script otherwise false.
    • recordCompile

      public boolean recordCompile(Rule rule, String triggerClass, ClassLoader loader, boolean successful, String detail)
      record the fact that a rule has been compiled with or without success
      Parameters:
      triggerClass - the name of the trigger class to which the rule is attached
      loader - the classloader of the trigger class
      successful - true if the rule compiled successfully and false if it suffered from parse, type or compile errors
      detail - text describing more details of the compilation outcome
      Returns:
      true if the rule needs to be installed otherwise false
    • purge

      public void purge(ClassLoader loader, String triggerClassName)
      delete any transforms associated with a specific trigger class and loader for deletion. this is called just before any attempt to retransform the class to inject the script's associated rule. it ensures that records of previous transforms associated with a prior retransformation of the class are removed before any new ones are added
    • purge

      public void purge()
      uninstall all transforms associated with this script. this is called after marking the script as deleted and regenerating the methods for any associated transformed class to ensure that it does not cause a rule trigger call to fail.
    • ensureTransformSet

      public TransformSet ensureTransformSet(ClassLoader loader, String triggerClass, Rule installedRule)
    • lookupTransformSet

      public TransformSet lookupTransformSet(ClassLoader loader, String triggerClass)
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • writeTo

      public void writeTo(PrintWriter writer)