public interface Instrumentation
有两种方法获得的Instrumentation
接口的实例:
当JVM的一种方式,表明了一个代理类推出。在这种情况下,一个Instrumentation
实例传递给代理类的premain
方法。
当JVM提供了一种机制,开始代理JVM启动后的某个时间。在这种情况下,一个Instrumentation
实例传递给代理代码agentmain
方法。
这些机制是在package specification描述。
一旦代理获取的Instrumentation
实例,代理可以调用实例方法在任何时间。
Modifier and Type | Method and Description |
---|---|
void |
addTransformer(ClassFileTransformer transformer)
注册所提供的变压器。
|
void |
addTransformer(ClassFileTransformer transformer, boolean canRetransform)
注册所提供的变压器。
|
void |
appendToBootstrapClassLoaderSearch(JarFile jarfile)
指定用自举类装载器定义的仪器类的一个罐子文件。
|
void |
appendToSystemClassLoaderSearch(JarFile jarfile)
指定由系统类装载器定义的仪器类的一个罐子文件。
|
类[] |
getAllLoadedClasses()
返回当前的JVM加载的所有类的数组。
|
类[] |
getInitiatedClasses(ClassLoader loader)
返回一个数组的所有类,
loader 是启动加载器。
|
long |
getObjectSize(Object objectToSize)
返回指定对象消耗的存储量的实现特定的近似值。
|
boolean |
isModifiableClass(类<?> theClass)
决定一个类是由
retransformation或
redefinition修改。
|
boolean |
isNativeMethodPrefixSupported()
返回当前JVM配置支持
setting a native method prefix。
|
boolean |
isRedefineClassesSupported()
返回当前JVM配置是否支持重新定义类。
|
boolean |
isRetransformClassesSupported()
返回是否当前的JVM配置支持转型类。
|
void |
redefineClasses(ClassDefinition... definitions)
使用所提供的类文件重新定义所提供的类。
|
boolean |
removeTransformer(ClassFileTransformer transformer)
将提供的变压器。
|
void |
retransformClasses(类<?>... classes)
变换提供的集合类。
|
void |
setNativeMethodPrefix(ClassFileTransformer transformer, String prefix)
此方法修改了本地方法解析的故障处理,允许重试以一个前缀应用到名称中。
|
void addTransformer(ClassFileTransformer transformer, boolean canRetransform)
canRetransform
是真实的,当他们
retransformed。看到
ClassFileTransformer.transform
变换顺序调用。如果变压器抛出异常,在执行过程中,JVM仍然要调用其他注册变压器。同一个变压器可以添加一次以上,但它是强烈劝阻-避免通过创建一个变压器类的一个新的实例。
这种方法的目的是用于仪器仪表,在class specification描述。
transformer
-变压器登记
canRetransform
-这是变压器变换转化
NullPointerException
如果通过
null
变压器
UnsupportedOperationException
canRetransform
当前JVM配置不允许再变形(
isRetransformClassesSupported()
是假的)
void addTransformer(ClassFileTransformer transformer)
同addTransformer(transformer, false)
。
transformer
-变压器登记
NullPointerException
如果通过
null
变压器
addTransformer(ClassFileTransformer,boolean)
boolean removeTransformer(ClassFileTransformer transformer)
transformer
-变压器注销
NullPointerException
如果通过
null
变压器
boolean isRetransformClassesSupported()
Can-Retransform-Classes
清单属性设置为
true
在代理JAR文件的支持(如在
package specification描述)和JVM支持此功能。一个单一的实例化一个JVM中,多次调用此方法将总是返回相同的答案。
retransformClasses(java.lang.Class<?>...)
void retransformClasses(类<?>... classes) throws UnmodifiableClassException
此功能有利于已经加载类的仪器。当类最初加载或当他们redefined,初始的类文件的字节可以与ClassFileTransformer
转化。这个函数运行转化过程(是否已发生转变)。这一转型模式遵循以下步骤:
canRetransform
虚假,字节返回的最后一班transform
负荷过程中重复使用或重新定义的转换的输出;注意,这相当于重新改造前,不变;除了transform
不叫canRetransform
真的transform
方法称为这些变压器转型秩序在transform
方法描述。这个命令用于自动重新改造不能变换。
最初的类文件字节代表了ClassLoader.defineClass
或redefineClasses
字节(在任何变换),但是他们可能不完全匹配。常量池可能不具有相同的布局或内容。常量池可能有更多或更少的条目。常量池入口,可以以不同的顺序;然而,在方法的字节码对应的常量池索引。一些属性可能不存在。在订单没有意义的地方,例如方法的顺序,订单可能不会被保存。
这种方法对一组以允许相互依存的变化超过一个班同时(复原类需要改造的B类)。
如果再转化的方法有活动的堆栈,那些活跃的帧继续运行原有方法的字节码。的转化方法将使用新的调用。
这种方法不会引起除了那些会习惯JVM语义下发生的任何初始化。换句话说,重新定义一个类不造成其初始化运行。静态变量的值将保持在调用之前的状态。
类的实例的转化不受影响。
逆变器的可能变化的方法体,常量池和属性。逆变器的不能添加、删除或重命名字段或方法,改变方法签名,或改变继承。这些限制可能被取消在未来的版本。类文件字节不检查,验证和安装,直到转换后已应用,如果所产生的字节是错误的,这种方法将抛出一个异常。
如果此方法抛出一个异常,没有课已转化。
这种方法的目的是用于仪器仪表,在class specification描述。
classes
-逆变类数组数组长度;一零是允许的,在这种情况下,这种方法不
UnmodifiableClassException
-如果指定类不能被修改(
isModifiableClass(java.lang.Class<?>)
将返回
false
)
UnsupportedOperationException
-如果当前JVM的配置不允许再变形(
isRetransformClassesSupported()
是假的)或再尝试让不支持的变化
ClassFormatError
-如果数据不包含一个有效的课堂
NoClassDefFoundError
-如果在类文件的名称是不相等的类的名称
UnsupportedClassVersionError
-如果不支持类文件的版本号
ClassCircularityError
-如果新的类包含一个圆
LinkageError
联动
NullPointerException
-如果提供的数组或其任何部分
null
。
isRetransformClassesSupported()
,
addTransformer(java.lang.instrument.ClassFileTransformer, boolean)
,
ClassFileTransformer
boolean isRedefineClassesSupported()
Can-Redefine-Classes
清单属性设置为
true
在代理JAR文件的支持(如在
package specification描述)和JVM支持此功能。一个单一的实例化一个JVM中,多次调用此方法将总是返回相同的答案。
redefineClasses(java.lang.instrument.ClassDefinition...)
void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException
本方法用于定义一个类不参考现有的类文件的字节,可以做重新编译时,从源头解决并继续调试。现有的类文件的字节,被转化(例如在字节码)retransformClasses
应使用。
这种方法对一组以允许相互依存的变化超过一个班在同一时间(重新定义的类可能需要重新定义的B类)。
如果重新定义方法具有积极的堆栈帧,那些活跃的帧继续运行原有方法的字节码。重新定义的方法将被用于新的调用。
这种方法不会引起除了那些会习惯JVM语义下发生的任何初始化。换句话说,重新定义一个类不造成其初始化运行。静态变量的值将保持在调用之前的状态。
重新定义的类的实例不受影响。
重新定义可能会改变方法体,常量池和属性。重新定义不能添加、删除或重命名字段或方法,改变方法签名,或改变继承。这些限制可能被取消在未来的版本。类文件字节不检查,验证和安装,直到转换后已应用,如果所产生的字节是错误的,这种方法将抛出一个异常。
如果此方法抛出一个异常,没有重新定义类。
这种方法的目的是用于仪器仪表,在class specification描述。
definitions
数组类的定义与相应的定义;一零长度数组是允许的,在这种情况下,这种方法不
UnmodifiableClassException
-如果指定类不能被修改(
isModifiableClass(java.lang.Class<?>)
将返回
false
)
UnsupportedOperationException
-如果当前JVM的配置不允许重新定义(
isRedefineClassesSupported()
是假的)或重新尝试让不支持的变化
ClassFormatError
-如果数据不包含一个有效的课堂
NoClassDefFoundError
-如果在类文件的名称是不相等的类的名称
UnsupportedClassVersionError
-如果不支持类文件的版本号
ClassCircularityError
-如果新的类包含一个圆
LinkageError
联动
NullPointerException
-如果提供定义数组或其任何部分
null
ClassNotFoundException
-不能扔(目前只兼容的原因)
isRedefineClassesSupported()
,
addTransformer(java.lang.instrument.ClassFileTransformer, boolean)
,
ClassFileTransformer
boolean isModifiableClass(类<?> theClass)
true
。如果一个类没有修改这个方法返回
一类是转化,isRetransformClassesSupported()
也必须是真实的。但isRetransformClassesSupported()
值不影响函数返回的值。一类被重新定义,isRedefineClassesSupported()
也必须是真实的。但isRedefineClassesSupported()
值不影响函数返回的值。
原始的类(例如,java.lang.Integer.TYPE
)和数组类永远不会改变。
false
。
theClass
-类检查被修改
NullPointerException
-如果指定的类
null
。
retransformClasses(java.lang.Class<?>...)
,
isRetransformClassesSupported()
,
redefineClasses(java.lang.instrument.ClassDefinition...)
,
isRedefineClassesSupported()
类[] getAllLoadedClasses()
类[] getInitiatedClasses(ClassLoader loader)
loader
是启动加载器。如果提供的装载机是
null
,返回由引导类加载器开始方法重写,继承类。
loader
-装载机的启动类将返回列表
long getObjectSize(Object objectToSize)
objectToSize
-大小的物体
NullPointerException
如果提供的对象是
null
。
void appendToBootstrapClassLoaderSearch(JarFile jarfile)
当虚拟机内置的类装载器,被称为“引导类加载器”,成功搜索的一类,在JAR file
条目将被搜索以及。
此方法可多次使用此方法在调用此方法的顺序中添加多个要搜索的多个文件。
该代理应小心,以确保该罐不包含任何类或资源以外的那些被引导类装载器定义的仪器仪表的目的。没有观察到这一警告可能会导致意想不到的行为,是很难诊断。例如,假设有一个装载器L,L的父为代表团是引导类装载器。此外,在C类的一个方法,通过定义一个类,参照非公开访问器类C 1美元。如果该文件包含一个类C 1美元,那么代表团的引导类加载程序将导致C 1美元被引导类加载程序定义。在这个例子中的一个IllegalAccessError
将抛出,可能会导致应用程序失败。避免这些类型的问题的一种方法,是使用仪器类使用一个唯一的包名称。
The Java™ Virtual Machine Specification指定一个随后试图解决一个象征性的参考,java虚拟机已成功地试图解决总是失败,同样的错误,被作为一个结果,初步解决的尝试。因此,如果JAR文件包含一个条目对应于一个java虚拟机现在试图解决一个引用类型,那么随后试图解决参考会失败同错误的初步尝试。
jarfile
的JAR文件进行搜索时,搜索引导类加载器失败一类。
null
jarfile
NullPointerException
。
appendToSystemClassLoaderSearch(java.util.jar.JarFile)
,
ClassLoader
,
JarFile
void appendToSystemClassLoaderSearch(JarFile jarfile)
getSystemClassLoader()
)成功搜索的一类,在
JarFile
条目将被搜索以及。
此方法可多次使用此方法在调用此方法的顺序中添加多个要搜索的多个文件。
该代理应小心,以确保该罐不包含任何类或资源以外的那些被系统类装载器定义的仪器的目的。不遵守这一警告可能导致意外的行为,是很难诊断(见appendToBootstrapClassLoaderSearch
)。
系统类加载器支持添加一个JAR文件被搜索到,如果它实现了一种appendToClassPathForInstrumentation
以java.lang.String
型单参数。该方法不需要public
访问。jar文件的名称是通过调用在jarfile
的getName()
方法和提供的appendToClassPathForInstrumentation
方法的参数。
The Java™ Virtual Machine Specification指定一个随后试图解决一个象征性的参考,java虚拟机已成功地试图解决总是失败,同样的错误,被作为一个结果,初步解决的尝试。因此,如果JAR文件包含一个条目对应于一个java虚拟机现在试图解决一个引用类型,那么随后试图解决参考会失败同错误的初步尝试。
该方法不改变java.class.path
system property
价值。
jarfile
的JAR文件进行搜索时,搜索系统类加载器失败一类。
UnsupportedOperationException
-如果系统类装载器不支持添加一一的JAR文件进行搜索。
null
jarfile
NullPointerException
。
appendToBootstrapClassLoaderSearch(java.util.jar.JarFile)
,
ClassLoader.getSystemClassLoader()
,
JarFile
boolean isNativeMethodPrefixSupported()
Can-Set-Native-Method-Prefix
清单属性中设置代理JAR文件
true
支持(如在
package specification描述)和JVM支持此功能。一个单一的实例化一个JVM中,多次调用此方法将总是返回相同的答案。
setNativeMethodPrefix(java.lang.instrument.ClassFileTransformer, java.lang.String)
void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix)
ClassFileTransformer
,可使用本地方法。
由于本地方法不能直接检测(他们没有字节码),就必须用非母语的方法可以检测。例如,如果我们有:
本地布尔foo(int x);
我们可以将类文件(在初始定义的类与classfiletransformer)使这成为:
布尔foo(int x){空记录进入foo…返回wrapped_foo(X);}当地的布尔wrapped_foo(int x);
在foo
成为包装的实际方法与附加前缀“wrapped_”。请注意,“wrapped_”将是一个糟糕的选择,因为它的前缀的名称可能会形成一个现有的方法这样的“美元myagentwrapped美元_”会更好,但会使这些例子不可读。
包装器将允许在本地方法调用上收集数据,但现在这个问题将与本机实现的包方法连接起来。这是wrapped_foo
方法需要解决的foo
的本地实现,这可能是:
java_somepackage_someclass_foo(JNIEnv指针,Jint X)
此函数允许指定的前缀和发生的适当的分辨率。具体而言,当标准分辨率分辨率是重试失败,以前缀的考虑。有两种方式解决时,用JNI函数RegisterNatives
和正常的自动分辨明确的决议。对于RegisterNatives
,JVM将本协会:
method(foo) -> nativeImplementation(foo)
当这失败,该决议案将重审与指定前缀添加到方法的名称,得到正确的分辨率:
method(wrapped_foo) -> nativeImplementation(foo)
自动分辨,JVM会尝试:
method(wrapped_foo) -> nativeImplementation(wrapped_foo)
当这失败,该决议案将重审与指定的前缀删除从实施的名字,得到正确的分辨率:
method(wrapped_foo) -> nativeImplementation(foo)
请注意,因为只有当标准分辨率失败时才使用前缀,本地方法可以有选择地进行包装。
由于每个ClassFileTransformer
自己能做转换的字节码,一层以上的包装可以应用。因此,每个变压器需要它自己的前缀。由于应用转换为前缀,如果应用,将其应用在同一顺序(见addTransformer
)。因此,如果三台变压器的应用包装,foo
可能成为$trans3_$trans2_$trans1_foo
。但如果说,第二变压器没有适用的包装foo
就$trans3_$trans1_foo
。能够有效地确定前缀序列,中间的前缀是如果非包装只存在于。因此,在最后一个例子中,即使$trans1_foo
不是本地方法的应用$trans1_foo
存在以来$trans1_
前缀。
transformer
-将使用这个前缀的classfiletransformer。
prefix
-前缀申请包本地方法时,重试失败的本地方法的分辨率。如果前缀是
null
或空字符串,那么失败的本地方法决议不重试此变压器。
NullPointerException
如果通过
null
变压器。
UnsupportedOperationException
-如果当前JVM的配置不允许设置一个本地方法的前缀(
isNativeMethodPrefixSupported()
是假的)。
IllegalArgumentException
-如果变压器没有注册(见
addTransformer
)。
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.