Problem with multi-release jars, agents and the bootstrap class path

Andrew Dinn adinn at
Thu Oct 13 20:43:24 UTC 2016

On 13/10/16 18:27, Alan Bateman wrote:
> What you see is deliberate. It wouldn't be impossible for the boot
> loader to support MR JARs but it hardly seems worth the complexity. One
> reason is that it's not a common way to deploy a general purpose
> library. Even if it were then it would be problematic going forward as
> we reduce the number of modules defined to the boot loader (you can't
> instrument code in core modules to call into a SQL library for example
> because java.sql types are not visible to code in the boot loader). The
> other thing is that the boot class path as we used to know it is mostly
> gone, it only really exists when using -Xbootclasspath/a or when JVM TI
> or java.lang.instrument do the equivalent.

Ok, that's what I was expecting to be the answer :-)

I am aware that the code I add to the bootstrap can only rely on a core
subset of the JDK runtime classes being available. That ought not to be
an issue -- I have deliberately kept the agent's footprint as small as
possible because every time Byteman uses an API it makes it trickier to
instrument the API class. I'd be interested to know what you are hoping
to exclude though, just in case. Am I ok with print stream? file
streams? localhost server sockets? Just checking :-)

> For the "hoist"-ing scenario then I assume you mean
> Instrumentation::appendToBootstrapClassLoaderSearch to add supporting
> classes to the boot class path so that they are visible to instrumented
> code. Can you use the same method to append a JAR file containing
> 53.0/9+ classes before you append the other JAR. That should be
> equivalent to what a MR JAR would give you, albeit without the
> convenience of everything in one artifact.

Yes, by hoisting I mean precisely that. The minor wrinkle that the class
which adds the agent jar to the bootstrap path actually gets loaded from
that same jar (but via the system classpath) is what led me to use  the
term 'hoist'. There is probably a joke in here somewhere about 'my own
petard' but I'll demur.

I could indeed use two jar files -- in fact my last attempt at a JDK9
compatible implementation did precisely that. However, that actually
turns out to be /much/ more inconvenient because it means the agent jar
doing the hoisting needs to be able to work out where the auxiliary jar
is. This results in a lot of configuration grief (because of the need to
cope with command line vs dynamic install and also to make it easy to do
from tools like maven). So I much prefer a one jar solution.

As it happens, I have managed to encapsulate the JDK8- vs JDK9+ variant
functionality behind an interface. This means that I ham able to employ
just one setup class which needs a JDK8- and JDK9+ variant -- it's job
is to provide a static method which populates the interface with a
suitable implementation. So, I /can/ actually resolve this issue by
bundling all the code in one jar but with this variant implemented as
two distinct classes. I will simply load the relevant variant by name +
reflectively invoke it's static setup method conditional on whether or
not the JDK includes Jigsaw.

I was asking not because this problem is not resolvable but because

  I thought the multi-release option was a very neat solution that I
really ought to try to use

  I envisaged that other agent implementors might not find it so easy to
encapsulate the required functionality

It's a shame multi-release won't work for all agents but never mind.

Thanks very much for the quick and helpful response.


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

More information about the core-libs-dev mailing list