[External] : Re: Reflective access to bytes[] of loaded class
Dan Heidinga
heidinga at redhat.com
Thu Feb 9 18:24:44 UTC 2023
Thanks for confirming, Gary.
On Thu, Feb 9, 2023 at 11:59 AM Gary Frost <gary.frost at oracle.com> wrote:
> Dan
>
> I have indeed used JVMTI (and Java) agents for this. In the case of JVMTI
> by keeping a std::map<std::string,byte[]>, and providing a JNI call to get
> the bytes.
>
> It works well for cases where we know the set of classes we want bytes for
> at JVM 'launch time' , or there is something in the class (name match?
> constant pool entry?) that we can trigger to prune the size of the map.
> Otherwise we are forced to retain a map for all classes, just in case.
>
> And of course who knew whether our JVMTI agent was the last 'actor' in the
> chain of possible mutators to play with the bytes.
>
Can you expand on the use case for getting the current bytes from the
runtime? As I said in the previous email, they aren't a good candidate for
feeding back into the runtime due to the existing JVMTI agent process. Is
this mostly for testing purposes?
--Dan
>
>
> Hence the desire for runtime help
>
>
> ------------------------------
> *From:* Dan Heidinga <heidinga at redhat.com>
> *Sent:* Thursday, February 9, 2023 4:35 PM
> *To:* Gary Frost <gary.frost at oracle.com>
> *Cc:* classfile-api-dev at openjdk.org <classfile-api-dev at openjdk.org>
> *Subject:* [External] : Re: Reflective access to bytes[] of loaded class
>
>
>
> On Thu, Feb 9, 2023 at 11:03 AM Gary Frost <gary.frost at oracle.com> wrote:
>
> I would like to make a case for adding a reflection API for getting the
> bytes for class loaded by the VM as part of this Classfile API.
>
> Something akin to
>
> byte[] Class.getClassfileBytes();
>
>
> I've often wanted the same kind of API when doing one off tests and minor
> modifications so I'm very sympathetic to the request. Typically when doing
> more "serious" class modification, I've used the
> Instrumentation::retransform API [0] or written a native JVMTI agent [1]
> and then such an api to get the current classfile bytes isn't required.
> Does this match your typical use cases as well?
>
> The JVM does some interesting handling of classfile bytes in these cases -
> it allows non-retransform-capable agents to do a 1 time modification of the
> original classfile bytes and then saves those bytes away before passing
> them on to the retransform-capable agents. One subsequent retransform
> events, those saved bytes are reused and only the retransform-capable
> agents get a chance to modify the bytes.
>
> The reason this matters is that existing retransform-capable agents aren't
> expecting to see the modifications they've made present in the classfile
> bytes they get passed. Providing an easy api to get the currently
> executing bytecodes will mean that these agents will now "see" their own
> modifications which may result in incompatibilities.
>
> I'd be interested in feedback from existing major agent providers to see
> how much of a problem such a change would cause them before pursuing it
> unless there's a more common pattern of use I'm unaware of.
>
> [0]
> https://cr.openjdk.java.net/~iris/se/17/latestSpec/api/java.instrument/java/lang/instrument/Instrumentation.html#retransformClasses(java.lang.Class..
> .)
> [1]
> https://cr.openjdk.java.net/~iris/se/17/latestSpec/specs/jvmti.html#RetransformClasses
>
>
>
>
> At present developers usually resort to something like
>
> clazz.getClassLoader().getResourceAsStream(
> clazz.getName().replace(".", "/") + ".class")
>
> Ignoring the fact that we may have just forced an expensive network fetch,
> to bytes that the JVM clearly already has 'squirrelled away' somewhere...
>
> For me this is hugely problematic as there is no guarentee that the bytes
> fetched from such a stream will match the bytes that the JVM is using for
> the class in question....
>
> Java offers all sorts of opportunities (JVMTI agents, Java agents, even
> custom ClassLoaders) for mutating the incoming classfile's bytes. All of
> which the stream fetched via getResourceAsStream() completely sidesteps.
>
>
> See above (or the JVMTI spec) for which bytes get passed through to
> agents. The story is more complex than it first appears.
>
> --Dan
>
>
>
> This may well be considered 'out of bounds' for the Classfile API, but I
> think we should consider it, as it seems to be something that users of the
> Classfile API will need going forward.
>
> Gary
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20230209/742246cb/attachment-0001.htm>
More information about the classfile-api-dev
mailing list