Project Jigsaw: Extending the service-provider loading facility

This page outlines an approach for extending the service-provider loading facility, java.util.ServiceLoader to modules.

The basic approach is to extend the module-info class so that the module declares the services (expressed as class types, usually interfaces or abstract classes) that it uses. The module-info is also used to declare that the module as a service provider in a manner that replaces the META-INF/services configuration file (a JAR file containing a module-info class may have both).

The following is an example:

    module A {
        requires service S;
    }

    module X {
        provides service S with S1;
    }

    module Y {
        provides service S with S2;
        provides service S with S3;
    }

In this example we have module A that load providers of type S. Modules X and Y are service providers containing implementations of S.

The idea is that when a configuration is computed that all service providers of any required services are included. If a new service provider module is installed then it will not be accessible to users of that service until they are re-configured. It would be a policy decision to automatically reconfigure.

In API terms then the existing load methods can be changed to work in module mode. In the following example then if invoked by code in module A then the resulting ServiceLoader will lazily load S1, S2, and S3.

    ServiceLoader<S> sl = ServiceLoader.load(S.class);

If invoked from a module that does not declare that it requires service S then either the load method fails, or the resulting ServiceLoader's iterator method returns an empty iterator (TBD).

In legacy mode then the ServiceLoader.load method will continue to use the legacy context class loader or system class loader.

Versioning: The service type does not have a version. It is simply a class type.

TBD: We need to examine if java.util.ResourceBundle can be extended to load resource bundles using this mechanism.