|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.jboss.byteman.agent.Transformer
public class Transformer
byte code transformer used to introduce byteman events into JBoss code
Nested Class Summary | |
---|---|
private class |
Transformer.VerifyLoader
classloader used by transformer when verification is switched on to detect errors in transformed bytecode |
Field Summary | |
---|---|
static java.lang.String |
ALLOW_CONFIG_UPDATE
system property which determines whether or not byteman configuration can be updated at runtime via the byteman agent listener |
private static boolean |
allowConfigUpdate
master switch which determines whether or not config values can be updated |
static java.lang.String |
BYTEMAN_PACKAGE_PREFIX
prefix for byteman package |
static java.lang.String |
BYTEMAN_SAMPLE_PACKAGE_PREFIX
prefix for byteman sample package |
static java.lang.String |
BYTEMAN_TEST_PACKAGE_PREFIX
prefix for byteman test package |
static java.lang.String |
COMPILE_TO_BYTECODE
system property set (to any value) in order to switch on compilation of rules and left unset if rules are to be interpreted. |
static java.lang.String |
COMPILE_TO_BYTECODE_COMPATIBILITY
retained for compatibility |
private static boolean |
compileToBytecode
switch to control whether rules are compiled to bytecode or not |
private static java.lang.Object |
configLock
lock object used to control getters and setters when allowConfigUpdate is true |
private static boolean |
debug
switch to control debug output during rule processing |
static java.lang.String |
DEBUG
system property set (to any value) in order to switch on debug statements in the default Helper |
private static java.lang.Integer |
DISABLED
|
private static java.lang.Integer |
DISABLED_USER
|
static java.lang.String |
DUMP_CFG
system property set (to any value) in order to switch on dumping of control flow graph for triger method after construction |
static java.lang.String |
DUMP_CFG_PARTIAL
system property set (to any value) in order to switch on dumping of control flow graph for trigger method at each stage of construction |
static java.lang.String |
DUMP_GENERATED_CLASSES
system property set (to any value) in order to switch on dumping of generated bytecode to .class files |
static java.lang.String |
DUMP_GENERATED_CLASSES_DIR
system property identifying directory in which to dump generated bytecode .class files |
static java.lang.String |
DUMP_GENERATED_CLASSES_INTERMEDIATE
system property set (to any value) in order to switch on dumping of intermediate generated bytecode to .class files |
private static boolean |
dumpCFG
switch to control control flow graph output during rule processing |
private static boolean |
dumpCFGPartial
switch to control control flow graph output during rule processing |
private static boolean |
dumpGeneratedClasses
switch to control dumping of generated bytecode to .class files |
private static java.lang.String |
dumpGeneratedClassesDir
directory in which to dump generated bytecode .class files (defaults to "." |
private static boolean |
dumpGeneratedClassesIntermediate
switch to control dumping of generated bytecode to .class files |
private static java.lang.Integer |
ENABLED
|
protected HelperManager |
helperManager
a manager for helper lifecycle events which can be safely handed on to rules |
protected java.lang.instrument.Instrumentation |
inst
the instrumentation interface to the JVM |
private static java.lang.ThreadLocal<java.lang.Integer> |
isEnabled
Thread local holding a per thread Boolean which is true if triggering is disabled and false if triggering is enabled |
protected boolean |
isRedefine
true if the instrumentor allows redefinition |
static java.lang.String |
JAVA_LANG_PACKAGE_PREFIX
prefix for org.jboss package |
protected LoadCache |
loadCache
a cache tracking which classes have been loaded by which class loaders which is used when attempting to resolve a superName to a superclass. |
protected ScriptRepository |
scriptRepository
a mapping from target class names which appear in rules to a script object holding the rule details |
static java.lang.String |
SKIP_OVERRIDE_RULES
system property which turns off injection into overriding methods |
private static boolean |
skipOverrideRules
switch to control whether rules are injected into overriding methods |
static java.lang.String |
SYSPROPS_STRICT_MODE
system property which enables the restriction that only byteman specific system properties will be gettable/settable via a client using the LISTSYSPROPS and SETSYSPROPS commands. |
static java.lang.String |
TRANSFORM_ALL
system property set to true in order to enable transform of java.lang classes |
static java.lang.String |
TRANSFORM_ALL_COMPATIBILITY
retained for compatibility |
private static boolean |
transformAll
switch to control whether transformations will be applied to java.lang.* classes |
private static boolean |
verbose
switch to control verbose output during rule processing |
static java.lang.String |
VERBOSE
system property set (to any value) in order to switch on dumping of generated bytecode to .class files |
static java.lang.String |
VERIFY_TRANSFORMED_BYTES
system property which enables the restriction that only byteman specific system properties will be gettable/settable via a client using the LISTSYSPROPS and SETSYSPROPS commands. |
private static boolean |
verifyTransformedBytes
switch to control whether we attempt to verify transformed bytecode before returning it by consructing a temporary class from it. |
Constructor Summary | |
---|---|
Transformer(java.lang.instrument.Instrumentation inst,
java.util.List<java.lang.String> scriptPaths,
java.util.List<java.lang.String> scriptTexts,
boolean isRedefine)
constructor allowing this transformer to be provided with access to the JVM's instrumentation implementation |
Method Summary | |
---|---|
static boolean |
allowConfigUpdate()
check whether changes to org.jboss.byteman.* system properties will affect the agent configuration. |
private void |
checkConfiguration(java.lang.String property)
|
private static boolean |
computeCompileToBytecode()
|
private static boolean |
computeDebug()
|
private static boolean |
computeDumpCFG()
|
private static boolean |
computeDumpCFGPartial()
|
static boolean |
computeDumpGeneratedClasses()
|
static java.lang.String |
computeDumpGeneratedClassesDir()
|
static boolean |
computeDumpGeneratedClassesIntermediate()
|
private static boolean |
computeSkipOverrideRules()
|
private static boolean |
computeTransformAll()
|
private static boolean |
computeVerbose()
|
private static boolean |
computeVerifyTransformedBytes()
|
static boolean |
disableTriggers(boolean isUser)
disable triggering of rules inside the current thread |
private static void |
dumpClass(java.lang.String fullName,
byte[] bytes)
|
private static void |
dumpClass(java.lang.String fullName,
byte[] bytes,
boolean intermediate)
|
protected void |
dumpScript(RuleScript ruleScript)
|
static boolean |
enableTriggers(boolean isReset)
enable triggering of rules inside the current thread |
private static boolean |
ensureDumpDirectory(java.lang.String fileName)
|
private ClassChecker |
getClassChecker(byte[] bytecode)
return a checker object which can be used to retrieve the super and interfaces of a class from its defining bytecode |
private ClassChecker |
getClassChecker(java.lang.String name,
java.lang.ClassLoader baseLoader)
return a checker object which can be used to retrieve the super and interfaces of a class from its name and classloader, identifying it from the Class instance if it the class is already loaded otherwise loading the corresponding bytecode and parsing it to obtain the relevant details. |
private 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. |
void |
installBootScripts()
ensure that scripts which apply to classes loaded before registering the transformer get are installed by retransforming the relevant classes |
protected boolean |
isBytemanClass(java.lang.String className)
test whether a class with a given name is located in the byteman package |
static boolean |
isCompileToBytecode()
check whether compilation of rules is enabled or disabled |
static boolean |
isDebug()
check whether debug mode for rule processing is enabled or disabled |
static boolean |
isDumpCFG()
check whether dumping of the control flow graph for the trigger class is enabled |
static boolean |
isDumpCFGPartial()
check whether dumping of the control flow graph for the trigger class during construction is enabled |
protected boolean |
isSkipClass(java.lang.Class<?> clazz)
check whether a class should not be considered for transformation |
protected boolean |
isTransformable(java.lang.String className)
test whether a class with a given name is a potential candidate for insertion of event notifications |
private boolean |
isTransformed(java.lang.Class clazz,
java.lang.String name,
boolean isInterface)
|
static boolean |
isTriggeringEnabled()
check if triggering of rules is enabled inside the current thread |
static boolean |
isVerbose()
check whether verbose mode for rule processing is enabled or disabled |
static void |
maybeDumpClass(java.lang.String fullName,
byte[] bytes)
|
static void |
maybeDumpClassIntermediate(java.lang.String fullName,
byte[] bytes)
|
private byte[] |
maybeVerifyTransformedBytes(java.lang.ClassLoader loader,
java.lang.String classname,
java.security.ProtectionDomain protectionDomain,
byte[] bytes)
return the result from calling verifyTransformedBytes if verification is enabled otherwise just return the supplied bytecode |
boolean |
skipOverrideRules()
check whether compilation of rules is enabled or disabled |
byte[] |
transform(java.lang.ClassLoader originalLoader,
java.lang.String className,
java.lang.Class<?> classBeingRedefined,
java.security.ProtectionDomain protectionDomain,
byte[] classfileBuffer)
The implementation of this method may transform the supplied class file and return a new replacement class file. |
byte[] |
transform(RuleScript ruleScript,
java.lang.ClassLoader loader,
java.lang.String className,
byte[] targetClassBytes)
The routine which actually does the real bytecode transformation. |
private byte[] |
tryTransform(byte[] buffer,
java.lang.String name,
java.lang.ClassLoader loader,
java.lang.String key,
boolean isInterface)
|
private byte[] |
tryTransform(byte[] buffer,
java.lang.String name,
java.lang.ClassLoader loader,
java.lang.String key,
boolean isInterface,
boolean isOverride)
|
void |
updateConfiguration(java.lang.String property)
notify a change to an org.jboss.byteman.* system property so that the agent can choose to update its configuration. |
private byte[] |
verifyTransformedBytes(java.lang.ClassLoader loader,
java.lang.String classname,
java.security.ProtectionDomain protectionDomain,
byte[] bytes)
verify the supplied bytecode by converting it to a class and calling newInstance with no args to instantiate. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final java.lang.String BYTEMAN_PACKAGE_PREFIX
public static final java.lang.String BYTEMAN_TEST_PACKAGE_PREFIX
public static final java.lang.String BYTEMAN_SAMPLE_PACKAGE_PREFIX
public static final java.lang.String JAVA_LANG_PACKAGE_PREFIX
public static final java.lang.String VERBOSE
public static final java.lang.String DUMP_CFG_PARTIAL
public static final java.lang.String DUMP_CFG
public static final java.lang.String DEBUG
public static final java.lang.String COMPILE_TO_BYTECODE_COMPATIBILITY
public static final java.lang.String COMPILE_TO_BYTECODE
public static final java.lang.String DUMP_GENERATED_CLASSES
public static final java.lang.String DUMP_GENERATED_CLASSES_INTERMEDIATE
public static final java.lang.String DUMP_GENERATED_CLASSES_DIR
public static final java.lang.String TRANSFORM_ALL
public static final java.lang.String TRANSFORM_ALL_COMPATIBILITY
public static final java.lang.String SKIP_OVERRIDE_RULES
public static final java.lang.String SYSPROPS_STRICT_MODE
public static final java.lang.String VERIFY_TRANSFORMED_BYTES
public static final java.lang.String ALLOW_CONFIG_UPDATE
protected final java.lang.instrument.Instrumentation inst
protected boolean isRedefine
protected final ScriptRepository scriptRepository
protected final LoadCache loadCache
protected final HelperManager helperManager
private static boolean verbose
private static boolean dumpCFGPartial
private static boolean dumpCFG
private static boolean debug
private static boolean compileToBytecode
private static boolean skipOverrideRules
private static boolean dumpGeneratedClasses
private static boolean dumpGeneratedClassesIntermediate
private static java.lang.String dumpGeneratedClassesDir
private static boolean transformAll
private static boolean verifyTransformedBytes
private static boolean allowConfigUpdate
private static java.lang.Object configLock
private static java.lang.ThreadLocal<java.lang.Integer> isEnabled
private static final java.lang.Integer DISABLED_USER
private static final java.lang.Integer DISABLED
private static final java.lang.Integer ENABLED
Constructor Detail |
---|
public Transformer(java.lang.instrument.Instrumentation inst, java.util.List<java.lang.String> scriptPaths, java.util.List<java.lang.String> scriptTexts, boolean isRedefine) throws java.lang.Exception
inst
- the instrumentation object used to interface to the JVM
java.lang.Exception
Method Detail |
---|
public void installBootScripts() throws java.lang.Exception
java.lang.Exception
public byte[] transform(java.lang.ClassLoader originalLoader, java.lang.String className, java.lang.Class<?> classBeingRedefined, java.security.ProtectionDomain protectionDomain, byte[] classfileBuffer) throws java.lang.instrument.IllegalClassFormatException
Instrumentation.addTransformer
,
the transformer will be called for every new class definition and every class redefinition.
The request for a new class definition is made with
ClassLoader.defineClass
.
The request for a class redefinition is made with
Instrumentation.redefineClasses
or its native equivalents.
The transformer is called during the processing of the request, before the class file bytes
have been verified or applied.
If the implementing method determines that no transformations are needed,
it should return null
.
Otherwise, it should create a new byte[]
array,
copy the input classfileBuffer
into it,
along with all desired transformations, and return the new array.
The input classfileBuffer
must not be modified.
In the redefine case, the transformer must support the redefinition semantics.
If a class that the transformer changed during initial definition is later redefined, the
transformer must insure that the second class output class file is a legal
redefinition of the first output class file.
If the transformer believes the classFileBuffer
does not
represent a validly formatted class file, it should throw
an IllegalClassFormatException
. Subsequent transformers
will still be called and the load or redefine will still
be attempted. Throwing an IllegalClassFormatException
thus
has the same effect as returning null but facilitates the
logging or debugging of format corruptions.
transform
in interface java.lang.instrument.ClassFileTransformer
originalLoader
- the defining loader of the class to be transformed,
may be null
if the bootstrap loaderclassName
- the name of the class in the internal form of fully
qualified class and interface names as defined in
The Java Virtual Machine Specification.
For example, "java/util/List"
.classBeingRedefined
- if this is a redefine, the class being redefined,
otherwise null
protectionDomain
- the protection domain of the class being defined or redefinedclassfileBuffer
- the input byte buffer in class file format - must not be modified
null
if no transform is performed.
java.lang.instrument.IllegalClassFormatException
- if the input does not represent a well-formed class fileInstrumentation.redefineClasses(java.lang.instrument.ClassDefinition...)
public static boolean disableTriggers(boolean isUser)
public static boolean enableTriggers(boolean isReset)
public static boolean isTriggeringEnabled()
public static boolean isVerbose()
public static boolean isDumpCFG()
public static boolean isDumpCFGPartial()
public static boolean isDebug()
public static boolean isCompileToBytecode()
public boolean skipOverrideRules()
public static boolean allowConfigUpdate()
public void updateConfiguration(java.lang.String property)
property
- an org.jboss.byteman.* system property which has been updated.protected boolean isTransformable(java.lang.String className)
className
-
public static void maybeDumpClassIntermediate(java.lang.String fullName, byte[] bytes)
public static void maybeDumpClass(java.lang.String fullName, byte[] bytes)
public byte[] transform(RuleScript ruleScript, java.lang.ClassLoader loader, java.lang.String className, byte[] targetClassBytes)
ruleScript
- loader
- className
- targetClassBytes
-
protected boolean isSkipClass(java.lang.Class<?> clazz)
clazz
- the class to check
private byte[] tryTransform(byte[] buffer, java.lang.String name, java.lang.ClassLoader loader, java.lang.String key, boolean isInterface)
private byte[] tryTransform(byte[] buffer, java.lang.String name, java.lang.ClassLoader loader, java.lang.String key, boolean isInterface, boolean isOverride)
protected void dumpScript(RuleScript ruleScript)
private boolean isTransformed(java.lang.Class clazz, java.lang.String name, boolean isInterface)
private ClassChecker getClassChecker(byte[] bytecode)
bytecode
-
private ClassChecker getClassChecker(java.lang.String name, java.lang.ClassLoader baseLoader)
name
- the name of the superclass being checkedbaseLoader
- the class loader of the subclass's bytecode
private byte[] maybeVerifyTransformedBytes(java.lang.ClassLoader loader, java.lang.String classname, java.security.ProtectionDomain protectionDomain, byte[] bytes)
loader
- classname
- protectionDomain
- bytes
-
private byte[] verifyTransformedBytes(java.lang.ClassLoader loader, java.lang.String classname, java.security.ProtectionDomain protectionDomain, byte[] bytes)
loader
- classname
- protectionDomain
- bytes
-
protected boolean isBytemanClass(java.lang.String className)
className
-
private static boolean computeVerbose()
private static boolean computeDumpCFGPartial()
private static boolean computeDumpCFG()
private static boolean computeDebug()
private static boolean computeCompileToBytecode()
private static boolean computeSkipOverrideRules()
public static boolean computeDumpGeneratedClasses()
public static boolean computeDumpGeneratedClassesIntermediate()
public static java.lang.String computeDumpGeneratedClassesDir()
private static boolean computeTransformAll()
private static boolean computeVerifyTransformedBytes()
private void checkConfiguration(java.lang.String property)
private static void dumpClass(java.lang.String fullName, byte[] bytes)
private static void dumpClass(java.lang.String fullName, byte[] bytes, boolean intermediate)
private static boolean ensureDumpDirectory(java.lang.String fileName)
private ClassWriter getNonLoadingClassWriter(int flags)
flags
-
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |