Thanks for the helpful explanation.
Post by Luke Hutchison
I have a related question about this specifically. I just added
multi-release jar support to ClassGraph (
https://github.com/classgraph/classgraph ). If one or more versioned
sections are present and the code is running on JRE9+, then the
highest-numbered section number less than or equal to the running JRE
version is scanned, and the other sections (including the base section) is
ignored by ClassGraph. Does this more or less match the JRE semantics, or
should I be rather using the versioned section to shadow/mask the base
section, but scan / read from both?
ie. does the JRE find resources and classes in both the versioned section
and the base section, or does the presence of a versioned section preclude
reading from the base section? Your comments seem to indicate the former,
since it sounds like module-info.class can be in either the versioned
section or the base section, and if it is in the base section, that means
module-info.class applies to all versions. That could mean that the base
section shadows the version sections, not the other way around (at least
If you are running on JDK $N then an entry in META-INF/versions/$N will
override an entry of the same name in versioned sections < $N as well as
the base section. The JarFile javadoc and JEP 238 describe this in detail.
One mental model is to think of it as a search path. If you are JDK 11 then
where "." is the top-level directory in the JAR file.
You can also verify your understanding by trying some examples with the
JarFile API, e.g. open the JarFile with the 4-arg constructor and use the
versionedStream method to obtain a stream of the JAR entries and then map
each entry to its real path with JarEntry::getRealPath. This might be
useful to verify that your library enumerates the correct set of entries.