Hi Alan, I have looked into the available options for providing my agent (or indeed any other agent) with access to Reflection and I think the available options, while usable, are a significant limitation wrt to the status quo.
The simplest, safe way to allow an agent to acquire the privileged reflective access available to java.base classes (i.e. not subject to module checks) is for the agent to delegate to an extension class added to java.base using the command line option -Xpatch. Having played around with the relevant class loaders I think that command line option appears to be the only clean way to inveigle a class into a platform module (without begging the question by assuming that you already have the ability to use stuff in java.base such as Unsafe.defineClass). It certainly does not appear to me as if there is any non-ugly way to introduce a class into this module at run time. The only route I could find is temporarily redefining a public method of a java.base class so that it hands over a privileged instance (such as an Unsafe instance) to agent code, making a call to the redefined code, and then redefining the method so that it reverts back to normal. This could probably be made relatively safe (need to worry about recursive calls and ensure it is idempotent in case something else uses the API) but it's pretty tacky and it's a rather crazy path for all agents to have to follow to obtain privileged access. The reason I am unhappy with just using -Xpatch is that it has two usability problems and also raises the issue of redundancy. Firstly, agents can be loaded dynamically when they are needed. That's often true with Byteman where an agent is used to diagnose errant behaviour if and when it happens. If the agent can only do what it needs on the condition that the user had the foresight to start the JVM with the relevant -Xpath option then this is not going to happen in lots of cases. For repeatable problems that's fine -- just restart the JVM. But for intermittent problems this is exactly when you don't want to be kicked by hindsight for your lack of foresight. The second reason is that it requires using two jars, the extension jar used by -Xpatch and then the agent jar. This may sound a small thing but it's easy to underestimate how hard it is for many users to get this sort of thing right, especially when they have to configure access to the jar as a java command line option in a maven pom. I have managed to hide the loading of the Byteman agent jar when running Byteman-based tests in maven by auto-loading the agent dynamically -- all users need to do is ensure that the agent jar and the jar which implement the JTest/TestNG API extensions supported by Byteman are provided as test dependencies. However, I cannot automate setting java command line options from maven. This is going to confuse and, ultimately, lose a lot of users. The redundancy issue is that following this path will require every agent to do something similar, provide a -Xpatch jar, have it /safely/ export an accessor instance to the agent code (and only the agent code) and then have the agent redirect all operations requiring privlege to that accessor instance. Why do all agents need to do this when providing a setAccessible method on class Instrumentation will immediately give every agent a secure channel for doing the same thing? Given the impending guillotine for completion of JDK I intend to raise a JIRA to mark the #ReflectiveAccessByInstrumentationAgents requirement as still needing a fix and suggesting a modification to Instrumenatation as the way to achieve it. If you have any other alternatives to the ones I have described for how to provide agents with java.base privileges I'd be very pleased to hear them and consider them as alternative implementations. Meanwhile I'll look at providing a webrev which implements what would be needed to provide the necessary capability via Instrumenatation. regards, Andrew Dinn -----------