RFR: 8200559: Java agents doing instrumentation need a means to define auxiliary classes [v2]

Alan Bateman Alan.Bateman at oracle.com
Wed Apr 21 18:40:44 UTC 2021

On 20/04/2021 21:26, Rafael Winterhalter wrote:
> I have earlier proposed to offer a "jdk.test" module that
> offers the  Instrumentation instance via a simple API similar to Byte
> Buddy's. The JVM would not load this module unless requested on the command
> line. Build tools like Maven's surefire or Gradle's testrunner could then
> standardize on loading this module as a convention to give access to this
> test module by default such that libraries like Mockito could continue to
> function out of the box without the libraries functioning on a standard VM
> without extra configuration. As far as I know, mainly test libraries need
> this API. This would also emphasise that Mockito and others are meant for
> testing and fewer people would abuse it for production applications. People
> would also have an explicit means of running a JVM for a production
> application or for executing a test.
Helping testing is good but a jdk.test module that hands out the 
Instrumentation object could be problematic. Is there a reason why the 
runner for Mockito and other mocking frameworks can't specify -javaagent 
when launching? I would expect at least some mocking scenarios to 
require load time transformations (to drop the final modifier from some 
API elements for example) so important to have the transformer set 
before classes are loaded.

> As for adding the API, my thought is that if the Instrumentation API were
> to throw exceptions on some methods/arguments for dynamic agents in the
> future, for example for retransformClasses(Object.class), this breaking
> change would then simply extend to the proposed "defineClass" method. In
> this sense, the Instrumentation API already assumes full power, I find it
> not problematic to add the missing bit to this API even if it was
> restricted in the future in the same spirit as other methods of the API
> would be.
I think it would really hard to put this genie back into a bottle. It's 
way more attractive to use that than the very agent oriented 
redefineModule and retransformClasses.

> I mentioned JNI as it is a well-known approach to defining a class today,
> using a minimal native binding to an interface that directly calls down to
> JNI's:
> jclass DefineClass(JNIEnv *env, const char *name, jobject loader, const
> jbyte *buf, jsize bufLen);
> This interface can then simply be used to define any class just as I
> propse, even when not writing an agent or attaching. This method makes
> class definitions also already trivial for JVMTI agents compared to Java
> agents. Unless restricting JNI, the defineClass method is already a low
> hanging fruit, but at the cost of having to maintain a tiny bit of native
> code.
Sure, if you are using native code then you have the full power of JVM 
TI and JNI available. Project Panama is exploring how to restrict access 
to native code, I think too early to say how this might extend to JNI.


More information about the core-libs-dev mailing list