Proposal to introduce method "Instrumentation.getInstance()" to instrument the current VM

Rafael Winterhalter rafael.wth at gmail.com
Thu Sep 29 17:50:18 UTC 2016


Hello,

I want to propose adding a method to the instrumentation API to receive an
instance of the current VM's instrumentation API. Currently, many
applications "self-attach" to gain such access. Unfortunately, this only
works on JDK-VMs but I believe that this approach will grow in popularity
with Java 9 where the Attach API is also part of any regular VM.

Currently, such self-attachment is a rather flaky procedure:

1. Locate the "tools.jar" relatively to the Java Home.
2. Create a new URLClassLoader for this jar.
3. Locate the VirtualMachine type.
4. Parse the process Id from the JMX ManagementBean.
5. Load an agent that stores the instrumentation instance in a public field.
6. Locate this type from the class loader and read the field to receive the
instance.

I maintain a library offering an API for such self-attach and we can do
some amazing things with it. For example, the Mockito library (ca. 400k
downloads/month) now allows for mocking of final methods and types by
inlining the mocking logic into a class what avoids class creation to
create mocks by a subclass with virtual method overrides. Or cache
libraries can call the objectSize method to limit memory usage by a given
number in byte.

Due to the need of publicly exposing the instrumentation API in a public
field when using the above approach, this is however also a security risk
and the procedure is also less stable as it should be as it needs I/O. In
Java 9, this improves as there is an API for reading the current process id
and for accessing the classes of tools.jar but the situation is still far
from ideal. Within any library that uses for example EhCache, the instance
can be stolen by any application on the class path by simple (public)
reflection what then allows instrumenting the security manager to gain all
privileges.

Therefore I want to propose adding a static method to the Instrumentation
interface:

interface Instrumentation {
  static Instrumentation getInstance(boolean redefine, boolean retransform,
boolean nativePrefix) {
    // security manager check
    return getInstance0(redefine, retransform, nativePrefix);
  }
}

This would increase security as the instance is only available aftrer a
check and does not need to be exposed. Also, it would speed up the
attachment process and avoid the I/O involved. Finally, it would make
convenience APIs like the one I implemented unneccessary.

What do you think of this?

Thank you for considering my proposal.
Best regards, Rafael


More information about the core-libs-dev mailing list