Extending java.base module

Volker Simonis volker.simonis at gmail.com
Fri Feb 24 15:08:05 UTC 2017

On Wed, Feb 15, 2017 at 5:20 PM, Volker Simonis
<volker.simonis at gmail.com> wrote:
> On Wed, Feb 15, 2017 at 5:16 PM, Alan Bateman <Alan.Bateman at oracle.com> wrote:
> > On 15/02/2017 16:01, Daniel Fuchs wrote:
> >
> >>
> >> In that specific case it's not java.base that depends
> >> on java.security.jgss, but the application itself.
> >>
> >> So I would expect the application code to either require
> >> java.security.jgss, or some higher level module for that
> >> itself requires java.security.jgss, or jlink to be run with
> >> command line options that explicitly add java.security.jgss
> >> to the image.
> >
> > java.security.jgss exports an API so it will be resolved by default when the
> > initial class is loaded from the class path. In addition, it provides a
> > SecurityProvider implementation and so will be resolved because java.base
> > `uses java.security.Provider`. For the jlink case then you are right, it
> > needs someone to know that the application might need to do SPNEGO
> > authentication.
> >
> > In any case, it's an example of how not to do things, and hopefully it will
> > be cleaned up at some point.
> >

While digging deeper into this topic, I found other such examples (and
you can easily find more by searching for "Class.forName" in the base
module :)

sun.text.bidi.BidiBase$TextAttributeConstants (which is in the base
module) has the following static initializer:

// Make sure to load the AWT's TextAttribute class before using the
constants, if any.
static {
    try {
        Class.forName("java.awt.font.TextAttribute", true, null);
    } catch (ClassNotFoundException e) {}
static final JavaAWTFontAccess jafa = SharedSecrets.getJavaAWTFontAccess();

which is clearly another implicit dependency from java.base to
java.desktop which contains java.awt.font.TextAttribute

There's yet another such implicit dependency from java.base to jdk.net
in sun.net.ext.ExtendedSocketOptions which has the following static

static {
    try {
        // If the class is present, it will be initialized which
        // triggers registration of the extended socket options.
        Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");
    } catch (ClassNotFoundException e) {
        // the jdk.net module is not present => no extended socket options
        instance = new NoExtendedSocketOptions();

So I'm wondering if these all are examples of "how not to do things"
which will be cleaned up eventually or are if there other reasons that
this cleanup hasn't been done until now. I can imagine that if all the
current, implicit dependencies would have been resolved by using
services, service binding could lead to a much bigger dependency graph
for the base module which would probably include most of the modules
in the jdk. Not sure if this could have an negative performance impact
on startup time?

Wouldn't it be a good idea to have a list of all this implicit
dependencies somewhere (preferable in JBS) with a short comment for
each of them (like "should be fixed by using services", "will leave as
is because it's required too early during initialization", "should
remove dependency by refactoring the code", etc..)

Thank you and best regards,

> Daniel, Alan, thanks for the clarification. I didn't wanted to blame
> anybody - just looking for good arguments to prevent such code in our
> version of the JDK :)
> > -Alan
> >
> >

More information about the jigsaw-dev mailing list