Accessing module internals from bytecode rewriting agent

Jeremy Manson jeremymanson at
Mon May 8 18:49:16 UTC 2017

On Mon, May 8, 2017 at 5:54 AM, dalibor topic <dalibor.topic at>

> On 05.05.2017 08:39, Jeremy Manson wrote:
>> Mostly, I'm telling you all because I think it makes an interesting case
>> study - a large Java installation and the issues it faces trying to roll
>> out JDK 9.
> Indeed - thank you for providing valuable insight into your concerns and
> experiences.
> If other installations do the kinds of things that we do, the path to a
>> JDK 9 without lots of add-exports and kill switch options is likely to
>> be slow and laborious for them.  We're comparatively well situated to do
>> it - we have our own JDK build and a staffed team to do / help with the
>> migration, and are likely to roll it out to everyone with the kill
>> switch turned on by default so that our awful hacks can stay put until
>> we finish fixing them.
> I think part of responsibly relying on awful hacks leveraging unsupported
> behavior is to budget for their removal/rewrite as the assumptions behind
> them get invalidated over time.

And we generally do go through this at every JDK release cycle.  This is
hardly the only time we've had to do a lot of unpleasant work.  A fun one
was in the Java 6->7 timeframe, when it turned out the fact that the JDK
iterated over methods in approximately-declaration order spilled over into
many, many tests, even though that was implementation-dependent behavior.
There was a very painful cleanup for everyone working on Java here.

We didn't mind doing that, because we knew it was an important part of the
metaspace work.  However, we did put in a JDK flag to mimic the old
behavior, for transitional purposes.

Sometimes, it might be well known where the awful hacks are buried, in
> particular with one's own code. Other times, in particular with third party
> code, it might not be quite as obvious. That's where the jdeps & jdeprscan
> tools come in to help get a sense of the scope & intensity of such problems
> at compile time.
> The kill switch complements that at runtime.

I'm sure we can mostly work around the compile-time stuff.  Similar
situations arise whenever an unsupported method is removed or changed.  I
recall we had to orchestrate a migration to javax.imageio from (something
else? can't remember) when we moved to OpenJDK.  We now have the moral
equivalent of a lot of unsupported methods being removed - even though they
aren't being removed, they are being hidden.  In general, I don't think it
is worth complaining about that, especially since we have the kill switch.

We shouldn't have much problem analyzing our dependencies - we build
everything feasible from source at head, and have a very comprehensive
suite of tests, so if there is a broken dependency in third party code, we
should know immediately.

In general, our upgrade strategy involves getting the world into a state
that works with both JDKs, and then switching the JDKs out from
underneath.  We are most likely to have to put our own hacks in the JDK for
the things for which "what you do in Java 8" and "what you do in Java 9"
can't be the same (or getting them to be the same is very difficult, or a
bad idea).

>From that perspective, the bootclasspath situation is interesting.  There
is no Xbootclasspath/p flag in Java 9, and no --add-exports or
--patch-module in Java 8, so there is no state that will work with both.
We could comb through every use in our repo, and add extra code to detect
which JDK we are using / switch between them.   Then, after the transition,
we could delete all of that extra code.  However, that would be
meaningfully harder than just putting Xbootclasspath/p back for the
transition, and it would leave our command lines less readable.  The better
thing for us to do is almost certainly to allow users to use
Xbootclasspath/p until we kill Java 8 internally.

Turning the big kill switch on by default, by comparison, is more similar
to the method iteration situation in Java 7; if we work hard, we can
probably get the world into a single state that will work without making
everyone's code worse.  However, doing that migration up front would be a
headache that will take time, and, typically, the more time we take, the
more incompatibilities crop up.  So, starting with the kill switch on by
default should be a time saver.


> cheers,
> dalibor topic
> --
> <> Dalibor Topic | Principal Product Manager
> Phone: +494089091214 <tel:+494089091214> | Mobile: +491737185961
> <tel:+491737185961>
> ORACLE Deutschland B.V. & Co. KG | Kühnehöfe 5 | 22761 Hamburg
> ORACLE Deutschland B.V. & Co. KG
> Hauptverwaltung: Riesstr. 25, D-80992 München
> Registergericht: Amtsgericht München, HRA 95603
> Komplementärin: ORACLE Deutschland Verwaltung B.V.
> Hertogswetering 163/167, 3543 AS Utrecht, Niederlande
> Handelsregister der Handelskammer Midden-Niederlande, Nr. 30143697
> Geschäftsführer: Alexander van der Ven, Jan Schultheiss, Val Maher
> <> Oracle is committed to developing
> practices and products that help protect the environment

More information about the core-libs-dev mailing list