Package org.jboss.byteman.agent
Class TransformContext
- java.lang.Object
-
- org.jboss.byteman.agent.TransformContext
-
public class TransformContext extends java.lang.Object
Class used to localise the context information employed when creating a rule from a rule script and using it to transform a method
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private class
TransformContext.TransformFailure
private exception class used to throw our way out of the ASM adapter code back into the transform method at the top level.
-
Field Summary
Fields Modifier and Type Field Description private AccessEnabler
accessEnabler
private boolean
failed
private Rule
firstRule
private HelperManager
helperManager
private static java.lang.String
JAVA_METHOD_SPEC_PATTERN
pattern used to identify target method specs which include a return type preceding the method name and parameter type list.private java.lang.ClassLoader
loader
private java.util.HashMap<java.lang.String,Rule>
ruleMap
a hashmap indexing Rule instances using key classname.methodnameandsig@loaderhashcode.private RuleScript
ruleScript
private java.lang.String
targetDescriptor
private java.lang.String
targetMethodName
static java.lang.String
TOFU
private Transformer
transformer
private java.lang.String
triggerClassName
-
Constructor Summary
Constructors Constructor Description TransformContext(Transformer transformer, RuleScript ruleScript, java.lang.String triggerClassName, java.lang.ClassLoader loader, HelperManager helperManager, AccessEnabler accessEnabler)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description Rule
createRule(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
called by a check adapter to create a rule specific to a given trigger method.void
fail(java.lang.String failMessage, java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
called by a check or trigger adapter to fail a transform because of a type issue.java.lang.String
findLeastCommonSuper(java.lang.String t1, java.lang.String t2)
private java.lang.String
getKeyTriggerMethodDescriptor(java.lang.String key)
return the trigger method descriptor used to construct the supplied rule keyprivate java.lang.String
getKeyTriggerMethodName(java.lang.String key)
return the trigger method name used to construct the supplied rule keyprivate org.objectweb.asm.ClassWriter
getNonLoadingClassWriter(int flags)
get a class writer which will not attempt to load classes.private java.lang.String
getRuleKey(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
return a unique string key identifying a specific rule compiled against some class and method/signature in the context of a specific class loaderjava.lang.String
getTriggerClassName()
boolean
injectIntoMethod(java.lang.String name, java.lang.String desc)
private java.util.LinkedList<java.lang.String>
listInterfaces(ClassChecker checker)
private java.util.LinkedList<java.lang.String>
listSupers(ClassChecker checker)
Rule
lookupRule(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
called by a trigger adapter to find a rule specific to a given trigger method, expects to find a rule created by the corresponding check adapter.boolean
matchTargetMethod(int access, java.lang.String name, java.lang.String desc)
private java.lang.String
mungeMethodSpecReturnType(java.lang.String targetMethodSpec)
detect a method specification which includes a return type preceding the method name and transform it so that the return type is at the end.private boolean
notifyRules()
this gets called when a transform attempt completes without any exceptions.void
parseRule()
private void
purgeRules()
this gets called when a transform attempt fails.void
recordFailedTransform(java.lang.Throwable th)
byte[]
transform(byte[] targetClassBytes)
void
warn(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor, java.lang.String warningMessage)
called by a check adapter to warn that a transform was not possible for a potential match target.
-
-
-
Field Detail
-
JAVA_METHOD_SPEC_PATTERN
private static final java.lang.String JAVA_METHOD_SPEC_PATTERN
pattern used to identify target method specs which include a return type preceding the method name and parameter type list. note that we can only handle a return type in cases where the parameter type list is also specified.- See Also:
- Constant Field Values
-
TOFU
public static final java.lang.String TOFU
- See Also:
- Constant Field Values
-
transformer
private Transformer transformer
-
ruleScript
private RuleScript ruleScript
-
triggerClassName
private java.lang.String triggerClassName
-
targetMethodName
private java.lang.String targetMethodName
-
targetDescriptor
private java.lang.String targetDescriptor
-
loader
private java.lang.ClassLoader loader
-
helperManager
private HelperManager helperManager
-
accessEnabler
private AccessEnabler accessEnabler
-
failed
private boolean failed
-
ruleMap
private java.util.HashMap<java.lang.String,Rule> ruleMap
a hashmap indexing Rule instances using key classname.methodnameandsig@loaderhashcode. rules are added to this map when they are created and removed when the transform is recorded as having succeeded or failed. a method check adapter will create a rule when it begins a method scan and a method trigger adpater will look it up in order to reuse it
-
firstRule
private Rule firstRule
-
-
Constructor Detail
-
TransformContext
public TransformContext(Transformer transformer, RuleScript ruleScript, java.lang.String triggerClassName, java.lang.ClassLoader loader, HelperManager helperManager, AccessEnabler accessEnabler)
-
-
Method Detail
-
transform
public byte[] transform(byte[] targetClassBytes)
-
parseRule
public void parseRule() throws java.lang.Exception
- Throws:
java.lang.Exception
-
lookupRule
public Rule lookupRule(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
called by a trigger adapter to find a rule specific to a given trigger method, expects to find a rule created by the corresponding check adapter. if no rule is found then injection must be bypassed for this method- Parameters:
triggerMethodName
- the name of a candidate method for injectiontriggerMethodDescriptor
- the descriptor of a candidate method for injection- Returns:
- the rule if it exists or NULL if not
-
createRule
public Rule createRule(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
called by a check adapter to create a rule specific to a given trigger method. the first such call reuses the rule created by the intiial parse. subsequent calls create a new rule.- Parameters:
triggerMethodName
- the name of a candidate method for injectiontriggerMethodDescriptor
- the descriptor of a candidate method for injection- Returns:
- the new rule
-
warn
public void warn(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor, java.lang.String warningMessage)
called by a check adapter to warn that a transform was not possible for a potential match target. this inhibits injection into the method being warned about allowing other injection operations to continue.- Parameters:
triggerMethodName
- the name of a candidate method for injectiontriggerMethodDescriptor
- the descriptor of a candidate method for injectionwarningMessage
- details of the warning
-
fail
public void fail(java.lang.String failMessage, java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
called by a check or trigger adapter to fail a transform because of a type issue. this aborts all injection into the current class not just injection into the current method.- Parameters:
failMessage
- details of the failuretriggerMethodName
- the name of a candidate method for injectiontriggerMethodDescriptor
- the descriptor of a candidate method for injection
-
recordFailedTransform
public void recordFailedTransform(java.lang.Throwable th)
-
matchTargetMethod
public boolean matchTargetMethod(int access, java.lang.String name, java.lang.String desc)
-
injectIntoMethod
public boolean injectIntoMethod(java.lang.String name, java.lang.String desc)
-
getTriggerClassName
public java.lang.String getTriggerClassName()
-
notifyRules
private boolean notifyRules()
this gets called when a transform attempt completes without any exceptions. if there are rules left in the rule map then they will belong successful injections.
-
purgeRules
private void purgeRules()
this gets called when a transform attempt fails. if there are rules left in the rule map then they will belong either to earlier successful injections or to the failed transform. in any case they need to be purged.
-
getRuleKey
private java.lang.String getRuleKey(java.lang.String triggerMethodName, java.lang.String triggerMethodDescriptor)
return a unique string key identifying a specific rule compiled against some class and method/signature in the context of a specific class loader- Returns:
- a unique string key
-
getKeyTriggerMethodName
private java.lang.String getKeyTriggerMethodName(java.lang.String key)
return the trigger method name used to construct the supplied rule key- Parameters:
key
-- Returns:
- the trigger method name
-
getKeyTriggerMethodDescriptor
private java.lang.String getKeyTriggerMethodDescriptor(java.lang.String key)
return the trigger method descriptor used to construct the supplied rule key- Parameters:
key
-- Returns:
- the trigger method descriptor
-
mungeMethodSpecReturnType
private java.lang.String mungeMethodSpecReturnType(java.lang.String targetMethodSpec)
detect a method specification which includes a return type preceding the method name and transform it so that the return type is at the end.- Parameters:
targetMethodSpec
-- Returns:
- the method spec in the desired format
-
getNonLoadingClassWriter
private org.objectweb.asm.ClassWriter getNonLoadingClassWriter(int flags)
get a class writer which will not attempt to load classes. The default classwriter tries this when a reference type local var frame slot aligns with a slot of reference type in a successor block's frame. This is merely so it can optimize a slot out of the frame change set in the special case where f1[slot].type < f2[slot].type or vice versa by using the least common supereclass. We have to use the Transformer to reuse existing loaded classes and, where a class has not been loaded, to attempt to load the bytecode as a resource and identify supers via the bytecode.- Parameters:
flags
-- Returns:
- a non-loading class writer
-
findLeastCommonSuper
public java.lang.String findLeastCommonSuper(java.lang.String t1, java.lang.String t2)
-
listInterfaces
private java.util.LinkedList<java.lang.String> listInterfaces(ClassChecker checker)
-
listSupers
private java.util.LinkedList<java.lang.String> listSupers(ClassChecker checker)
-
-