java.lang.Object | |
↳ | sun.instrument.InstrumentationImpl |
The Java side of the JPLIS implementation. Works in concert with a native JVMTI agent to implement the JPLIS API set. Provides both the Java API implementation of the Instrumentation interface and utility Java routines to support the native code. Keeps a pointer to the native data structure in a scalar field to allow native processing behind native methods.
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Registers the supplied transformer.
| |||||||||||
Registers the supplied transformer.
| |||||||||||
Specifies a JAR file with instrumentation classes to be defined by the
bootstrap class loader.
| |||||||||||
Specifies a JAR file with instrumentation classes to be defined by the
system class loader.
| |||||||||||
Returns an array of all classes currently loaded by the JVM.
| |||||||||||
Returns an array of all classes for which
loader is an initiating loader. | |||||||||||
Returns an implementation-specific approximation of the amount of storage consumed by
the specified object.
| |||||||||||
Determines whether a class is modifiable by
retransformation
or redefinition . | |||||||||||
Returns whether the current JVM configuration supports
setting a native method prefix . | |||||||||||
Returns whether or not the current JVM configuration supports redefinition
of classes.
| |||||||||||
Returns whether or not the current JVM configuration supports retransformation
of classes.
| |||||||||||
Unregisters the supplied transformer.
| |||||||||||
This method modifies the failure handling of
native method resolution by allowing retry
with a prefix applied to the name.
|
[Expand]
Inherited Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
![]() | |||||||||||
![]() |
Registers the supplied transformer. All future class definitions
will be seen by the transformer, except definitions of classes upon which any
registered transformer is dependent.
The transformer is called when classes are loaded, when they are
redefined
. and if canRetransform
is true,
when they are retransformed
.
See ClassFileTransformer.transform
for the order
of transform calls.
If a transformer throws
an exception during execution, the JVM will still call the other registered
transformers in order. The same transformer may be added more than once,
but it is strongly discouraged -- avoid this by creating a new instance of
tranformer class.
This method is intended for use in instrumentation, as described in the
class specification
.
transformer | the transformer to register |
---|---|
canRetransform | can this transformer's transformations be retransformed |
Registers the supplied transformer.
Same as addTransformer(transformer, false)
.
transformer | the transformer to register |
---|
Specifies a JAR file with instrumentation classes to be defined by the bootstrap class loader.
When the virtual machine's built-in class loader, known as the "bootstrap
class loader", unsuccessfully searches for a class, the entries in the JAR file
will be searched as well.
This method may be used multiple times to add multiple JAR files to be searched in the order that this method was invoked.
The agent should take care to ensure that the JAR does not contain any
classes or resources other than those to be defined by the bootstrap
class loader for the purpose of instrumentation.
Failure to observe this warning could result in unexpected
behaviour that is difficult to diagnose. For example, suppose there is a
loader L, and L's parent for delegation is the bootstrap class loader.
Furthermore, a method in class C, a class defined by L, makes reference to
a non-public accessor class C$1. If the JAR file contains a class C$1 then
the delegation to the bootstrap class loader will cause C$1 to be defined
by the bootstrap class loader. In this example an IllegalAccessError
will be thrown that may cause the application to fail. One approach to
avoiding these types of issues, is to use a unique package name for the
instrumentation classes.
The Java Virtual Machine Specification specifies that a subsequent attempt to resolve a symbolic reference that the Java virtual machine has previously unsuccessfully attempted to resolve always fails with the same error that was thrown as a result of the initial resolution attempt. Consequently, if the JAR file contains an entry that corresponds to a class for which the Java virtual machine has unsuccessfully attempted to resolve a reference, then subsequent attempts to resolve that reference will fail with the same error as the initial attempt.
jarfile | The JAR file to be searched when the bootstrap class loader unsuccessfully searches for a class. |
---|
Specifies a JAR file with instrumentation classes to be defined by the
system class loader.
When the system class loader for delegation (see
getSystemClassLoader()
)
unsuccessfully searches for a class, the entries in the JarFile
will be searched as well.
This method may be used multiple times to add multiple JAR files to be searched in the order that this method was invoked.
The agent should take care to ensure that the JAR does not contain any
classes or resources other than those to be defined by the system class
loader for the purpose of instrumentation.
Failure to observe this warning could result in unexpected
behaviour that is difficult to diagnose (see
appendToBootstrapClassLoaderSearch
.
The system class loader supports adding a JAR file to be searched if
it implements a method named appendToClassPathForInstrumentation
which takes a single parameter of type java.lang.String
. The
method is not required to have public
access. The name of
the JAR file is obtained by invoking the getName()
method on the jarfile
and this is provided as the
parameter to the appendtoClassPathForInstrumentation
method.
The Java Virtual Machine Specification specifies that a subsequent attempt to resolve a symbolic reference that the Java virtual machine has previously unsuccessfully attempted to resolve always fails with the same error that was thrown as a result of the initial resolution attempt. Consequently, if the JAR file contains an entry that corresponds to a class for which the Java virtual machine has unsuccessfully attempted to resolve a reference, then subsequent attempts to resolve that reference will fail with the same error as the initial attempt.
This method does not change the value of java.class.path
system property
.
jarfile | The JAR file to be searched when the system class loader unsuccessfully searches for a class. |
---|
Returns an array of all classes currently loaded by the JVM.
Returns an array of all classes for which loader
is an initiating loader.
If the supplied loader is null
, classes initiated by the bootstrap class
loader are returned.
loader | the loader whose initiated class list will be returned |
---|
Returns an implementation-specific approximation of the amount of storage consumed by the specified object. The result may include some or all of the object's overhead, and thus is useful for comparison within an implementation but not between implementations. The estimate may change during a single invocation of the JVM.
objectToSize | the object to size |
---|
Determines whether a class is modifiable by
retransformation
or redefinition
.
If a class is modifiable then this method returns true
.
If a class is not modifiable then this method returns false
.
For a class to be retransformed, isRetransformClassesSupported()
must also be true.
But the value of isRetransformClassesSupported()
does not influence the value
returned by this function.
For a class to be redefined, isRedefineClassesSupported()
must also be true.
But the value of isRedefineClassesSupported()
does not influence the value
returned by this function.
Primitive classes (for example, java.lang.Integer.TYPE
)
and array classes are never modifiable.
Returns whether the current JVM configuration supports
setting a native method prefix
.
The ability to set a native method prefix is an optional
capability of a JVM.
Setting a native method prefix will only be supported if the
Can-Set-Native-Method-Prefix
manifest attribute is set to
true
in the agent JAR file (as described in the
package specification
) and the JVM supports
this capability.
During a single instantiation of a single JVM, multiple
calls to this method will always return the same answer.
Returns whether or not the current JVM configuration supports redefinition
of classes.
The ability to redefine an already loaded class is an optional capability
of a JVM.
Redefinition will only be supported if the
Can-Redefine-Classes
manifest attribute is set to
true
in the agent JAR file (as described in the
package specification
) and the JVM supports
this capability.
During a single instantiation of a single JVM, multiple calls to this
method will always return the same answer.
Returns whether or not the current JVM configuration supports retransformation
of classes.
The ability to retransform an already loaded class is an optional capability
of a JVM.
Retransformation will only be supported if the
Can-Retransform-Classes
manifest attribute is set to
true
in the agent JAR file (as described in the
package specification
) and the JVM supports
this capability.
During a single instantiation of a single JVM, multiple calls to this
method will always return the same answer.
Unregisters the supplied transformer. Future class definitions will not be shown to the transformer. Removes the most-recently-added matching instance of the transformer. Due to the multi-threaded nature of class loading, it is possible for a transformer to receive calls after it has been removed. Transformers should be written defensively to expect this situation.
transformer | the transformer to unregister |
---|
This method modifies the failure handling of
native method resolution by allowing retry
with a prefix applied to the name.
When used with the
ClassFileTransformer
,
it enables native methods to be
instrumented.
native boolean foo(int x);We could transform the class file (with the ClassFileTransformer during the initial definition of the class) so that this becomes:
boolean foo(int x) { ... record entry to foo ... return wrapped_foo(x); } native boolean wrapped_foo(int x);Where
foo
becomes a wrapper for the actual native
method with the appended prefix "wrapped_". Note that
"wrapped_" would be a poor choice of prefix since it
might conceivably form the name of an existing method
thus something like "$$$MyAgentWrapped$$$_" would be
better but would make these examples less readable.
The wrapper will allow data to be collected on the native
method call, but now the problem becomes linking up the
wrapped method with the native implementation.
That is, the method wrapped_foo
needs to be
resolved to the native implementation of foo
,
which might be:
Java_somePackage_someClass_foo(JNIEnv* env, jint x)This function allows the prefix to be specified and the proper resolution to occur. Specifically, when the standard resolution fails, the resolution is retried taking the prefix into consideration. There are two ways that resolution occurs, explicit resolution with the JNI function
RegisterNatives
and the normal automatic resolution. For
RegisterNatives
, the JVM will attempt this
association:
method(foo) -> nativeImplementation(foo)When this fails, the resolution will be retried with the specified prefix prepended to the method name, yielding the correct resolution:
method(wrapped_foo) -> nativeImplementation(foo)For automatic resolution, the JVM will attempt:
method(wrapped_foo) -> nativeImplementation(wrapped_foo)When this fails, the resolution will be retried with the specified prefix deleted from the implementation name, yielding the correct resolution:
method(wrapped_foo) -> nativeImplementation(foo)Note that since the prefix is only used when standard resolution fails, native methods can be wrapped selectively. Since each
ClassFileTransformer
can do its own transformation of the bytecodes, more
than one layer of wrappers may be applied. Thus each
transformer needs its own prefix. Since transformations
are applied in order, the prefixes, if applied, will
be applied in the same order
(see addTransformer
).
Thus if three transformers applied
wrappers, foo
might become
$trans3_$trans2_$trans1_foo
. But if, say,
the second transformer did not apply a wrapper to
foo
it would be just
$trans3_$trans1_foo
. To be able to
efficiently determine the sequence of prefixes,
an intermediate prefix is only applied if its non-native
wrapper exists. Thus, in the last example, even though
$trans1_foo
is not a native method, the
$trans1_
prefix is applied since
$trans1_foo
exists.transformer | The ClassFileTransformer which wraps using this prefix. |
---|---|
prefix | The prefix which has been applied to wrapped native methods. |