On 28/06/16 22:47, mark.reinh...@oracle.com wrote: > FYI, I've just posted proposals for some of the open issues in the > draft JPMS specification, including: > . . . > #ReflectiveAccessByInstrumentationAgents > . . .
I am not sure the proposed solution is going to work for my agent and it may well be a problem for other agents for a similar reason. At root, the problem is that the new API seems to be tackling a different problem to the one which motivated me to raise this issue. The new API allows an agent to rewrite any arbitrary module M so that it exports a previously hidden package P to some other module M'. Exercising this API would indeed be sufficient to allow methods of classes in M' to obtain references to non-public methods/fields of classes in package P, enable access and then invoke/access them via reflection. It would also allow the enabled references to be selectively handed on to other code which the agent might want to be able to employ reflection. My problem is not with the functionality per se rather with the provenance of module M'. As I understand the current situation (after conversations with Alan Bateman) all agent classes loaded from an agent jar -- whether the agent is deployed on the command line or dynamically, using the VM_Attach API -- will belong to the unnamed module _M. My problem turns on the question what is the relation between M' and _M? In my case it is my agent code itself that needs to be able to perform reflective accesses. The agent does not need to provide any modules that belong to user code or JDK runtime code with the ability to perform reflective access. So, in my case it is only classes in _M that I want to be grant the opportunity to perform the reflective access. Clearly, I don't want to make M' == _M i.e. to export P to all classes in the unnamed module _M. That would be a serious security flaw. Indeed, in general, the idea that an agent will take some module M' and provide all classes in M' with access to classes in package P is only going to work when the agent has some level of trust in the code in module M'. I can imagine cases where, say, that might occur for a module that is not part of the agent per se -- e.g. module M' is part of some middleware layer whose behaviour has some guarantee of reliability. However, in most cases it is going to be the case that the code in module M' is directly related to the agent code and must be deployed along with the agent. It is highly unlikely that an agent will want to grant some arbitrary user module wholesale access to a package of some other module. Restricted export to the agent itself is certainly the only option in my case. So, with this proposed API my agent would itself need to provide a module M' and only need it in order to delegate requests which enable reflective member access. It is immaterial whether the reflective access itself is performed by the code in module M' or by agent code. This presents two problems, one merely awkward, the other a show-stopper. My agent will need to provide two deliverables, the agent jar and a module. So, for command line use of the agent, my users will need to be able to configure deployment of both deliverables. This complicates usage and also requires different usage if users need to switch from a pre-Jigsaw to a Jigsaw-enabled JDK (it is common for Byteman to be used in environments where more than one JDK is installed). I may be able to mitigate this complexity using convenience scripts (as I have done already to deal with the difficulty many Byteman users face configuring the existing javaagent option). Secondly, and far more importantly, there does not appear to be a way to deploy both the agent jar and an accompanying module dynamically. I don't see any option for adding the required agent module M' to the module path after start-up. This is a show-stopper because 99% of Byteman usage involves dynamic loading of the agent. I don't doubt that this will also be a show-stopper for many other agents. What are the alternatives? Perhaps Instrumentation needs to provide an API to add a module to the module path at runtime? Alternatively, perhaps the proposed API could be used to define a new module at runtime as well as to redefine an existing one? That still leaves the question of how to populate that module with one or more classes. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander